Merge branch 'main' into next

This commit is contained in:
Livio Spring 2024-05-28 14:33:54 +02:00
commit 8ce3af2f9d
No known key found for this signature in database
GPG Key ID: 26BB1C2FA5952CF0
388 changed files with 13486 additions and 6671 deletions

View File

@ -1,15 +1,27 @@
### Definition of Ready # Which Problems Are Solved
- [ ] I am happy with the code Replace this example text with a concise list of problems that this PR solves.
- [ ] Short description of the feature/issue is added in the pr description For example:
- [ ] PR is linked to the corresponding user story - If the property XY is not given, the system crashes with a nil pointer exception.
- [ ] Acceptance criteria are met
- [ ] All open todos and follow ups are defined in a new ticket and justified # How the Problems Are Solved
- [ ] Deviations from the acceptance criteria and design are agreed with the PO and documented.
- [ ] No debug or dead code Replace this example text with a concise list of changes that this PR introduces.
- [ ] My code has no repetitions For example:
- [ ] Critical parts are tested automatically - Validates if property XY is given and throws an error if not
- [ ] Where possible E2E tests are implemented
- [ ] Documentation/examples are up-to-date # Additional Changes
- [ ] 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 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

View File

@ -5,6 +5,7 @@ on:
jobs: jobs:
test: test:
timeout-minutes: 10
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:

31
.github/workflows/ready_for_review.yml vendored Normal file
View 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
})

View File

@ -23,7 +23,7 @@ Tracing:
Type: none # ZITADEL_TRACING_TYPE Type: none # ZITADEL_TRACING_TYPE
Fraction: 1.0 # ZITADEL_TRACING_FRACTION Fraction: 1.0 # ZITADEL_TRACING_FRACTION
# The endpoint of the otel collector endpoint # The endpoint of the otel collector endpoint
Endpoint: '' #ZITADEL_TRACING_ENDPOINT Endpoint: "" #ZITADEL_TRACING_ENDPOINT
Telemetry: Telemetry:
# As long as Enabled is true, ZITADEL tries to send usage data to the configured Telemetry.Endpoints. # 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 PrivacyLink: https://zitadel.com/docs/legal/privacy-policy # ZITADEL_DEFAULTINSTANCE_PRIVACYPOLICY_PRIVACYLINK
HelpLink: "" # ZITADEL_DEFAULTINSTANCE_PRIVACYPOLICY_HELPLINK HelpLink: "" # ZITADEL_DEFAULTINSTANCE_PRIVACYPOLICY_HELPLINK
SupportEmail: "" # ZITADEL_DEFAULTINSTANCE_PRIVACYPOLICY_SUPPORTEMAIL 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: NotificationPolicy:
PasswordChange: true # ZITADEL_DEFAULTINSTANCE_NOTIFICATIONPOLICY_PASSWORDCHANGE PasswordChange: true # ZITADEL_DEFAULTINSTANCE_NOTIFICATIONPOLICY_PASSWORDCHANGE
LabelPolicy: LabelPolicy:

View File

@ -19,6 +19,7 @@ var (
createUserStmt string createUserStmt string
grantStmt string grantStmt string
settingsStmt string
databaseStmt string databaseStmt string
createEventstoreStmt string createEventstoreStmt string
createProjectionsStmt 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 return cmd
} }
@ -62,6 +63,7 @@ func InitAll(ctx context.Context, config *Config) {
VerifyUser(config.Database.Username(), config.Database.Password()), VerifyUser(config.Database.Username(), config.Database.Password()),
VerifyDatabase(config.Database.DatabaseName()), VerifyDatabase(config.Database.DatabaseName()),
VerifyGrant(config.Database.DatabaseName(), config.Database.Username()), VerifyGrant(config.Database.DatabaseName(), config.Database.Username()),
VerifySettings(config.Database.DatabaseName(), config.Database.Username()),
) )
logging.OnError(err).Fatal("unable to initialize the database") logging.OnError(err).Fatal("unable to initialize the database")
@ -147,6 +149,11 @@ func ReadStmts(typ string) (err error) {
return err return err
} }
settingsStmt, err = readStmt(typ, "11_settings")
if err != nil {
return err
}
return nil return nil
} }

View 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;

View 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
View 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
View 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
View 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
View 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;

View File

@ -108,6 +108,8 @@ type Steps struct {
s23CorrectGlobalUniqueConstraints *CorrectGlobalUniqueConstraints s23CorrectGlobalUniqueConstraints *CorrectGlobalUniqueConstraints
s24AddActorToAuthTokens *AddActorToAuthTokens s24AddActorToAuthTokens *AddActorToAuthTokens
s25User11AddLowerFieldsToVerifiedEmail *User11AddLowerFieldsToVerifiedEmail s25User11AddLowerFieldsToVerifiedEmail *User11AddLowerFieldsToVerifiedEmail
s26AuthUsers3 *AuthUsers3
s27IDPTemplate6SAMLNameIDFormat *IDPTemplate6SAMLNameIDFormat
} }
func MustNewSteps(v *viper.Viper) *Steps { func MustNewSteps(v *viper.Viper) *Steps {

View File

@ -138,6 +138,8 @@ func Setup(config *Config, steps *Steps, masterKey string) {
steps.s23CorrectGlobalUniqueConstraints = &CorrectGlobalUniqueConstraints{dbClient: esPusherDBClient} steps.s23CorrectGlobalUniqueConstraints = &CorrectGlobalUniqueConstraints{dbClient: esPusherDBClient}
steps.s24AddActorToAuthTokens = &AddActorToAuthTokens{dbClient: queryDBClient} steps.s24AddActorToAuthTokens = &AddActorToAuthTokens{dbClient: queryDBClient}
steps.s25User11AddLowerFieldsToVerifiedEmail = &User11AddLowerFieldsToVerifiedEmail{dbClient: esPusherDBClient} 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) err = projection.Create(ctx, projectionDBClient, eventstoreClient, config.Projections, nil, nil, nil)
logging.OnError(err).Fatal("unable to start projections") logging.OnError(err).Fatal("unable to start projections")
@ -175,6 +177,7 @@ func Setup(config *Config, steps *Steps, masterKey string) {
steps.s22ActiveInstancesIndex, steps.s22ActiveInstancesIndex,
steps.s23CorrectGlobalUniqueConstraints, steps.s23CorrectGlobalUniqueConstraints,
steps.s24AddActorToAuthTokens, steps.s24AddActorToAuthTokens,
steps.s26AuthUsers3,
} { } {
mustExecuteMigration(ctx, eventstoreClient, step, "migration failed") mustExecuteMigration(ctx, eventstoreClient, step, "migration failed")
} }
@ -188,6 +191,7 @@ func Setup(config *Config, steps *Steps, masterKey string) {
steps.s18AddLowerFieldsToLoginNames, steps.s18AddLowerFieldsToLoginNames,
steps.s21AddBlockFieldToLimits, steps.s21AddBlockFieldToLimits,
steps.s25User11AddLowerFieldsToVerifiedEmail, steps.s25User11AddLowerFieldsToVerifiedEmail,
steps.s27IDPTemplate6SAMLNameIDFormat,
} { } {
mustExecuteMigration(ctx, eventstoreClient, step, "migration failed") mustExecuteMigration(ctx, eventstoreClient, step, "migration failed")
} }

View File

@ -1,6 +1,7 @@
import { Directive, ElementRef, EventEmitter, HostListener, Output } from '@angular/core'; import { Directive, ElementRef, EventEmitter, HostListener, Output } from '@angular/core';
@Directive({ @Directive({
standalone: true,
selector: '[cnslScrollable]', selector: '[cnslScrollable]',
}) })
export class ScrollableDirective { export class ScrollableDirective {
@ -15,7 +16,6 @@ export class ScrollableDirective {
const top = event.target.scrollTop; const top = event.target.scrollTop;
const height = this.el.nativeElement.scrollHeight; const height = this.el.nativeElement.scrollHeight;
const offset = this.el.nativeElement.offsetHeight; const offset = this.el.nativeElement.offsetHeight;
// emit bottom event // emit bottom event
if (top > height - offset - 1) { if (top > height - offset - 1) {
this.scrollPosition.emit('bottom'); this.scrollPosition.emit('bottom');

View File

@ -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 {}

View File

@ -6,7 +6,6 @@ import { MatIconModule } from '@angular/material/icon';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatTooltipModule } from '@angular/material/tooltip'; import { MatTooltipModule } from '@angular/material/tooltip';
import { TranslateModule } from '@ngx-translate/core'; 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 { 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 { 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'; 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], declarations: [ChangesComponent],
imports: [ imports: [
CommonModule, CommonModule,
ScrollableModule,
MatProgressSpinnerModule, MatProgressSpinnerModule,
TranslateModule, TranslateModule,
MatIconModule, MatIconModule,
@ -30,6 +28,6 @@ import { ChangesComponent } from './changes.component';
MatTooltipModule, MatTooltipModule,
AvatarModule, AvatarModule,
], ],
exports: [ChangesComponent, ScrollableModule], exports: [ChangesComponent],
}) })
export class ChangesModule {} export class ChangesModule {}

View File

@ -1,11 +1,11 @@
<div class="footer-wrapper"> <div class="footer-wrapper">
<div class="footer-row"> <div class="footer-row">
<div class="footer-links"> <div class="footer-links" *ngIf="authService.privacypolicy | async as pP">
<a target="_blank" *ngIf="policy?.tosLink" rel="noreferrer" [href]="policy?.tosLink" external> <a target="_blank" *ngIf="pP?.tosLink" rel="noreferrer" [href]="pP?.tosLink" external>
<span>{{ 'FOOTER.LINKS.TOS' | translate }}</span> <span>{{ 'FOOTER.LINKS.TOS' | translate }}</span>
<i class="las la-external-link-alt"></i> <i class="las la-external-link-alt"></i>
</a> </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> <span>{{ 'FOOTER.LINKS.PP' | translate }}</span>
<i class="las la-external-link-alt"></i> <i class="las la-external-link-alt"></i>
</a> </a>

View File

@ -8,16 +8,7 @@ import { faXTwitter } from '@fortawesome/free-brands-svg-icons';
templateUrl: './footer.component.html', templateUrl: './footer.component.html',
styleUrls: ['./footer.component.scss'], styleUrls: ['./footer.component.scss'],
}) })
export class FooterComponent implements OnInit { export class FooterComponent {
public policy?: PrivacyPolicy.AsObject;
public faXTwitter = faXTwitter; public faXTwitter = faXTwitter;
constructor(public authService: GrpcAuthService) {} constructor(public authService: GrpcAuthService) {}
ngOnInit(): void {
this.authService.getMyPrivacyPolicy().then((policyResp) => {
if (policyResp.policy) {
this.policy = policyResp.policy;
}
});
}
} }

View File

@ -168,7 +168,11 @@
<span class="fill-space"></span> <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 }} {{ 'MENU.DOCUMENTATION' | translate }}
</a> </a>

View File

@ -224,7 +224,8 @@
flex: 1; flex: 1;
} }
.doc-link { .doc-link,
.custom-link {
margin-right: 1rem; margin-right: 1rem;
@media only screen and (max-width: 800px) { @media only screen and (max-width: 800px) {

View File

@ -1,5 +1,5 @@
import { ConnectedPosition, ConnectionPositionPair } from '@angular/cdk/overlay'; 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 { Router } from '@angular/router';
import { BehaviorSubject, Observable, of, Subject } from 'rxjs'; import { BehaviorSubject, Observable, of, Subject } from 'rxjs';
import { Org } from 'src/app/proto/generated/zitadel/org_pb'; 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 { BreadcrumbService, BreadcrumbType } from 'src/app/services/breadcrumb.service';
import { GrpcAuthService } from 'src/app/services/grpc-auth.service'; import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
import { ManagementService } from 'src/app/services/mgmt.service'; import { ManagementService } from 'src/app/services/mgmt.service';
import { ActionKeysType } from '../action-keys/action-keys.component'; import { ActionKeysType } from '../action-keys/action-keys.component';
import { GetPrivacyPolicyResponse } from 'src/app/proto/generated/zitadel/management_pb';
@Component({ @Component({
selector: 'cnsl-header', selector: 'cnsl-header',
@ -31,6 +31,9 @@ export class HeaderComponent implements OnDestroy {
private destroy$: Subject<void> = new Subject(); private destroy$: Subject<void> = new Subject();
public BreadcrumbType: any = BreadcrumbType; public BreadcrumbType: any = BreadcrumbType;
public ActionKeysType: any = ActionKeysType; public ActionKeysType: any = ActionKeysType;
public docsLink = 'https://zitadel.com/docs';
public customLink = '';
public customLinkText = '';
public positions: ConnectedPosition[] = [ public positions: ConnectedPosition[] = [
new ConnectionPositionPair({ originX: 'start', originY: 'bottom' }, { overlayX: 'start', overlayY: 'top' }, 0, 10), 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 mgmtService: ManagementService,
public breadcrumbService: BreadcrumbService, public breadcrumbService: BreadcrumbService,
public router: Router, 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() { public ngOnDestroy() {
this.destroy$.next(); this.destroy$.next();

View File

@ -15,7 +15,7 @@
/> />
</div> </div>
<div class="org-wrapper"> <div class="org-wrapper" cnslScrollable (scrollPosition)="onNearEndScroll($event)">
<button <button
class="org-button-with-pin" class="org-button-with-pin"
mat-button mat-button

View File

@ -1,11 +1,14 @@
import { SelectionModel } from '@angular/cdk/collections'; import { SelectionModel } from '@angular/cdk/collections';
import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'; import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { UntypedFormControl } from '@angular/forms'; 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 { 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 { AuthenticationService } from 'src/app/services/authentication.service';
import { GrpcAuthService } from 'src/app/services/grpc-auth.service'; import { GrpcAuthService } from 'src/app/services/grpc-auth.service';
import { ToastService } from 'src/app/services/toast.service';
const ORG_QUERY_LIMIT = 100;
@Component({ @Component({
selector: 'cnsl-org-context', selector: 'cnsl-org-context',
@ -16,7 +19,30 @@ export class OrgContextComponent implements OnInit {
public pinned: SelectionModel<Org.AsObject> = new SelectionModel<Org.AsObject>(true, []); public pinned: SelectionModel<Org.AsObject> = new SelectionModel<Org.AsObject>(true, []);
public orgLoading$: BehaviorSubject<any> = new BehaviorSubject(false); 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(''); public filterControl: UntypedFormControl = new UntypedFormControl('');
@Input() public org!: Org.AsObject; @Input() public org!: Org.AsObject;
@ViewChild('input', { static: false }) input!: ElementRef; @ViewChild('input', { static: false }) input!: ElementRef;
@ -26,15 +52,17 @@ export class OrgContextComponent implements OnInit {
constructor( constructor(
public authService: AuthenticationService, public authService: AuthenticationService,
private auth: GrpcAuthService, private auth: GrpcAuthService,
private toast: ToastService,
) { ) {
this.filterControl.valueChanges.pipe(debounceTime(500)).subscribe((value) => { 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 { public ngOnInit(): void {
this.focusFilter(); this.focusFilter();
this.loadOrgs(); this.init();
} }
public setActiveOrg(org: Org.AsObject) { public setActiveOrg(org: Org.AsObject) {
@ -42,7 +70,24 @@ export class OrgContextComponent implements OnInit {
this.closedCard.emit(); 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) { if (!filter) {
const value = this.input?.nativeElement?.value; const value = this.input?.nativeElement?.value;
if (value) { if (value) {
@ -61,29 +106,52 @@ export class OrgContextComponent implements OnInit {
orgNameQuery.setMethod(TextQueryMethod.TEXT_QUERY_METHOD_CONTAINS_IGNORE_CASE); orgNameQuery.setMethod(TextQueryMethod.TEXT_QUERY_METHOD_CONTAINS_IGNORE_CASE);
query.setNameQuery(orgNameQuery); query.setNameQuery(orgNameQuery);
} }
this.orgLoading$.next(true); this.orgLoading$.next(true);
this.orgs$ = from(this.auth.listMyProjectOrgs(undefined, 0, query ? [query] : undefined)).pipe( return this.auth
map((resp) => { .listMyProjectOrgs(ORG_QUERY_LIMIT, offset, query ? [query] : undefined, OrgFieldName.ORG_FIELD_NAME_NAME, 'asc')
return resp.resultList.sort((left, right) => left.name.localeCompare(right.name)); .then((result) => {
}),
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(() => {
this.orgLoading$.next(false); 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 { public closeCard(element: HTMLElement): void {

View File

@ -12,11 +12,13 @@ import { HasRoleModule } from 'src/app/directives/has-role/has-role.module';
import { InputModule } from '../input/input.module'; import { InputModule } from '../input/input.module';
import { OrgContextComponent } from './org-context.component'; import { OrgContextComponent } from './org-context.component';
import { ScrollableDirective } from 'src/app/directives/scrollable/scrollable.directive';
@NgModule({ @NgModule({
declarations: [OrgContextComponent], declarations: [OrgContextComponent],
imports: [ imports: [
CommonModule, CommonModule,
ScrollableDirective,
FormsModule, FormsModule,
A11yModule, A11yModule,
ReactiveFormsModule, ReactiveFormsModule,

View File

@ -52,7 +52,7 @@
</ng-container> </ng-container>
<ng-container matColumnDef="name"> <ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> <th mat-header-cell mat-sort-header *matHeaderCellDef>
{{ 'ORG.PAGES.NAME' | translate }} {{ 'ORG.PAGES.NAME' | translate }}
</th> </th>
<td mat-cell *matCellDef="let org" (click)="setAndNavigateToOrg(org)"> <td mat-cell *matCellDef="let org" (click)="setAndNavigateToOrg(org)">

View File

@ -50,4 +50,12 @@
<i *ngIf="password?.dirty && !password?.errors?.['errorslowercasemissing']" class="las la-check green"></i> <i *ngIf="password?.dirty && !password?.errors?.['errorslowercasemissing']" class="las la-check green"></i>
<span class="cnsl-secondary-text">{{ 'ERRORS.LOWERCASEMISSING' | translate }}</span> <span class="cnsl-secondary-text">{{ 'ERRORS.LOWERCASEMISSING' | translate }}</span>
</div> </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> </div>

View File

@ -9,6 +9,7 @@
color="warn" color="warn"
(click)="resetDefault()" (click)="resetDefault()"
mat-stroked-button mat-stroked-button
data-e2e="reset-button"
> >
{{ 'POLICY.RESET' | translate }} {{ 'POLICY.RESET' | translate }}
</button> </button>
@ -40,7 +41,23 @@
<cnsl-form-field class="privacy-policy-formfield"> <cnsl-form-field class="privacy-policy-formfield">
<cnsl-label>{{ 'POLICY.PRIVACY_POLICY.SUPPORTEMAIL' | translate }}</cnsl-label> <cnsl-label>{{ 'POLICY.PRIVACY_POLICY.SUPPORTEMAIL' | translate }}</cnsl-label>
<input cnslInput name="supportEmail" formControlName="supportEmail" /> <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> </cnsl-form-field>
</form> </form>
</div> </div>
@ -53,6 +70,7 @@
color="primary" color="primary"
type="submit" type="submit"
mat-raised-button mat-raised-button
data-e2e="save-button"
> >
{{ 'ACTIONS.SAVE' | translate }} {{ 'ACTIONS.SAVE' | translate }}
</button> </button>

View File

@ -61,6 +61,9 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
privacyLink: ['', []], privacyLink: ['', []],
helpLink: ['', []], helpLink: ['', []],
supportEmail: ['', []], supportEmail: ['', []],
docsLink: ['', []],
customLink: ['', []],
customLinkText: ['', []],
}); });
this.canWrite$.pipe(take(1)).subscribe((canWrite) => { this.canWrite$.pipe(take(1)).subscribe((canWrite) => {
@ -107,6 +110,9 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
privacyLink: '', privacyLink: '',
helpLink: '', helpLink: '',
supportEmail: '', supportEmail: '',
docsLink: '',
customLink: '',
customLinkText: '',
}); });
} }
}) })
@ -117,6 +123,9 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
privacyLink: '', privacyLink: '',
helpLink: '', helpLink: '',
supportEmail: '', supportEmail: '',
docsLink: '',
customLink: '',
customLinkText: '',
}); });
}); });
} }
@ -129,11 +138,16 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
req.setTosLink(this.form.get('tosLink')?.value); req.setTosLink(this.form.get('tosLink')?.value);
req.setHelpLink(this.form.get('helpLink')?.value); req.setHelpLink(this.form.get('helpLink')?.value);
req.setSupportEmail(this.form.get('supportEmail')?.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) (this.service as ManagementService)
.addCustomPrivacyPolicy(req) .addCustomPrivacyPolicy(req)
.then(() => { .then(() => {
this.toast.showInfo('POLICY.PRIVACY_POLICY.SAVED', true); this.toast.showInfo('POLICY.PRIVACY_POLICY.SAVED', true);
this.loadData(); this.loadData();
// Reload console as links may have changed
this.reloadConsole();
}) })
.catch((error) => this.toast.showError(error)); .catch((error) => this.toast.showError(error));
} else { } else {
@ -142,12 +156,17 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
req.setTosLink(this.form.get('tosLink')?.value); req.setTosLink(this.form.get('tosLink')?.value);
req.setHelpLink(this.form.get('helpLink')?.value); req.setHelpLink(this.form.get('helpLink')?.value);
req.setSupportEmail(this.form.get('supportEmail')?.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) (this.service as ManagementService)
.updateCustomPrivacyPolicy(req) .updateCustomPrivacyPolicy(req)
.then(() => { .then(() => {
this.toast.showInfo('POLICY.PRIVACY_POLICY.SAVED', true); this.toast.showInfo('POLICY.PRIVACY_POLICY.SAVED', true);
this.loadData(); this.loadData();
// Reload console as links may have changed
this.reloadConsole();
}) })
.catch((error) => this.toast.showError(error)); .catch((error) => this.toast.showError(error));
} }
@ -157,12 +176,17 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
req.setTosLink(this.form.get('tosLink')?.value); req.setTosLink(this.form.get('tosLink')?.value);
req.setHelpLink(this.form.get('helpLink')?.value); req.setHelpLink(this.form.get('helpLink')?.value);
req.setSupportEmail(this.form.get('supportEmail')?.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) (this.service as AdminService)
.updatePrivacyPolicy(req) .updatePrivacyPolicy(req)
.then(() => { .then(() => {
this.toast.showInfo('POLICY.PRIVACY_POLICY.SAVED', true); this.toast.showInfo('POLICY.PRIVACY_POLICY.SAVED', true);
this.loadData(); this.loadData();
// Reload console as links may have changed
this.reloadConsole();
}) })
.catch((error) => this.toast.showError(error)); .catch((error) => this.toast.showError(error));
} }
@ -188,6 +212,7 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
.then(() => { .then(() => {
setTimeout(() => { setTimeout(() => {
this.loadData(); this.loadData();
window.location.reload();
}, 1000); }, 1000);
}) })
.catch((error) => { .catch((error) => {
@ -209,4 +234,10 @@ export class PrivacyPolicyComponent implements OnInit, OnDestroy {
return false; return false;
} }
} }
private reloadConsole(): void {
setTimeout(() => {
window.location.reload();
}, 1000);
}
} }

View File

@ -1,7 +1,7 @@
.option-form { .option-form {
display: grid; display: grid;
grid-template-columns: 1fr; grid-template-columns: 1fr;
max-width: 400px; max-width: 500px;
padding-bottom: 1rem; padding-bottom: 1rem;
.checkbox-desc { .checkbox-desc {

View File

@ -70,6 +70,28 @@
</button> </button>
</div> </div>
<div *ngIf="showOptional"> <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 <cnsl-provider-options
[initialOptions]="provider?.config?.options" [initialOptions]="provider?.config?.options"
(optionsChanged)="options = $event" (optionsChanged)="options = $event"

View File

@ -1,3 +1,12 @@
.metadata-xml { .metadata-xml {
min-height: 200px; min-height: 200px;
} }
.transient-info {
max-width: 500px;
.transient-info-desc {
margin-top: 0;
margin-bottom: 0.5rem;
}
}

View File

@ -1,6 +1,12 @@
import { Component, Injector, Type } from '@angular/core'; import { Component, Injector, Type } from '@angular/core';
import { Location } from '@angular/common'; 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 { AbstractControl, FormGroup, UntypedFormControl, UntypedFormGroup } from '@angular/forms';
import { PolicyComponentServiceType } from '../../policies/policy-component-types.enum'; import { PolicyComponentServiceType } from '../../policies/policy-component-types.enum';
import { ManagementService } from '../../../services/mgmt.service'; import { ManagementService } from '../../../services/mgmt.service';
@ -46,6 +52,7 @@ export class ProviderSamlSpComponent {
// DEPRECATED: use service$ instead // DEPRECATED: use service$ instead
private service!: ManagementService | AdminService; private service!: ManagementService | AdminService;
bindingValues: string[] = Object.keys(SAMLBinding); bindingValues: string[] = Object.keys(SAMLBinding);
nameIDFormatValues: string[] = Object.keys(SAMLNameIDFormat);
public justCreated$: BehaviorSubject<string> = new BehaviorSubject<string>(''); public justCreated$: BehaviorSubject<string> = new BehaviorSubject<string>('');
public justActivated$ = new BehaviorSubject<boolean>(false); public justActivated$ = new BehaviorSubject<boolean>(false);
@ -118,6 +125,8 @@ export class ProviderSamlSpComponent {
metadataUrl: new UntypedFormControl('', []), metadataUrl: new UntypedFormControl('', []),
binding: new UntypedFormControl(this.bindingValues[0], [requiredValidator]), binding: new UntypedFormControl(this.bindingValues[0], [requiredValidator]),
withSignedRequest: new UntypedFormControl(true, [requiredValidator]), withSignedRequest: new UntypedFormControl(true, [requiredValidator]),
nameIdFormat: new UntypedFormControl(SAMLNameIDFormat.SAML_NAME_ID_FORMAT_PERSISTENT, []),
transientMappingAttributeName: new UntypedFormControl('', []),
}, },
atLeastOneIsFilled('metadataXml', 'metadataUrl'), atLeastOneIsFilled('metadataXml', 'metadataUrl'),
); );
@ -196,8 +205,12 @@ export class ProviderSamlSpComponent {
req.setWithSignedRequest(this.withSignedRequest?.value); req.setWithSignedRequest(this.withSignedRequest?.value);
// @ts-ignore // @ts-ignore
req.setBinding(SAMLBinding[this.binding?.value]); req.setBinding(SAMLBinding[this.binding?.value]);
// @ts-ignore
req.setNameIdFormat(SAMLNameIDFormat[this.nameIDFormat?.value]);
req.setTransientMappingAttributeName(this.transientMapping?.value);
req.setProviderOptions(this.options); req.setProviderOptions(this.options);
console.log(req);
this.loading = true; this.loading = true;
this.service this.service
.updateSAMLProvider(req) .updateSAMLProvider(req)
@ -229,6 +242,11 @@ export class ProviderSamlSpComponent {
// @ts-ignore // @ts-ignore
req.setBinding(SAMLBinding[this.binding?.value]); req.setBinding(SAMLBinding[this.binding?.value]);
req.setWithSignedRequest(this.withSignedRequest?.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.loading = true;
this.service this.service
.addSAMLProvider(req) .addSAMLProvider(req)
@ -279,6 +297,14 @@ export class ProviderSamlSpComponent {
return false; 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 { private get name(): AbstractControl | null {
return this.form.get('name'); return this.form.get('name');
} }
@ -298,4 +324,12 @@ export class ProviderSamlSpComponent {
private get withSignedRequest(): AbstractControl | null { private get withSignedRequest(): AbstractControl | null {
return this.form.get('withSignedRequest'); 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');
}
} }

View File

@ -50,7 +50,7 @@
.formfield { .formfield {
display: block; display: block;
max-width: 400px; max-width: 500px;
&.pwd { &.pwd {
display: none; display: none;
@ -132,7 +132,7 @@
} }
.string-list-component-wrapper { .string-list-component-wrapper {
max-width: 400px; max-width: 500px;
} }
.identity-provider-content { .identity-provider-content {
@ -144,7 +144,7 @@
} }
.identity-provider-2-col { .identity-provider-2-col {
max-width: 400px; max-width: 500px;
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
column-gap: 1rem; column-gap: 1rem;
@ -160,7 +160,7 @@
.flex-line { .flex-line {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
max-width: 400px; max-width: 500px;
.formfield { .formfield {
flex: 1; flex: 1;

View File

@ -36,7 +36,7 @@ export const APPEARANCE_GROUP: SettingLinks = {
}; };
export const PRIVACY_POLICY: SettingLinks = { export const PRIVACY_POLICY: SettingLinks = {
i18nTitle: 'SETTINGS.LIST.PRIVACYPOLICY', i18nTitle: 'DESCRIPTIONS.SETTINGS.PRIVACY_POLICY.TITLE',
i18nDesc: 'POLICY.PRIVACY_POLICY.DESCRIPTION', i18nDesc: 'POLICY.PRIVACY_POLICY.DESCRIPTION',
iamRouterLink: ['/settings'], iamRouterLink: ['/settings'],
orgRouterLink: ['/org-settings'], orgRouterLink: ['/org-settings'],

View File

@ -187,7 +187,7 @@ export const LOGINTEXTS: SidenavSetting = {
export const PRIVACYPOLICY: SidenavSetting = { export const PRIVACYPOLICY: SidenavSetting = {
id: 'privacypolicy', id: 'privacypolicy',
i18nKey: 'SETTINGS.LIST.PRIVACYPOLICY', i18nKey: 'DESCRIPTIONS.SETTINGS.PRIVACY_POLICY.TITLE',
groupI18nKey: 'SETTINGS.GROUPS.OTHER', groupI18nKey: 'SETTINGS.GROUPS.OTHER',
requiredRoles: { requiredRoles: {
[PolicyComponentServiceType.MGMT]: ['policy.read'], [PolicyComponentServiceType.MGMT]: ['policy.read'],

View File

@ -2,7 +2,7 @@
title="{{ title="{{
id ? ('SMTP.DETAIL.TITLE' | translate) : ('SMTP.CREATE.STEPS.TITLE' | translate: { value: providerDefaultSetting.name }) id ? ('SMTP.DETAIL.TITLE' | translate) : ('SMTP.CREATE.STEPS.TITLE' | translate: { value: providerDefaultSetting.name })
}}" }}"
[createSteps]="2" [createSteps]="3"
[currentCreateStep]="currentCreateStep" [currentCreateStep]="currentCreateStep"
(closed)="close()" (closed)="close()"
> >
@ -133,7 +133,7 @@
class="create-button" class="create-button"
color="primary" color="primary"
data-e2e="create-button" data-e2e="create-button"
(click)="savePolicy()" (click)="savePolicy(stepper)"
[disabled]=" [disabled]="
firstFormGroup.invalid || secondFormGroup.invalid || (['iam.policy.write'] | hasRole | async) === false firstFormGroup.invalid || secondFormGroup.invalid || (['iam.policy.write'] | hasRole | async) === false
" "
@ -143,6 +143,82 @@
</div> </div>
</mat-step> </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"> <ng-template matStepperIcon="edit">
<mat-icon>check</mat-icon> <mat-icon>check</mat-icon>
</ng-template> </ng-template>

View File

@ -31,6 +31,8 @@ import {
OutlookDefaultSettings, OutlookDefaultSettings,
SendgridDefaultSettings, SendgridDefaultSettings,
} from './known-smtp-providers-settings'; } from './known-smtp-providers-settings';
import { MatStepper } from '@angular/material/stepper';
import { SMTPConfigState } from 'src/app/proto/generated/zitadel/settings_pb';
@Component({ @Component({
selector: 'cnsl-smtp-provider', selector: 'cnsl-smtp-provider',
@ -48,7 +50,7 @@ export class SMTPProviderComponent {
public smtpLoading: boolean = false; public smtpLoading: boolean = false;
public hasSMTPConfig: boolean = false; public hasSMTPConfig: boolean = false;
public isActive: boolean = false;
public updateClientSecret: boolean = false; public updateClientSecret: boolean = false;
// stepper // stepper
@ -166,6 +168,7 @@ export class SMTPProviderComponent {
.then((data) => { .then((data) => {
this.smtpLoading = false; this.smtpLoading = false;
if (data.smtpConfig) { if (data.smtpConfig) {
this.isActive = data.smtpConfig.state === SMTPConfigState.SMTP_CONFIG_ACTIVE;
this.hasSMTPConfig = true; this.hasSMTPConfig = true;
this.firstFormGroup.patchValue({ this.firstFormGroup.patchValue({
['description']: data.smtpConfig.description, ['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) { if (this.hasSMTPConfig) {
const req = new UpdateSMTPConfigRequest(); const req = new UpdateSMTPConfigRequest();
req.setId(this.id); req.setId(this.id);
@ -228,19 +231,49 @@ export class SMTPProviderComponent {
} }
} }
public savePolicy(): void { public activateSMTPConfig() {
this.updateData() this.service
.activateSMTPConfig(this.id)
.then(() => { .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); this.toast.showInfo('SETTING.SMTP.SAVED', true);
setTimeout(() => { setTimeout(() => {
this.close(); stepper.next();
}, 2000); }, 2000);
}) })
.catch((error: unknown) => { .catch((error: unknown) => {
if (`${error}`.includes('No changes')) { if (`${error}`.includes('No changes')) {
this.toast.showInfo('SETTING.SMTP.NOCHANGES', true); this.toast.showInfo('SETTING.SMTP.NOCHANGES', true);
setTimeout(() => { setTimeout(() => {
this.close(); stepper.next();
}, 2000); }, 2000);
} else { } else {
this.toast.showError(error); this.toast.showError(error);

View File

@ -68,4 +68,32 @@
font-size: 14px; 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;
}
}
} }

View File

@ -35,6 +35,10 @@ export class AuthenticationService {
return from(this.oauthService.loadUserProfile()); return from(this.oauthService.loadUserProfile());
} }
public getIdToken(): string {
return this.oauthService.getIdToken();
}
public async authenticate(partialConfig?: Partial<AuthConfig>, force: boolean = false): Promise<boolean> { public async authenticate(partialConfig?: Partial<AuthConfig>, force: boolean = false): Promise<boolean> {
if (partialConfig) { if (partialConfig) {
Object.assign(this.authConfig, partialConfig); Object.assign(this.authConfig, partialConfig);

View File

@ -27,7 +27,6 @@ import {
GetMyPhoneRequest, GetMyPhoneRequest,
GetMyPhoneResponse, GetMyPhoneResponse,
GetMyPrivacyPolicyRequest, GetMyPrivacyPolicyRequest,
GetMyPrivacyPolicyResponse,
GetMyProfileRequest, GetMyProfileRequest,
GetMyProfileResponse, GetMyProfileResponse,
GetMyUserRequest, GetMyUserRequest,
@ -99,11 +98,10 @@ import { ChangeQuery } from '../proto/generated/zitadel/change_pb';
import { MetadataQuery } from '../proto/generated/zitadel/metadata_pb'; import { MetadataQuery } from '../proto/generated/zitadel/metadata_pb';
import { ListQuery } from '../proto/generated/zitadel/object_pb'; import { ListQuery } from '../proto/generated/zitadel/object_pb';
import { Org, OrgFieldName, OrgQuery } from '../proto/generated/zitadel/org_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 { Gender, MembershipQuery, User, WebAuthNVerification } from '../proto/generated/zitadel/user_pb';
import { GrpcService } from './grpc.service'; import { GrpcService } from './grpc.service';
import { StorageKey, StorageLocation, StorageService } from './storage.service'; import { StorageKey, StorageLocation, StorageService } from './storage.service';
import { ThemeService } from './theme.service';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
@ -137,11 +135,18 @@ export class GrpcAuthService {
>(undefined); >(undefined);
labelPolicyLoading$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true); 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 zitadelPermissions: BehaviorSubject<string[]> = new BehaviorSubject<string[]>([]);
public readonly fetchedZitadelPermissions: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); public readonly fetchedZitadelPermissions: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
public cachedOrgs: BehaviorSubject<Org.AsObject[]> = new BehaviorSubject<Org.AsObject[]>([]); public cachedOrgs: BehaviorSubject<Org.AsObject[]> = new BehaviorSubject<Org.AsObject[]>([]);
private cachedLabelPolicies: { [orgId: string]: LabelPolicy.AsObject } = {}; private cachedLabelPolicies: { [orgId: string]: LabelPolicy.AsObject } = {};
private cachedPrivacyPolicies: { [orgId: string]: PrivacyPolicy.AsObject } = {};
constructor( constructor(
private readonly grpcService: GrpcService, 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([ this.user = forkJoin([
of(this.oauthService.getAccessToken()), of(this.oauthService.getAccessToken()),
this.oauthService.events.pipe( this.oauthService.events.pipe(
@ -394,9 +418,12 @@ export class GrpcAuthService {
if (queryList) { if (queryList) {
req.setQueriesList(queryList); req.setQueriesList(queryList);
} }
// if (sortingColumn) { if (sortingDirection) {
// req.setSortingColumn(sortingColumn); query.setAsc(sortingDirection === 'asc');
// } }
if (sortingColumn) {
req.setSortingColumn(sortingColumn);
}
req.setQuery(query); req.setQuery(query);
@ -697,7 +724,23 @@ export class GrpcAuthService {
} }
} }
public getMyPrivacyPolicy(): Promise<GetMyPrivacyPolicyResponse.AsObject> { public getMyPrivacyPolicy(orgIdForCache?: string): Promise<PrivacyPolicy.AsObject> {
return this.grpcService.auth.getMyPrivacyPolicy(new GetMyPrivacyPolicyRequest(), null).then((resp) => resp.toObject()); 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();
}
});
}
} }
} }

View File

@ -18,6 +18,7 @@ import { I18nInterceptor } from './interceptors/i18n.interceptor';
import { OrgInterceptor } from './interceptors/org.interceptor'; import { OrgInterceptor } from './interceptors/org.interceptor';
import { StorageService } from './storage.service'; import { StorageService } from './storage.service';
import { FeatureServiceClient } from '../proto/generated/zitadel/feature/v2beta/Feature_serviceServiceClientPb'; import { FeatureServiceClient } from '../proto/generated/zitadel/feature/v2beta/Feature_serviceServiceClientPb';
import { GrpcAuthService } from './grpc-auth.service';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',

View File

@ -2,11 +2,13 @@ import { Injectable } from '@angular/core';
import { MatDialog } from '@angular/material/dialog'; import { MatDialog } from '@angular/material/dialog';
import { Request, UnaryInterceptor, UnaryResponse } from 'grpc-web'; import { Request, UnaryInterceptor, UnaryResponse } from 'grpc-web';
import { Subject } from 'rxjs'; 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 { WarnDialogComponent } from 'src/app/modules/warn-dialog/warn-dialog.component';
import { AuthenticationService } from '../authentication.service'; import { AuthenticationService } from '../authentication.service';
import { StorageService } from '../storage.service'; import { StorageService } from '../storage.service';
import { AuthConfig } from 'angular-oauth2-oidc';
import { GrpcAuthService } from '../grpc-auth.service';
const authorizationKey = 'Authorization'; const authorizationKey = 'Authorization';
const bearerPrefix = 'Bearer'; const bearerPrefix = 'Bearer';
@ -44,7 +46,7 @@ export class AuthInterceptor<TReq = unknown, TResp = unknown> implements UnaryIn
return response; return response;
}) })
.catch(async (error: any) => { .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); this.triggerDialog.next(true);
} }
return Promise.reject(error); return Promise.reject(error);
@ -67,7 +69,13 @@ export class AuthInterceptor<TReq = unknown, TResp = unknown> implements UnaryIn
.pipe(take(1)) .pipe(take(1))
.subscribe((resp) => { .subscribe((resp) => {
if (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);
} }
}); });
} }

View File

@ -129,7 +129,7 @@
}, },
"PRIVACY_POLICY": { "PRIVACY_POLICY": {
"TITLE": "Външни връзки", "TITLE": "Външни връзки",
"DESCRIPTION": "Насочете вашите потребители към персонализирани външни ресурси, показани на страницата за вход. Потребителите трябва да приемат Условията за ползване и Политиката за поверителност, преди да могат да се регистрират." "DESCRIPTION": "Насочете потребителите си към персонализирани външни ресурси, показани на страницата за вход. Потребителите трябва да приемат Общите условия и Политиката за поверителност, преди да могат да се регистрират. Променете връзката към вашата документация или задайте празен низ, за ​​да скриете бутона за документация от конзолата. Добавете персонализирана външна връзка и персонализиран текст за тази връзка в конзолата или ги оставете празни, за да скриете този бутон."
}, },
"SMTP_PROVIDER": { "SMTP_PROVIDER": {
"TITLE": "Настройки на SMTP", "TITLE": "Настройки на SMTP",
@ -588,6 +588,7 @@
"INVALID_FORMAT": "Форматирането е невалидно.", "INVALID_FORMAT": "Форматирането е невалидно.",
"NOTANEMAIL": "Дадената стойност не е имейл адрес.", "NOTANEMAIL": "Дадената стойност не е имейл адрес.",
"MINLENGTH": "Трябва да е поне {{requiredLength}} знака дълги.", "MINLENGTH": "Трябва да е поне {{requiredLength}} знака дълги.",
"MAXLENGTH": "Трябва да е по-малко от {{requiredLength}} символа",
"UPPERCASEMISSING": "Трябва да включва главна буква.", "UPPERCASEMISSING": "Трябва да включва главна буква.",
"LOWERCASEMISSING": "Трябва да включва малка буква.", "LOWERCASEMISSING": "Трябва да включва малка буква.",
"SYMBOLERROR": "Трябва да включва символ или препинателен знак.", "SYMBOLERROR": "Трябва да включва символ или препинателен знак.",
@ -873,7 +874,8 @@
"SET": "Задайте нова парола", "SET": "Задайте нова парола",
"RESENDNOTIFICATION": "Изпратете връзка за повторно задаване на парола", "RESENDNOTIFICATION": "Изпратете връзка за повторно задаване на парола",
"REQUIRED": "Някои задължителни полета липсват.", "REQUIRED": "Някои задължителни полета липсват.",
"MINLENGTHERROR": "Трябва да бъде поне {{value}} знака дълги." "MINLENGTHERROR": "Трябва да бъде поне {{value}} знака дълги.",
"MAXLENGTHERROR": "Трябва да съдържа по-малко от {{value}} знака."
}, },
"ID": "документ за самоличност", "ID": "документ за самоличност",
"EMAIL": "Електронна поща", "EMAIL": "Електронна поща",
@ -1564,6 +1566,9 @@
"POLICYLINK": "Връзка към Политика за поверителност", "POLICYLINK": "Връзка към Политика за поверителност",
"HELPLINK": "Връзка към Помощ", "HELPLINK": "Връзка към Помощ",
"SUPPORTEMAIL": "Имейл за поддръжка", "SUPPORTEMAIL": "Имейл за поддръжка",
"DOCSLINK": "Връзка към документи (Console)",
"CUSTOMLINK": "Персонализирана връзка (Console)",
"CUSTOMLINKTEXT": "Персонализиран текст на връзката (Console)",
"SAVED": "Запазено успешно!", "SAVED": "Запазено успешно!",
"RESET_TITLE": "Възстановяване на стойностите по подразбиране", "RESET_TITLE": "Възстановяване на стойностите по подразбиране",
"RESET_DESCRIPTION": "На път сте да възстановите връзките по подразбиране за TOS и Политика за поверителност. " "RESET_DESCRIPTION": "На път сте да възстановите връзките по подразбиране за TOS и Политика за поверителност. "
@ -2215,7 +2220,7 @@
"SMTP": { "SMTP": {
"LIST": { "LIST": {
"TITLE": "SMTP доставчик", "TITLE": "SMTP доставчик",
"DESCRIPTION": "Това са SMTP доставчиците за вашето копие на Zitadel. Активирайте този, който искате да използвате, за да изпращате известия до вашите потребители.", "DESCRIPTION": "Това са SMTP доставчиците за вашето копие на ZITADEL. Активирайте този, който искате да използвате, за да изпращате известия до вашите потребители.",
"EMPTY": "Няма наличен SMTP доставчик", "EMPTY": "Няма наличен SMTP доставчик",
"ACTIVATED": "Активиран", "ACTIVATED": "Активиран",
"ACTIVATE": "Активирайте доставчика", "ACTIVATE": "Активирайте доставчика",
@ -2243,7 +2248,16 @@
"CURRENT_DESC_TITLE": "Това са вашите SMTP настройки", "CURRENT_DESC_TITLE": "Това са вашите SMTP настройки",
"PROVIDER_SETTINGS": "Настройки на SMTP доставчик", "PROVIDER_SETTINGS": "Настройки на SMTP доставчик",
"SENDER_SETTINGS": "Настройки на изпращача", "SENDER_SETTINGS": "Настройки на изпращача",
"TEST_SETTINGS": "Тествайте настройките на SMTP" "TEST_SETTINGS": "Тествайте настройките на SMTP",
"NEXT_STEPS": "Следващи стъпки",
"ACTIVATE": {
"TITLE": "Активирайте вашия SMTP доставчик",
"DESCRIPTION": "ZITADEL не може да използва този SMTP доставчик за изпращане на известия, докато не го активирате. Ако активирате този доставчик, всеки друг доставчик, който е бил активен, сега ще бъде деактивиран."
},
"DEACTIVATE": {
"TITLE": "Деактивирайте вашия SMTP доставчик",
"DESCRIPTION": "Ако деактивирате този SMTP доставчик, ZITADEL не може да го използва за изпращане на известия, докато не го активирате отново."
}
} }
}, },
"DETAIL": { "DETAIL": {

View File

@ -129,7 +129,7 @@
}, },
"PRIVACY_POLICY": { "PRIVACY_POLICY": {
"TITLE": "Externí odkazy", "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": { "SMTP_PROVIDER": {
"TITLE": "Nastavení SMTP", "TITLE": "Nastavení SMTP",
@ -595,6 +595,7 @@
"INVALID_FORMAT": "Formát je neplatný.", "INVALID_FORMAT": "Formát je neplatný.",
"NOTANEMAIL": "Zadaná hodnota není e-mailová adresa.", "NOTANEMAIL": "Zadaná hodnota není e-mailová adresa.",
"MINLENGTH": "Musí být dlouhé alespoň {{requiredLength}} znaků.", "MINLENGTH": "Musí být dlouhé alespoň {{requiredLength}} znaků.",
"MAXLENGTH": "Musí být kratší než {{requiredLength}} znaků",
"UPPERCASEMISSING": "Musí obsahovat velké písmeno.", "UPPERCASEMISSING": "Musí obsahovat velké písmeno.",
"LOWERCASEMISSING": "Musí obsahovat malé písmeno.", "LOWERCASEMISSING": "Musí obsahovat malé písmeno.",
"SYMBOLERROR": "Musí obsahovat symbol nebo interpunkční znaménko.", "SYMBOLERROR": "Musí obsahovat symbol nebo interpunkční znaménko.",
@ -880,7 +881,8 @@
"SET": "Nastavit nové heslo", "SET": "Nastavit nové heslo",
"RESENDNOTIFICATION": "Odeslat odkaz pro reset hesla", "RESENDNOTIFICATION": "Odeslat odkaz pro reset hesla",
"REQUIRED": "Některá povinná pole nejsou vyplněna.", "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", "ID": "ID",
"EMAIL": "E-mail", "EMAIL": "E-mail",
@ -1571,6 +1573,9 @@
"POLICYLINK": "Odkaz na Zásady ochrany osobních údajů", "POLICYLINK": "Odkaz na Zásady ochrany osobních údajů",
"HELPLINK": "Odkaz na pomoc", "HELPLINK": "Odkaz na pomoc",
"SUPPORTEMAIL": "E-mailová podpora", "SUPPORTEMAIL": "E-mailová podpora",
"DOCSLINK": "Odkaz na Dokumenty (Console)",
"CUSTOMLINK": "Vlastní odkaz (Console)",
"CUSTOMLINKTEXT": "Text vlastního odkazu (Console)",
"SAVED": "Úspěšně uloženo!", "SAVED": "Úspěšně uloženo!",
"RESET_TITLE": "Obnovit výchozí hodnoty", "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?" "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": { "SMTP": {
"LIST": { "LIST": {
"TITLE": "Poskytovatel SMTP", "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", "EMPTY": "Není k dispozici žádný poskytovatel SMTP",
"ACTIVATED": "Aktivováno", "ACTIVATED": "Aktivováno",
"ACTIVATE": "Aktivujte poskytovatele", "ACTIVATE": "Aktivujte poskytovatele",
@ -2262,7 +2267,16 @@
"CURRENT_DESC_TITLE": "Toto jsou vaše nastavení SMTP", "CURRENT_DESC_TITLE": "Toto jsou vaše nastavení SMTP",
"PROVIDER_SETTINGS": "Nastavení poskytovatele SMTP", "PROVIDER_SETTINGS": "Nastavení poskytovatele SMTP",
"SENDER_SETTINGS": "Nastavení odesílatele", "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": { "DETAIL": {

View File

@ -129,7 +129,7 @@
}, },
"PRIVACY_POLICY": { "PRIVACY_POLICY": {
"TITLE": "Externe Links", "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": { "SMTP_PROVIDER": {
"TITLE": "SMTP-Einstellungen", "TITLE": "SMTP-Einstellungen",
@ -594,6 +594,7 @@
"INVALID_FORMAT": "Das Format is ungültig.", "INVALID_FORMAT": "Das Format is ungültig.",
"NOTANEMAIL": "Der eingegebene Wert ist keine E-Mail Adresse.", "NOTANEMAIL": "Der eingegebene Wert ist keine E-Mail Adresse.",
"MINLENGTH": "Muss mindestens {{requiredLength}} Zeichen lang sein.", "MINLENGTH": "Muss mindestens {{requiredLength}} Zeichen lang sein.",
"MAXLENGTH": "Muss weniger als {{requiredLength}} Zeichen enthalten",
"UPPERCASEMISSING": "Muss einen Grossbuchstaben beinhalten.", "UPPERCASEMISSING": "Muss einen Grossbuchstaben beinhalten.",
"LOWERCASEMISSING": "Muss einen Kleinbuchstaben beinhalten.", "LOWERCASEMISSING": "Muss einen Kleinbuchstaben beinhalten.",
"SYMBOLERROR": "Muss ein Symbol/Satzzeichen beinhalten.", "SYMBOLERROR": "Muss ein Symbol/Satzzeichen beinhalten.",
@ -879,7 +880,8 @@
"SET": "Passwort neu setzen", "SET": "Passwort neu setzen",
"RESENDNOTIFICATION": "Email zum Zurücksetzen senden", "RESENDNOTIFICATION": "Email zum Zurücksetzen senden",
"REQUIRED": "Bitte prüfe, dass alle notwendigen Felder ausgefüllt sind.", "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", "ID": "ID",
"EMAIL": "E-Mail", "EMAIL": "E-Mail",
@ -1570,6 +1572,9 @@
"POLICYLINK": "Link zur den Datenschutzrichtlinien", "POLICYLINK": "Link zur den Datenschutzrichtlinien",
"HELPLINK": "Link zur Hilfestellung", "HELPLINK": "Link zur Hilfestellung",
"SUPPORTEMAIL": "Support E-Mail", "SUPPORTEMAIL": "Support E-Mail",
"DOCSLINK": "Link zu Dokumenten (Console)",
"CUSTOMLINK": "Benutzerdefinierter Link (Console)",
"CUSTOMLINKTEXT": "Benutzerdefinierter Linktext (Console)",
"SAVED": "Saved successfully!", "SAVED": "Saved successfully!",
"RESET_TITLE": "Standardwerte wiederherstellen", "RESET_TITLE": "Standardwerte wiederherstellen",
"RESET_DESCRIPTION": "Sie sind im Begriff die Standardlinks für die AGBs und Datenschutzrichtlinie wiederherzustellen. Wollen Sie fortfahren?" "RESET_DESCRIPTION": "Sie sind im Begriff die Standardlinks für die AGBs und Datenschutzrichtlinie wiederherzustellen. Wollen Sie fortfahren?"
@ -2224,7 +2229,7 @@
"SMTP": { "SMTP": {
"LIST": { "LIST": {
"TITLE": "SMTP-Anbieter", "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", "EMPTY": "Kein SMTP-Anbieter verfügbar",
"ACTIVATED": "Aktiviert", "ACTIVATED": "Aktiviert",
"ACTIVATE": "Anbieter aktivieren", "ACTIVATE": "Anbieter aktivieren",
@ -2252,7 +2257,16 @@
"CURRENT_DESC_TITLE": "Dies sind Ihre SMTP-Einstellungen", "CURRENT_DESC_TITLE": "Dies sind Ihre SMTP-Einstellungen",
"PROVIDER_SETTINGS": "SMTP-Anbietereinstellungen", "PROVIDER_SETTINGS": "SMTP-Anbietereinstellungen",
"SENDER_SETTINGS": "Absendereinstellungen", "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": { "DETAIL": {

View File

@ -54,7 +54,7 @@
}, },
"MACHINES": { "MACHINES": {
"TITLE": "Service Users", "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." "METADATA": "Add custom attributes to the user like the authenticating system. You can use this information in your actions."
}, },
"SELF": { "SELF": {
@ -129,7 +129,7 @@
}, },
"PRIVACY_POLICY": { "PRIVACY_POLICY": {
"TITLE": "External Links", "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": { "SMTP_PROVIDER": {
"TITLE": "SMTP Settings", "TITLE": "SMTP Settings",
@ -595,8 +595,9 @@
"INVALID_FORMAT": "The formatting is invalid.", "INVALID_FORMAT": "The formatting is invalid.",
"NOTANEMAIL": "The given value is not an e-mail address.", "NOTANEMAIL": "The given value is not an e-mail address.",
"MINLENGTH": "Must be at least {{requiredLength}} characters long.", "MINLENGTH": "Must be at least {{requiredLength}} characters long.",
"UPPERCASEMISSING": "Must include an uppercase character.", "MAXLENGTH": "Must be less than {{requiredLength}} characters.",
"LOWERCASEMISSING": "Must include a lowercase character.", "UPPERCASEMISSING": "Must include an uppercase letter.",
"LOWERCASEMISSING": "Must include a lowercase letter.",
"SYMBOLERROR": "Must include a symbol or punctuation mark.", "SYMBOLERROR": "Must include a symbol or punctuation mark.",
"NUMBERERROR": "Must include a digit.", "NUMBERERROR": "Must include a digit.",
"PWNOTEQUAL": "The passwords provided do not match.", "PWNOTEQUAL": "The passwords provided do not match.",
@ -880,7 +881,8 @@
"SET": "Set New Password", "SET": "Set New Password",
"RESENDNOTIFICATION": "Send Password Reset Link", "RESENDNOTIFICATION": "Send Password Reset Link",
"REQUIRED": "Some required fields are missing.", "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", "ID": "ID",
"EMAIL": "E-mail", "EMAIL": "E-mail",
@ -1335,7 +1337,7 @@
"DOMAIN": "Domain settings", "DOMAIN": "Domain settings",
"LOGINTEXTS": "Login Interface Texts", "LOGINTEXTS": "Login Interface Texts",
"BRANDING": "Branding", "BRANDING": "Branding",
"PRIVACYPOLICY": "Privacy Policy", "PRIVACYPOLICY": "External links",
"OIDC": "OIDC Token lifetime and expiration", "OIDC": "OIDC Token lifetime and expiration",
"SECRETS": "Secret Generator", "SECRETS": "Secret Generator",
"SECURITY": "Security settings", "SECURITY": "Security settings",
@ -1571,6 +1573,9 @@
"POLICYLINK": "Link to Privacy Policy", "POLICYLINK": "Link to Privacy Policy",
"HELPLINK": "Link to Help", "HELPLINK": "Link to Help",
"SUPPORTEMAIL": "Support Email", "SUPPORTEMAIL": "Support Email",
"DOCSLINK": "Docs Link (Console)",
"CUSTOMLINK": "Custom Link (Console)",
"CUSTOMLINKTEXT": "Custom Link Text (Console)",
"SAVED": "Saved successfully!", "SAVED": "Saved successfully!",
"RESET_TITLE": "Restore Default Values", "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?" "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" "DESCRIPTION": "Enter the credentials for your Apple Provider"
}, },
"SAML": { "SAML": {
"TITLE": "Sign in with Saml SP", "TITLE": "Sign in with SAML SP",
"DESCRIPTION": "Enter the credentials for your SAML Provider" "DESCRIPTION": "Enter the credentials for your SAML Provider"
} }
}, },
@ -2174,7 +2179,10 @@
"METADATAXML": "Metadata Xml", "METADATAXML": "Metadata Xml",
"METADATAURL": "Metadata URL", "METADATAURL": "Metadata URL",
"BINDING": "Binding", "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": { "TOAST": {
"SAVED": "Successfully saved.", "SAVED": "Successfully saved.",
@ -2243,7 +2251,7 @@
"SMTP": { "SMTP": {
"LIST": { "LIST": {
"TITLE": "SMTP Provider", "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", "EMPTY": "No SMTP Provider available",
"ACTIVATED": "Activated", "ACTIVATED": "Activated",
"ACTIVATE": "Activate provider", "ACTIVATE": "Activate provider",
@ -2271,7 +2279,16 @@
"CURRENT_DESC_TITLE": "These are your SMTP settings", "CURRENT_DESC_TITLE": "These are your SMTP settings",
"PROVIDER_SETTINGS": "SMTP Provider Settings", "PROVIDER_SETTINGS": "SMTP Provider Settings",
"SENDER_SETTINGS": "Sender 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": { "DETAIL": {

View File

@ -129,7 +129,7 @@
}, },
"PRIVACY_POLICY": { "PRIVACY_POLICY": {
"TITLE": "Enlaces Externos", "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": { "SMTP_PROVIDER": {
"TITLE": "Configuración de SMTP", "TITLE": "Configuración de SMTP",
@ -595,6 +595,7 @@
"INVALID_FORMAT": "El formato no es valido.", "INVALID_FORMAT": "El formato no es valido.",
"NOTANEMAIL": "El valor proporcionado no es una dirección de email.", "NOTANEMAIL": "El valor proporcionado no es una dirección de email.",
"MINLENGTH": "Debe tener al menos {{requiredLength}} caracteres de longitud.", "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.", "UPPERCASEMISSING": "Debe incluir un carácter en mayúscula.",
"LOWERCASEMISSING": "Debe incluir un carácter en minúscula.", "LOWERCASEMISSING": "Debe incluir un carácter en minúscula.",
"SYMBOLERROR": "Debe incluir un símbolo o un signo de puntuación.", "SYMBOLERROR": "Debe incluir un símbolo o un signo de puntuación.",
@ -880,7 +881,8 @@
"SET": "Establecer nueva contraseña", "SET": "Establecer nueva contraseña",
"RESENDNOTIFICATION": "Enviar enlace para restablecer la contraseña", "RESENDNOTIFICATION": "Enviar enlace para restablecer la contraseña",
"REQUIRED": "Faltan algunos campos requeridos.", "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", "ID": "ID",
"EMAIL": "Email", "EMAIL": "Email",
@ -1572,6 +1574,9 @@
"POLICYLINK": "Enlace a Política de privacidad", "POLICYLINK": "Enlace a Política de privacidad",
"HELPLINK": "Enlace de ayuda", "HELPLINK": "Enlace de ayuda",
"SUPPORTEMAIL": "Email de soporte", "SUPPORTEMAIL": "Email de soporte",
"DOCSLINK": "Enlace de documentos (Console)",
"CUSTOMLINK": "Enlace personalizado (Console)",
"CUSTOMLINKTEXT": "Texto de enlace personalizado (Console)",
"SAVED": "¡Se guardó con éxito!", "SAVED": "¡Se guardó con éxito!",
"RESET_TITLE": "Restaurar valores por defecto", "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?" "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": { "SMTP": {
"LIST": { "LIST": {
"TITLE": "Proveedor SMTP", "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", "EMPTY": "No hay ningún proveedor SMTP disponible",
"ACTIVATED": "Activado", "ACTIVATED": "Activado",
"ACTIVATE": "Activar proveedor", "ACTIVATE": "Activar proveedor",
@ -2250,7 +2255,16 @@
"CURRENT_DESC_TITLE": "Estas son tus configuraciones SMTP", "CURRENT_DESC_TITLE": "Estas son tus configuraciones SMTP",
"PROVIDER_SETTINGS": "Configuración del proveedor SMTP", "PROVIDER_SETTINGS": "Configuración del proveedor SMTP",
"SENDER_SETTINGS": "Configuración del remitente", "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": { "DETAIL": {

File diff suppressed because it is too large Load Diff

View File

@ -129,7 +129,7 @@
}, },
"PRIVACY_POLICY": { "PRIVACY_POLICY": {
"TITLE": "Link Esterni", "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": { "SMTP_PROVIDER": {
"TITLE": "Impostazioni SMTP", "TITLE": "Impostazioni SMTP",
@ -593,6 +593,7 @@
"INVALID_FORMAT": "Il formato non è valido.", "INVALID_FORMAT": "Il formato non è valido.",
"NOTANEMAIL": "Il valore dato non è un indirizzo e-mail.", "NOTANEMAIL": "Il valore dato non è un indirizzo e-mail.",
"MINLENGTH": "Deve essere lunga almeno {{requiredLength}} caratteri.", "MINLENGTH": "Deve essere lunga almeno {{requiredLength}} caratteri.",
"MAXLENGTH": "Deve contenere meno di {{requiredLength}} caratteri.",
"UPPERCASEMISSING": "Deve includere un carattere maiuscolo.", "UPPERCASEMISSING": "Deve includere un carattere maiuscolo.",
"LOWERCASEMISSING": "Deve includere un carattere minuscolo.", "LOWERCASEMISSING": "Deve includere un carattere minuscolo.",
"SYMBOLERROR": "Deve includere un simbolo o un segno di punteggiatura.", "SYMBOLERROR": "Deve includere un simbolo o un segno di punteggiatura.",
@ -878,7 +879,8 @@
"SET": "Imposta nuova password", "SET": "Imposta nuova password",
"RESENDNOTIFICATION": "Invia email per la reimpostazione", "RESENDNOTIFICATION": "Invia email per la reimpostazione",
"REQUIRED": "Mancano alcuni campi obbligatori.", "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", "ID": "ID",
"EMAIL": "E-mail", "EMAIL": "E-mail",
@ -1570,6 +1572,9 @@
"POLICYLINK": "Link all'informativa sulla privacy", "POLICYLINK": "Link all'informativa sulla privacy",
"HELPLINK": "link per l'aiuto", "HELPLINK": "link per l'aiuto",
"SUPPORTEMAIL": "e-mail di supporto", "SUPPORTEMAIL": "e-mail di supporto",
"DOCSLINK": "Collegamento a Documenti (Console)",
"CUSTOMLINK": "Collegamento personalizzato (Console)",
"CUSTOMLINKTEXT": "Testo del collegamento personalizzato (Console)",
"SAVED": "Salvato con successo!", "SAVED": "Salvato con successo!",
"RESET_TITLE": "Ripristina i valori predefiniti", "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?" "RESET_DESCRIPTION": "Stai per ripristinare i link predefiniti per i TOS e l'informativa sulla privacy. Vuoi davvero continuare?"
@ -2225,7 +2230,7 @@
"SMTP": { "SMTP": {
"LIST": { "LIST": {
"TITLE": "Fornitore SMTP", "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", "EMPTY": "Nessun provider SMTP disponibile",
"ACTIVATED": "Attivato", "ACTIVATED": "Attivato",
"ACTIVATE": "Attiva fornitore", "ACTIVATE": "Attiva fornitore",
@ -2253,7 +2258,16 @@
"CURRENT_DESC_TITLE": "Queste sono le tue impostazioni SMTP", "CURRENT_DESC_TITLE": "Queste sono le tue impostazioni SMTP",
"PROVIDER_SETTINGS": "Impostazioni del provider SMTP", "PROVIDER_SETTINGS": "Impostazioni del provider SMTP",
"SENDER_SETTINGS": "Impostazioni mittente", "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": { "DETAIL": {

View File

@ -129,7 +129,7 @@
}, },
"PRIVACY_POLICY": { "PRIVACY_POLICY": {
"TITLE": "外部リンク", "TITLE": "外部リンク",
"DESCRIPTION": "ログインページに表示されるカスタム外部リソースへのユーザーガイドです。ユーザーは、サインアップする前に利用規約とプライバシーポリシーを受け入れる必要があります。" "DESCRIPTION": "ログイン ページに表示されるカスタム外部リソースにユーザーを誘導します。ユーザーはサインアップする前に、サービス利用規約とプライバシー ポリシーに同意する必要があります。ドキュメントへのリンクを変更するか、空の文字列を設定してコンソールからドキュメント ボタンを非表示にします。カスタム外部リンクとそのリンクのカスタム テキストをコンソールに追加するか、それらを空に設定してそのボタンを非表示にします。"
}, },
"SMTP_PROVIDER": { "SMTP_PROVIDER": {
"TITLE": "SMTP設定", "TITLE": "SMTP設定",
@ -595,6 +595,7 @@
"INVALID_FORMAT": "不正なフォーマットです", "INVALID_FORMAT": "不正なフォーマットです",
"NOTANEMAIL": "入力された値がメールアドレスではありません。", "NOTANEMAIL": "入力された値がメールアドレスではありません。",
"MINLENGTH": "{{requiredLength}} 文字以上の文字列が必要です。", "MINLENGTH": "{{requiredLength}} 文字以上の文字列が必要です。",
"MAXLENGTH": "{{requiredLength}}文字以下でなければなりません.",
"UPPERCASEMISSING": "大文字を含める必要があります。", "UPPERCASEMISSING": "大文字を含める必要があります。",
"LOWERCASEMISSING": "小文字を含める必要があります。", "LOWERCASEMISSING": "小文字を含める必要があります。",
"SYMBOLERROR": "記号を含める必要があります。", "SYMBOLERROR": "記号を含める必要があります。",
@ -880,7 +881,8 @@
"SET": "新しいパスワードを設定する", "SET": "新しいパスワードを設定する",
"RESENDNOTIFICATION": "パスワードリセットのリンクを送信する", "RESENDNOTIFICATION": "パスワードリセットのリンクを送信する",
"REQUIRED": "一部の必須項目が不足しています。", "REQUIRED": "一部の必須項目が不足しています。",
"MINLENGTHERROR": "最小で{{value}}文字の長さが必要です。" "MINLENGTHERROR": "最小で{{value}}文字の長さが必要です。",
"MAXLENGTHERROR": "{{value}}文字以下でなければなりません"
}, },
"ID": "id", "ID": "id",
"EMAIL": "Eメール", "EMAIL": "Eメール",
@ -1566,6 +1568,10 @@
"TOSLINK": "利用規約へのリンク", "TOSLINK": "利用規約へのリンク",
"POLICYLINK": "プライバシーポリシーへのリンク", "POLICYLINK": "プライバシーポリシーへのリンク",
"HELPLINK": "ヘルプへのリンク", "HELPLINK": "ヘルプへのリンク",
"SUPPORTEMAIL": "サポートメール",
"DOCSLINK": "ドキュメントリンク (Console)",
"CUSTOMLINK": "カスタムリンク(Console)",
"CUSTOMLINKTEXT": "カスタム リンク テキスト (Console)",
"SAVED": "正常に保存されました!", "SAVED": "正常に保存されました!",
"RESET_TITLE": "デフォルト値を復元する", "RESET_TITLE": "デフォルト値を復元する",
"RESET_DESCRIPTION": "TOSおよびプライバシーポリシーのデフォルトリンクを復元しようとしています。本当によろしいですか" "RESET_DESCRIPTION": "TOSおよびプライバシーポリシーのデフォルトリンクを復元しようとしています。本当によろしいですか"
@ -2216,7 +2222,7 @@
"SMTP": { "SMTP": {
"LIST": { "LIST": {
"TITLE": "SMTPプロバイダー", "TITLE": "SMTPプロバイダー",
"DESCRIPTION": "これらは、Zitadel インスタンスの SMTP プロバイダーです。ユーザーに通知を送信するために使用するものをアクティブにします。", "DESCRIPTION": "これらは、ZITADEL インスタンスの SMTP プロバイダーです。ユーザーに通知を送信するために使用するものをアクティブにします。",
"EMPTY": "使用可能な SMTP プロバイダーがありません", "EMPTY": "使用可能な SMTP プロバイダーがありません",
"ACTIVATED": "アクティブ化された", "ACTIVATED": "アクティブ化された",
"ACTIVATE": "プロバイダーをアクティブ化する", "ACTIVATE": "プロバイダーをアクティブ化する",
@ -2244,7 +2250,16 @@
"CURRENT_DESC_TITLE": "これらは SMTP 設定です", "CURRENT_DESC_TITLE": "これらは SMTP 設定です",
"PROVIDER_SETTINGS": "SMTPプロバイダーの設定", "PROVIDER_SETTINGS": "SMTPプロバイダーの設定",
"SENDER_SETTINGS": "送信者の設定", "SENDER_SETTINGS": "送信者の設定",
"TEST_SETTINGS": "SMTP設定をテストする" "TEST_SETTINGS": "SMTP設定をテストする",
"NEXT_STEPS": "次のステップ",
"ACTIVATE": {
"TITLE": "SMTP プロバイダーをアクティブ化する",
"DESCRIPTION": "ZITADEL は、アクティブ化するまで、この SMTP プロバイダーを使用して通知を送信できません。このプロバイダーをアクティブ化すると、アクティブだった他のプロバイダーは非アクティブ化されます。"
},
"DEACTIVATE": {
"TITLE": "SMTPプロバイダーを非アクティブ化します",
"DESCRIPTION": "この SMTP プロバイダーを非アクティブ化すると、再度アクティブ化するまで、Zitadel はそれを使用して通知を送信できなくなります。"
}
} }
}, },
"DETAIL": { "DETAIL": {

View File

@ -129,7 +129,7 @@
}, },
"PRIVACY_POLICY": { "PRIVACY_POLICY": {
"TITLE": "Надворешни врски", "TITLE": "Надворешни врски",
"DESCRIPTION": "Упатете ги вашите корисници кон прилагодени надворешни ресурси прикажани на страницата за најава. Корисниците треба да ги прифатат условите за користење и политиката за приватност пред да се регистрираат." "DESCRIPTION": "Водете ги вашите корисници до сопствени надворешни ресурси прикажани на страницата за најавување. Корисниците треба да ги прифатат Условите за користење и Политиката за приватност пред да можат да се регистрираат. Променете ја врската до вашата документација или поставете празна низа за да го скриете копчето за документација од конзолата. Додајте приспособена надворешна врска и прилагоден текст за таа врска во конзолата или поставете ги празни за да го скриете тоа копче."
}, },
"SMTP_PROVIDER": { "SMTP_PROVIDER": {
"TITLE": "SMTP поставки", "TITLE": "SMTP поставки",
@ -595,6 +595,7 @@
"INVALID_FORMAT": "Невалиден формат.", "INVALID_FORMAT": "Невалиден формат.",
"NOTANEMAIL": "Внесената вредност не е е-пошта.", "NOTANEMAIL": "Внесената вредност не е е-пошта.",
"MINLENGTH": "Мора да биде најмалку {{requiredLength}} карактери долга.", "MINLENGTH": "Мора да биде најмалку {{requiredLength}} карактери долга.",
"MAXLENGTH": "Мора да биде помалку од {{requiredLength}} карактери.",
"UPPERCASEMISSING": "Мора да содржи голема буква.", "UPPERCASEMISSING": "Мора да содржи голема буква.",
"LOWERCASEMISSING": "Мора да содржи мала буква.", "LOWERCASEMISSING": "Мора да содржи мала буква.",
"SYMBOLERROR": "Мора да содржи симбол или знак за интерпункција.", "SYMBOLERROR": "Мора да содржи симбол или знак за интерпункција.",
@ -880,7 +881,8 @@
"SET": "Постави нова лозинка", "SET": "Постави нова лозинка",
"RESENDNOTIFICATION": "Испрати линк за ресетирање на лозинката", "RESENDNOTIFICATION": "Испрати линк за ресетирање на лозинката",
"REQUIRED": "Некои задолжителни полиња не се пополнети.", "REQUIRED": "Некои задолжителни полиња не се пополнети.",
"MINLENGTHERROR": "Мора да биде најмалку {{value}} карактери долга." "MINLENGTHERROR": "Мора да биде најмалку {{value}} карактери долга.",
"MAXLENGTHERROR": "Мора да биде помалку од {{value}} карактери"
}, },
"ID": "ID", "ID": "ID",
"EMAIL": "E-пошта", "EMAIL": "E-пошта",
@ -1572,6 +1574,9 @@
"POLICYLINK": "Линк кон Политиката за приватност", "POLICYLINK": "Линк кон Политиката за приватност",
"HELPLINK": "Линк кон Помош", "HELPLINK": "Линк кон Помош",
"SUPPORTEMAIL": "Е-пошта за поддршка", "SUPPORTEMAIL": "Е-пошта за поддршка",
"DOCSLINK": "Врска за документи (Console)",
"CUSTOMLINK": "Прилагодена врска (Console)",
"CUSTOMLINKTEXT": "Текст за приспособена врска (Console)",
"SAVED": "Успешно зачувано!", "SAVED": "Успешно зачувано!",
"RESET_TITLE": "Врати на стандардни вредности", "RESET_TITLE": "Врати на стандардни вредности",
"RESET_DESCRIPTION": "Се подготвувате да ги вратите стандардните линкови за Условите за користење и Политиката за приватност. Дали сте сигурни дека сакате да продолжите?" "RESET_DESCRIPTION": "Се подготвувате да ги вратите стандардните линкови за Условите за користење и Политиката за приватност. Дали сте сигурни дека сакате да продолжите?"
@ -2222,7 +2227,7 @@
"SMTP": { "SMTP": {
"LIST": { "LIST": {
"TITLE": "SMTP провајдер", "TITLE": "SMTP провајдер",
"DESCRIPTION": "Ова се давателите на SMTP за вашиот пример Zitadel. Активирајте го оној што сакате да го користите за испраќање известувања до вашите корисници.", "DESCRIPTION": "Ова се давателите на SMTP за вашиот пример ZITADEL. Активирајте го оној што сакате да го користите за испраќање известувања до вашите корисници.",
"EMPTY": "Нема достапен SMTP провајдер", "EMPTY": "Нема достапен SMTP провајдер",
"ACTIVATED": "Активиран", "ACTIVATED": "Активиран",
"ACTIVATE": "Активирајте го провајдерот", "ACTIVATE": "Активирајте го провајдерот",
@ -2250,7 +2255,16 @@
"CURRENT_DESC_TITLE": "Ова се вашите поставки за SMTP", "CURRENT_DESC_TITLE": "Ова се вашите поставки за SMTP",
"PROVIDER_SETTINGS": "Поставки на провајдерот SMTP", "PROVIDER_SETTINGS": "Поставки на провајдерот SMTP",
"SENDER_SETTINGS": "Поставки на испраќачот", "SENDER_SETTINGS": "Поставки на испраќачот",
"TEST_SETTINGS": "Тестирајте ги поставките за SMTP" "TEST_SETTINGS": "Тестирајте ги поставките за SMTP",
"NEXT_STEPS": "Следните чекори",
"ACTIVATE": {
"TITLE": "Активирајте го вашиот SMTP провајдер",
"DESCRIPTION": "ZITADEL не може да го користи овој SMTP провајдер за да испраќа известувања додека не го активирате. Ако го активирате овој добавувач, секој друг провајдер што бил активен сега ќе се деактивира."
},
"DEACTIVATE": {
"TITLE": "Деактивирајте го вашиот SMTP провајдер",
"DESCRIPTION": "Ако го деактивирате овој SMTP провајдер, ZITADEL не може да го користи за испраќање известувања додека не го активирате повторно."
}
} }
}, },
"DETAIL": { "DETAIL": {

View File

@ -129,7 +129,7 @@
}, },
"PRIVACY_POLICY": { "PRIVACY_POLICY": {
"TITLE": "Externe links", "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": { "SMTP_PROVIDER": {
"TITLE": "SMTP-instellingen", "TITLE": "SMTP-instellingen",
@ -595,6 +595,7 @@
"INVALID_FORMAT": "De opmaak is ongeldig.", "INVALID_FORMAT": "De opmaak is ongeldig.",
"NOTANEMAIL": "De opgegeven waarde is geen e-mailadres.", "NOTANEMAIL": "De opgegeven waarde is geen e-mailadres.",
"MINLENGTH": "Moet minimaal {{requiredLength}} tekens lang zijn.", "MINLENGTH": "Moet minimaal {{requiredLength}} tekens lang zijn.",
"MAXLENGTH": "Moet minder dan {{requiredLength}} tekens bevatten.",
"UPPERCASEMISSING": "Moet een hoofdletter bevatten.", "UPPERCASEMISSING": "Moet een hoofdletter bevatten.",
"LOWERCASEMISSING": "Moet een kleine letter bevatten.", "LOWERCASEMISSING": "Moet een kleine letter bevatten.",
"SYMBOLERROR": "Moet een symbool of leesteken bevatten.", "SYMBOLERROR": "Moet een symbool of leesteken bevatten.",
@ -880,7 +881,8 @@
"SET": "Stel nieuw wachtwoord in", "SET": "Stel nieuw wachtwoord in",
"RESENDNOTIFICATION": "Stuur wachtwoord reset link", "RESENDNOTIFICATION": "Stuur wachtwoord reset link",
"REQUIRED": "Sommige verplichte velden ontbreken.", "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", "ID": "ID",
"EMAIL": "E-mail", "EMAIL": "E-mail",
@ -1571,6 +1573,9 @@
"POLICYLINK": "Link naar Privacybeleid", "POLICYLINK": "Link naar Privacybeleid",
"HELPLINK": "Link naar Help", "HELPLINK": "Link naar Help",
"SUPPORTEMAIL": "Ondersteuning Email", "SUPPORTEMAIL": "Ondersteuning Email",
"DOCSLINK": "Documentenlink (Console)",
"CUSTOMLINK": "Aangepaste link (Console)",
"CUSTOMLINKTEXT": "Aangepaste linktekst (Console)",
"SAVED": "Succesvol opgeslagen!", "SAVED": "Succesvol opgeslagen!",
"RESET_TITLE": "Herstel Standaard Waarden", "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?" "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" "DESCRIPTION": "Voer de inloggegevens in voor uw Apple Provider"
}, },
"SAML": { "SAML": {
"TITLE": "Log in met Saml SP", "TITLE": "Log in met SAML SP",
"DESCRIPTION": "Voer de inloggegevens in voor uw SAML Provider" "DESCRIPTION": "Voer de inloggegevens in voor uw SAML Provider"
} }
}, },
@ -2243,7 +2248,7 @@
"SMTP": { "SMTP": {
"LIST": { "LIST": {
"TITLE": "SMTP-provider", "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", "EMPTY": "Geen SMTP-provider beschikbaar",
"ACTIVATED": "Geactiveerd", "ACTIVATED": "Geactiveerd",
"ACTIVATE": "Aanbieder activeren", "ACTIVATE": "Aanbieder activeren",
@ -2271,7 +2276,16 @@
"CURRENT_DESC_TITLE": "Dit zijn uw SMTP-instellingen", "CURRENT_DESC_TITLE": "Dit zijn uw SMTP-instellingen",
"PROVIDER_SETTINGS": "SMTP-providerinstellingen", "PROVIDER_SETTINGS": "SMTP-providerinstellingen",
"SENDER_SETTINGS": "Afzenderinstellingen", "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": { "DETAIL": {

View File

@ -129,7 +129,7 @@
}, },
"PRIVACY_POLICY": { "PRIVACY_POLICY": {
"TITLE": "Linki zewnętrzne", "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": { "SMTP_PROVIDER": {
"TITLE": "Ustawienia SMTP", "TITLE": "Ustawienia SMTP",
@ -594,6 +594,7 @@
"INVALID_FORMAT": "Format jest nieprawidłowy.", "INVALID_FORMAT": "Format jest nieprawidłowy.",
"NOTANEMAIL": "Podana wartość nie jest adresem e-mail.", "NOTANEMAIL": "Podana wartość nie jest adresem e-mail.",
"MINLENGTH": "Musi mieć co najmniej {{requiredLength}} znaków.", "MINLENGTH": "Musi mieć co najmniej {{requiredLength}} znaków.",
"MAXLENGTH": "Musi zawierać mniej niż {{requiredLength}} znaków.",
"UPPERCASEMISSING": "Musi zawierać wielką literę.", "UPPERCASEMISSING": "Musi zawierać wielką literę.",
"LOWERCASEMISSING": "Musi zawierać małą literę.", "LOWERCASEMISSING": "Musi zawierać małą literę.",
"SYMBOLERROR": "Musi zawierać symbol lub znak interpunkcyjny.", "SYMBOLERROR": "Musi zawierać symbol lub znak interpunkcyjny.",
@ -879,7 +880,8 @@
"SET": "Ustaw nowe hasło", "SET": "Ustaw nowe hasło",
"RESENDNOTIFICATION": "Wyślij link resetowania hasła", "RESENDNOTIFICATION": "Wyślij link resetowania hasła",
"REQUIRED": "Brakuje niektórych wymaganych pól.", "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", "ID": "ID",
"EMAIL": "E-mail", "EMAIL": "E-mail",
@ -1570,6 +1572,9 @@
"POLICYLINK": "Link do polityki prywatności", "POLICYLINK": "Link do polityki prywatności",
"HELPLINK": "Link do pomocy", "HELPLINK": "Link do pomocy",
"SUPPORTEMAIL": "E-mail wsparcia", "SUPPORTEMAIL": "E-mail wsparcia",
"DOCSLINK": "Link do Dokumentów (Console)",
"CUSTOMLINK": "Link niestandardowy (Console)",
"CUSTOMLINKTEXT": "Niestandardowy tekst łącza (Console)",
"SAVED": "Pomyślnie zapisano!", "SAVED": "Pomyślnie zapisano!",
"RESET_TITLE": "Przywróć wartości domyślne", "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ć?" "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": { "SMTP": {
"LIST": { "LIST": {
"TITLE": "Dostawca SMTP", "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", "EMPTY": "Brak dostępnego dostawcy SMTP",
"ACTIVATED": "Aktywowany", "ACTIVATED": "Aktywowany",
"ACTIVATE": "Aktywuj dostawcę", "ACTIVATE": "Aktywuj dostawcę",
@ -2253,7 +2258,16 @@
"CURRENT_DESC_TITLE": "To są Twoje ustawienia SMTP", "CURRENT_DESC_TITLE": "To są Twoje ustawienia SMTP",
"PROVIDER_SETTINGS": "Ustawienia dostawcy SMTP", "PROVIDER_SETTINGS": "Ustawienia dostawcy SMTP",
"SENDER_SETTINGS": "Ustawienia nadawcy", "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": { "DETAIL": {

View File

@ -129,7 +129,7 @@
}, },
"PRIVACY_POLICY": { "PRIVACY_POLICY": {
"TITLE": "Links Externos", "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": { "SMTP_PROVIDER": {
"TITLE": "Configurações de SMTP", "TITLE": "Configurações de SMTP",
@ -595,6 +595,7 @@
"INVALID_FORMAT": "O formato é inválido.", "INVALID_FORMAT": "O formato é inválido.",
"NOTANEMAIL": "O valor fornecido não é um endereço de e-mail.", "NOTANEMAIL": "O valor fornecido não é um endereço de e-mail.",
"MINLENGTH": "Deve ter pelo menos {{requiredLength}} caracteres.", "MINLENGTH": "Deve ter pelo menos {{requiredLength}} caracteres.",
"MAXLENGTH": "Deve ter menos de {{requiredLength}} caracteres.",
"UPPERCASEMISSING": "Deve incluir uma letra maiúscula.", "UPPERCASEMISSING": "Deve incluir uma letra maiúscula.",
"LOWERCASEMISSING": "Deve incluir uma letra minúscula.", "LOWERCASEMISSING": "Deve incluir uma letra minúscula.",
"SYMBOLERROR": "Deve incluir um símbolo ou caractere de pontuação.", "SYMBOLERROR": "Deve incluir um símbolo ou caractere de pontuação.",
@ -880,7 +881,8 @@
"SET": "Definir Nova Senha", "SET": "Definir Nova Senha",
"RESENDNOTIFICATION": "Enviar Link de Redefinição de Senha", "RESENDNOTIFICATION": "Enviar Link de Redefinição de Senha",
"REQUIRED": "Algumas informações obrigatórias estão faltando.", "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", "ID": "ID",
"EMAIL": "E-mail", "EMAIL": "E-mail",
@ -1572,6 +1574,9 @@
"POLICYLINK": "Link para a Política de Privacidade", "POLICYLINK": "Link para a Política de Privacidade",
"HELPLINK": "Link para Ajuda", "HELPLINK": "Link para Ajuda",
"SUPPORTEMAIL": "E-mail de suporte", "SUPPORTEMAIL": "E-mail de suporte",
"DOCSLINK": "Link do Documentos (Console)",
"CUSTOMLINK": "Link personalizado (Console)",
"CUSTOMLINKTEXT": "Texto do link personalizado (Console)",
"SAVED": "Salvo com sucesso!", "SAVED": "Salvo com sucesso!",
"RESET_TITLE": "Restaurar valores padrão", "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?" "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": { "SMTP": {
"LIST": { "LIST": {
"TITLE": "Provedor SMTP", "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", "EMPTY": "Nenhum provedor SMTP disponível",
"ACTIVATED": "Ativado", "ACTIVATED": "Ativado",
"ACTIVATE": "Ativar provedor", "ACTIVATE": "Ativar provedor",
@ -2248,7 +2253,16 @@
"CURRENT_DESC_TITLE": "Estas são suas configurações de SMTP", "CURRENT_DESC_TITLE": "Estas são suas configurações de SMTP",
"PROVIDER_SETTINGS": "Configurações do provedor SMTP", "PROVIDER_SETTINGS": "Configurações do provedor SMTP",
"SENDER_SETTINGS": "Configurações do remetente", "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": { "DETAIL": {

View File

@ -129,7 +129,7 @@
}, },
"PRIVACY_POLICY": { "PRIVACY_POLICY": {
"TITLE": "Внешние ссылки", "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": { "SMTP_PROVIDER": {
"TITLE": "Настройки SMTP", "TITLE": "Настройки SMTP",
@ -594,6 +594,7 @@
"INVALID_FORMAT": "Форматирование неверно.", "INVALID_FORMAT": "Форматирование неверно.",
"NOTANEMAIL": "Данное значение не является адресом электронной почты.", "NOTANEMAIL": "Данное значение не является адресом электронной почты.",
"MINLENGTH": "Должно быть не менее {{requiredLength}} символов.", "MINLENGTH": "Должно быть не менее {{requiredLength}} символов.",
"MAXLENGTH": "Должно быть меньше {{requiredLength}} символов.",
"UPPERCASEMISSING": "Должен содержать символ верхнего регистра.", "UPPERCASEMISSING": "Должен содержать символ верхнего регистра.",
"LOWERCASEMISSING": "Должен включать строчные буквы.", "LOWERCASEMISSING": "Должен включать строчные буквы.",
"SYMBOLERROR": "Должен содержать символ или знак препинания.", "SYMBOLERROR": "Должен содержать символ или знак препинания.",
@ -887,7 +888,8 @@
"RESENDNOTIFICATION": "Отправить ссылку для сброса пароля", "RESENDNOTIFICATION": "Отправить ссылку для сброса пароля",
"REQUIRED": "Отсутствуют некоторые обязательные поля.", "REQUIRED": "Отсутствуют некоторые обязательные поля.",
"MINLENGTHERROR": "Должно быть не менее {{value}} символов.", "MINLENGTHERROR": "Должно быть не менее {{value}} символов.",
"NOTEQUAL": "Указанные пароли не совпадают." "NOTEQUAL": "Указанные пароли не совпадают.",
"MAXLENGTHERROR": "Должно быть меньше {{value}} символов"
}, },
"ID": "Идентификатор", "ID": "Идентификатор",
"EMAIL": "Электронная почта", "EMAIL": "Электронная почта",
@ -1626,6 +1628,9 @@
"POLICYLINK": "Ссылка на Политику конфиденциальности", "POLICYLINK": "Ссылка на Политику конфиденциальности",
"HELPLINK": "Ссылка на Помощь", "HELPLINK": "Ссылка на Помощь",
"SUPPORTEMAIL": "Электронная почта поддержки", "SUPPORTEMAIL": "Электронная почта поддержки",
"DOCSLINK": "Ссылка на Документы (Console)",
"CUSTOMLINK": "Пользовательская ссылка (Console)",
"CUSTOMLINKTEXT": "Пользовательский текст ссылки (Console)",
"SAVED": "Успешно сохранено!", "SAVED": "Успешно сохранено!",
"RESET_TITLE": "Восстановить значения по умолчанию", "RESET_TITLE": "Восстановить значения по умолчанию",
"RESET_DESCRIPTION": "Вы собираетесь восстановить ссылки по умолчанию для Пользовательского соглашения и Политики конфиденциальности. Вы действительно хотите продолжить?" "RESET_DESCRIPTION": "Вы собираетесь восстановить ссылки по умолчанию для Пользовательского соглашения и Политики конфиденциальности. Вы действительно хотите продолжить?"
@ -2337,7 +2342,7 @@
"SMTP": { "SMTP": {
"LIST": { "LIST": {
"TITLE": "SMTP-провайдер", "TITLE": "SMTP-провайдер",
"DESCRIPTION": "Это поставщики SMTP для вашего экземпляра Zitadel. Активируйте тот, который вы хотите использовать для отправки уведомлений вашим пользователям.", "DESCRIPTION": "Это поставщики SMTP для вашего экземпляра ZITADEL. Активируйте тот, который вы хотите использовать для отправки уведомлений вашим пользователям.",
"EMPTY": "SMTP-провайдер не доступен", "EMPTY": "SMTP-провайдер не доступен",
"ACTIVATED": "Активировано", "ACTIVATED": "Активировано",
"ACTIVATE": "Активировать провайдера", "ACTIVATE": "Активировать провайдера",
@ -2365,7 +2370,16 @@
"CURRENT_DESC_TITLE": "Это ваши настройки SMTP", "CURRENT_DESC_TITLE": "Это ваши настройки SMTP",
"PROVIDER_SETTINGS": "Настройки SMTP-провайдера", "PROVIDER_SETTINGS": "Настройки SMTP-провайдера",
"SENDER_SETTINGS": "Настройки отправителя", "SENDER_SETTINGS": "Настройки отправителя",
"TEST_SETTINGS": "Проверка настроек SMTP" "TEST_SETTINGS": "Проверка настроек SMTP",
"NEXT_STEPS": "Следующие шаги",
"ACTIVATE": {
"TITLE": "Активируйте своего SMTP-провайдера",
"DESCRIPTION": "ZITADEL не может использовать этого поставщика SMTP для отправки уведомлений, пока вы его не активируете. Если вы активируете этого провайдера, любой другой провайдер, который был активен, теперь будет деактивирован."
},
"DEACTIVATE": {
"TITLE": "Деактивируйте своего SMTP-провайдера",
"DESCRIPTION": "Если вы деактивируете этого поставщика SMTP, ZITADEL не сможет использовать его для отправки уведомлений, пока вы не активируете его снова."
}
} }
}, },
"DETAIL": { "DETAIL": {

View File

@ -129,7 +129,7 @@
}, },
"PRIVACY_POLICY": { "PRIVACY_POLICY": {
"TITLE": "外部链接", "TITLE": "外部链接",
"DESCRIPTION": "引导您的用户到登录页面上显示的自定义外部资源。用户需要在注册前接受服务条款和隐私政策。" "DESCRIPTION": "引导您的用户访问登录页面上显示的自定义外部资源。用户需要先接受服务条款和隐私政策,然后才能注册。更改文档的链接或设置空字符串以在控制台中隐藏文档按钮。在控制台中添加自定义外部链接和该链接的自定义文本,或将它们设置为空以隐藏该按钮。"
}, },
"SMTP_PROVIDER": { "SMTP_PROVIDER": {
"TITLE": "SMTP设置", "TITLE": "SMTP设置",
@ -594,6 +594,7 @@
"INVALID_FORMAT": "格式是无效的。", "INVALID_FORMAT": "格式是无效的。",
"NOTANEMAIL": "给定的值不是合法电子邮件地址。", "NOTANEMAIL": "给定的值不是合法电子邮件地址。",
"MINLENGTH": "长度必须至少是{{requiredLength}}字符。", "MINLENGTH": "长度必须至少是{{requiredLength}}字符。",
"MAXLENGTH": "必须少于{{requiredLength}}个字符.",
"UPPERCASEMISSING": "密码必须包含大写字符。", "UPPERCASEMISSING": "密码必须包含大写字符。",
"LOWERCASEMISSING": "密码必须包含小写字符。", "LOWERCASEMISSING": "密码必须包含小写字符。",
"SYMBOLERROR": "密码必须包含符号或标点符号。", "SYMBOLERROR": "密码必须包含符号或标点符号。",
@ -879,7 +880,8 @@
"SET": "设置新密码", "SET": "设置新密码",
"RESENDNOTIFICATION": "发送重置密码链接", "RESENDNOTIFICATION": "发送重置密码链接",
"REQUIRED": "缺少必填字段。", "REQUIRED": "缺少必填字段。",
"MINLENGTHERROR": "密码长度必须至少为 {{value}} 个字符。" "MINLENGTHERROR": "密码长度必须至少为 {{value}} 个字符。",
"MAXLENGTHERROR": "必须少于{{value}}个字符"
}, },
"ID": "ID", "ID": "ID",
"EMAIL": "电子邮件", "EMAIL": "电子邮件",
@ -1569,6 +1571,9 @@
"POLICYLINK": "链接到隐私政策", "POLICYLINK": "链接到隐私政策",
"HELPLINK": "链接到帮助", "HELPLINK": "链接到帮助",
"SUPPORTEMAIL": "支持邮箱", "SUPPORTEMAIL": "支持邮箱",
"DOCSLINK": "文档链接Console",
"CUSTOMLINK": "自定义链接Console",
"CUSTOMLINKTEXT": "自定义链接文本Console",
"SAVED": "保存成功!", "SAVED": "保存成功!",
"RESET_TITLE": "恢复默认值", "RESET_TITLE": "恢复默认值",
"RESET_DESCRIPTION": "您即将恢复 TOS 和隐私政策的默认链接。你真的要继续吗?" "RESET_DESCRIPTION": "您即将恢复 TOS 和隐私政策的默认链接。你真的要继续吗?"
@ -2224,7 +2229,7 @@
"SMTP": { "SMTP": {
"LIST": { "LIST": {
"TITLE": "SMTP 提供商", "TITLE": "SMTP 提供商",
"DESCRIPTION": "这些是您的 Zitadel 实例的 SMTP 提供商。激活您想要用来向用户发送通知的通知。", "DESCRIPTION": "这些是您的 ZITADEL 实例的 SMTP 提供商。激活您想要用来向用户发送通知的通知。",
"EMPTY": "没有可用的 SMTP 提供商", "EMPTY": "没有可用的 SMTP 提供商",
"ACTIVATED": "活性", "ACTIVATED": "活性",
"ACTIVATE": "激活提供商", "ACTIVATE": "激活提供商",
@ -2252,7 +2257,16 @@
"CURRENT_DESC_TITLE": "这些是您的 SMTP 设置", "CURRENT_DESC_TITLE": "这些是您的 SMTP 设置",
"PROVIDER_SETTINGS": "SMTP 提供商设置", "PROVIDER_SETTINGS": "SMTP 提供商设置",
"SENDER_SETTINGS": "发件人设置", "SENDER_SETTINGS": "发件人设置",
"TEST_SETTINGS": "测试 SMTP 设置" "TEST_SETTINGS": "测试 SMTP 设置",
"NEXT_STEPS": "下一步",
"ACTIVATE": {
"TITLE": "激活您的 SMTP 提供商",
"DESCRIPTION": "在您激活此 SMTP 提供程序之前Zitadel 无法使用它来发送通知。如果您激活此提供程序,任何其他处于活动状态的提供程序现在都将被停用。"
},
"DEACTIVATE": {
"TITLE": "停用您的 SMTP 提供商",
"DESCRIPTION": "如果您停用此 SMTP 提供程序Zitadel 将无法使用它发送通知,直到您再次激活它。"
}
} }
}, },
"DETAIL": { "DETAIL": {

View File

@ -86,6 +86,11 @@ And if you use a different service, for example `zitadel.session.v2.SessionServi
### Targets and Includes ### 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. 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. The Includes can be defined in the Execution directly, which means you include all defined Targets by a before set Execution.

View 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.

View File

@ -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. 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. 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 ## Accessing the Audit Log
### Last changes of an object ### 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 ## 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). Follow our guide on how to [integrate ZITADEL with external systems for streaming events and audit logs](/docs/guides/integrate/external-audit-log).
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

View File

@ -1,10 +1,28 @@
--- ---
title: ZITADEL Applications title: Configure applications for your frontend and backend services and clients
sidebar_label: Applications 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)

View File

@ -1,6 +1,7 @@
--- ---
title: ZITADEL Instances title: ZITADEL Instances
sidebar_label: Instances sidebar_label: Instances
sidebar_position: 1
--- ---
## Instance Structure ## Instance Structure

View File

@ -1,6 +1,7 @@
--- ---
title: ZITADEL Organizations title: ZITADEL Organizations
sidebar_label: Organizations sidebar_label: Organizations
sidebar_position: 2
--- ---
import OrgDescription from './_org_description.mdx'; import OrgDescription from './_org_description.mdx';

View File

@ -1,10 +1,9 @@
--- ---
title: ZITADEL Projects title: Organize applications, services, and roles with projects
sidebar_label: Projects sidebar_label: Projects
sidebar_position: 4
--- ---
# Project
import ProjectDescription from './\_project_description.mdx'; import ProjectDescription from './\_project_description.mdx';
<ProjectDescription name="ProjectDescription" /> <ProjectDescription name="ProjectDescription" />

View File

@ -1,6 +1,7 @@
--- ---
title: ZITADEL Users title: ZITADEL Users
sidebar_label: Users sidebar_label: Users
sidebar_position: 3
--- ---
## Types of users ## 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. 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. 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
Service users are for machine-to-machine communication and you would use those typically to access secure backend services. 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. 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. 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 ### Managers
Any user, human or service user, can be given a [Manager](/concepts/structure/managers) role. 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. 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). Users can only exist within one [organization](/concepts/structure/organizations).
It is currently not possible to move users between 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`). 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. 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). Consider this general recommendation as a starting point:
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.
## 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. You might want to adjust this general setup based on your [scenario](/guides/solution-scenarios/introduction).
The external identity will be linked to the ZITADEL account.
You can link multiple external accounts to a ZITADEl account. 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.
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.
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)

View File

@ -8,7 +8,7 @@ OAuth 2 Token Introspection.
At the end of the guide you should have an API with a protected endpoint. 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 ## Set up application and obtain keys

View File

@ -13,7 +13,6 @@ curl --request PATCH \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
--data '{ --data '{
"sessionToken": "yMDi6uVPJAcphbbz0LaxC07ihWkNTe7m0Xqch8SzfM5Cz3HSIQIDZ65x1f5Qal0jxz0MEyo-_zYcUg",
"checks": { "checks": {
"webAuthN": { "webAuthN": {
"credentialAssertionData": {} "credentialAssertionData": {}

View File

@ -140,7 +140,6 @@ curl --request PATCH \
--header 'Accept: application/json' \ --header 'Accept: application/json' \
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
--data '{ --data '{
"sessionToken": "W3mEoesTiYOsiR1LYUCRw3vaEwXKLGDTsqOV_bkOhlah_-ZbuiLgvnzADwe_iYMusbwkMhp7VfMn8j",
"checks": { "checks": {
"totp": { "totp": {
"code": "323764" "code": "323764"
@ -270,7 +269,6 @@ curl --request PATCH \
--header 'Authorization: Bearer '"$TOKEN"'' \ --header 'Authorization: Bearer '"$TOKEN"'' \
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
--data '{ --data '{
"sessionToken": "W3mEoesTiYOsiR1LYUCRw3WaFwXKLGDRsqOV_bkOhlah_-ZpuiLgvnzADwe_iYMusbwkMhp7VfMn8g",
"checks": { "checks": {
"otpSms": { "otpSms": {
"code": "3237642" "code": "3237642"
@ -359,7 +357,6 @@ curl --request PATCH \
--header 'Authorization: Bearer '"$TOKEN"'' \ --header 'Authorization: Bearer '"$TOKEN"'' \
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
--data '{ --data '{
"sessionToken": "W3mEoesTiYOsiR1LYUCRw3WaFwXKLGDRsqOV_bkOhlah_-ZpuiLgvnzADwe_iYMusbwkMhp7VfMn8g",
"checks": { "checks": {
"otpEmail": { "otpEmail": {
"code": "3237642" "code": "3237642"

View File

@ -76,12 +76,14 @@ The application can then request a token calling the /token endpoint of the logi
- [ ] AuthRequest UI locales - [ ] AuthRequest UI locales
- Multifactor - Multifactor
- [x] Passkeys - [x] Passkeys
- [ ] TOTP - [x] TOTP
- [x] OTP via email
- [x] OTP via SMS
- Passwordless - Passwordless
- [x] Passkeys - [x] Passkeys
- Security Prompts - Security Prompts
- [x] Setup Passkey as Passwordless method - [x] Setup Passkey as Passwordless method
- [ ] Setup TOTP as Multifactor - [x] Setup TOTP as Multifactor
- [ ] Password Change - [ ] Password Change
- Login - Login
- [x] Email Password - [x] Email Password
@ -89,7 +91,7 @@ The application can then request a token calling the /token endpoint of the logi
- [x] IDPs - [x] IDPs
- [x] Google - [x] Google
- [ ] GitHub - [ ] GitHub
- [ ] GitLab - [x] GitLab
- [ ] Azure - [ ] Azure
- [ ] Apple - [ ] Apple
- Register - Register
@ -104,8 +106,12 @@ Authenticated users are directly able to self service their account.
- [ ] Change user information - [ ] Change user information
- [ ] Password Change - [ ] Password Change
- [x] Setup Passkey - [x] Setup Passkey
- [ ] Setup Multifactor TOTP - [x] Setup Multifactor
- [ ] Setup Multifactor Passkey (U2F) - [x] Passkeys
- [x] TOTP
- [x] OTP via email
- [x] OTP via SMS
- [x] Setup Multifactor Passkey (U2F)
- [ ] Validate Account (email verification) - [ ] Validate Account (email verification)
### Setup ### Setup

View File

@ -163,7 +163,7 @@ Checkout how to handle [session validation](./session-validation).
Your session already has a username check. Your session already has a username check.
The next step is to check the password. 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 ### Request
@ -174,7 +174,6 @@ curl --request PATCH \
--header 'Authorization: Bearer '"$TOKEN"''\ --header 'Authorization: Bearer '"$TOKEN"''\
--header 'Content-Type: application/json' \ --header 'Content-Type: application/json' \
--data '{ --data '{
"sessionToken": "yMDi6uVPJAcphbbz0LaxC07ihWkNTe7m0Xqch8SzfM5Cz3HSIQIDZ65x1f5Qal0jxz0MEyo-_zYcUg",
"checks": { "checks": {
"password": { "password": {
"password": "Secr3tP4ssw0rd!" "password": "Secr3tP4ssw0rd!"

View 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)

View File

@ -7,6 +7,7 @@ import ThemedImage from "@theme/ThemedImage";
import AuthType from "../../integrate/application/_auth-type.mdx"; import AuthType from "../../integrate/application/_auth-type.mdx";
import ReviewConfig from "../../integrate/application/_review-config.mdx"; import ReviewConfig from "../../integrate/application/_review-config.mdx";
import AppType from "./_application-types.mdx";
## What is an application? ## 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 ## 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, ...) <AppType />
- [**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)
The first three options (Web, Native and User Agent) require user interaction, the fourth option (API) has no direct user-interaction. 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. Depending on the app type, there are small differences in the possible settings.

View File

@ -26,8 +26,7 @@ When you configure your default settings, you can set the following:
- [**Branding**](#branding): Appearance of the login interface. - [**Branding**](#branding): Appearance of the login interface.
- [**Message Texts**](#message-texts): Text and internationalization for emails - [**Message Texts**](#message-texts): Text and internationalization for emails
- [**Login Interface Texts**](#login-interface-texts): Text and internationalization for the login interface - [**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. - [**External Links**](#external-links): Links to your own Terms of Service and Privacy Policy regulations, Help Page, Support email, documentation link...
- [**Privacy Policy**](#privacy-policy-and-tos): Links to your own Terms of Service and Privacy Policy regulations. Link to Help Page.
- [**OIDC Token Lifetimes and Expiration**](#oidc-token-lifetimes-and-expiration): Token lifetime and expiration settings. - [**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. - [**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. 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. 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. On register each user has to accept these policies.
This policy can be also be overriden by your organizations. This policy can be also be overriden by your organizations.
@ -269,8 +269,16 @@ Example:
`https://demo.com/tos-{{.Lang}}` `https://demo.com/tos-{{.Lang}}`
<img <img
src="/docs/img/guides/console/privacypolicy.png" src="/docs/img/guides/console/external_links_1.png"
alt="Privacy Policy" 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" width="600px"
/> />

View File

@ -114,7 +114,7 @@ Those settings are the same as on your instance.
- [**Branding**](./default-settings#branding): Appearance of the login interface. - [**Branding**](./default-settings#branding): Appearance of the login interface.
- [**Message Texts**](./default-settings#message-texts): Text and internationalization for emails - [**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 - [**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. 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.

View File

@ -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) ![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. 1. Click on “Authorizations” on the top menu.

View File

@ -3,7 +3,7 @@ title: Rate Limit Policy
custom_edit_url: null 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). 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: Rate limits are implemented with the following rules:
| Path | Description | Rate Limiting | One Minute Banning | | 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 | | 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 ## Load Testing

View File

@ -6,7 +6,7 @@ sidebar_label: Introduction
You can integrate ZITADEL quickly into your application and be up and running within minutes. 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. 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"; import { Frameworks } from "../../src/components/frameworks";
@ -14,6 +14,12 @@ import { Frameworks } from "../../src/components/frameworks";
<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 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. OIDC is a standard for authentication and most languages and frameworks do provide a OIDC library which can be easily integrated to your application.

View File

@ -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. 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: The default configuration of the database looks like this:
```yaml ```yaml

View 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.

View File

@ -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>New flag to prefill projections during setup instead of after start</td>
<td>Feature description</td> <td>Feature description</td>
<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>
<td>2.44.0, 2.43.6, 2.42.12</td> <td>2.44.0, 2.43.6, 2.42.12</td>
<td>2024-01-25</td> <td>2024-01-25</td>
</tr> </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> </table>
## Subscribe to our Mailing List ## Subscribe to our Mailing List

View File

@ -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.", "This part of our documentation contains ZITADEL specific or general concepts required to understand the system or our guides.",
}, },
items: [ items: [
"concepts/structure/instance", {
"concepts/structure/organizations", type: "category",
"concepts/structure/projects", label: "Resources",
"concepts/structure/applications", collapsed: false,
"concepts/structure/granted_projects", items: [
"concepts/structure/users", {
"concepts/structure/managers", type: "autogenerated",
"concepts/structure/policies", dirName: "concepts/structure",
}
]
},
{
type: "category",
label: "Features",
collapsed: false,
items: [
{ {
type: "autogenerated", type: "autogenerated",
dirName: "concepts/features", dirName: "concepts/features",
}
]
}, },
{ {
type: "autogenerated", type: "autogenerated",

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

BIN
docs/static/img/sdk-examples/console.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

View File

@ -32,6 +32,7 @@ describe('instance notifications', () => {
cy.get('[formcontrolname="replyToAddress"]').clear().type('replyto1@example.com'); cy.get('[formcontrolname="replyToAddress"]').clear().type('replyto1@example.com');
cy.get('[data-e2e="create-button"]').click(); cy.get('[data-e2e="create-button"]').click();
cy.shouldConfirmSuccess(); cy.shouldConfirmSuccess();
cy.get('[data-e2e="close-button"]').click();
cy.get('tr').contains('mailgun'); cy.get('tr').contains('mailgun');
cy.get('tr').contains('smtp.mailgun.org:587'); cy.get('tr').contains('smtp.mailgun.org:587');
cy.get('tr').contains('sender1@example.com'); cy.get('tr').contains('sender1@example.com');
@ -51,6 +52,7 @@ describe('instance notifications', () => {
cy.get('[formcontrolname="senderName"]').clear().type('Change1'); cy.get('[formcontrolname="senderName"]').clear().type('Change1');
cy.get('[data-e2e="create-button"]').click(); cy.get('[data-e2e="create-button"]').click();
cy.shouldConfirmSuccess(); cy.shouldConfirmSuccess();
cy.get('[data-e2e="close-button"]').click();
rowSelector = `tr:contains('mailgun')`; rowSelector = `tr:contains('mailgun')`;
cy.get(rowSelector).contains('mailgun'); cy.get(rowSelector).contains('mailgun');
cy.get(rowSelector).contains('smtp.mailgun.org:587'); 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('[formcontrolname="replyToAddress"]').clear().type('replyto2@example.com');
cy.get('[data-e2e="create-button"]').click(); cy.get('[data-e2e="create-button"]').click();
cy.shouldConfirmSuccess(); cy.shouldConfirmSuccess();
cy.get('[data-e2e="close-button"]').click();
rowSelector = `tr:contains('mailjet')`; rowSelector = `tr:contains('mailjet')`;
cy.get(rowSelector).contains('mailjet'); cy.get(rowSelector).contains('mailjet');
cy.get(rowSelector).contains('in-v3.mailjet.com:587'); cy.get(rowSelector).contains('in-v3.mailjet.com:587');
@ -130,6 +133,51 @@ describe('instance notifications', () => {
rowSelector = `tr:contains('mailgun')`; rowSelector = `tr:contains('mailgun')`;
cy.get(rowSelector).should('not.exist'); 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', () => { describe('sms settings', () => {

View File

@ -26,8 +26,9 @@ describe('organizations', () => {
it('should delete an org', () => { it('should delete an org', () => {
cy.visit(orgsPath); cy.visit(orgsPath);
cy.contains('tr', newOrg).click(); cy.contains('tr', newOrg).click();
cy.wait(3000);
cy.get('[data-e2e="actions"]').click(); 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-input"]').focus().clear().type(newOrg);
cy.get('[data-e2e="confirm-dialog-button"]').click(); cy.get('[data-e2e="confirm-dialog-button"]').click();
cy.shouldConfirmSuccess(); cy.shouldConfirmSuccess();

View 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);
});
});

View 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
View File

@ -49,7 +49,7 @@ require (
github.com/nicksnyder/go-i18n/v2 v2.4.0 github.com/nicksnyder/go-i18n/v2 v2.4.0
github.com/pquerna/otp v1.4.0 github.com/pquerna/otp v1.4.0
github.com/rakyll/statik v0.1.7 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/santhosh-tekuri/jsonschema/v5 v5.3.1
github.com/sony/sonyflake v1.2.0 github.com/sony/sonyflake v1.2.0
github.com/spf13/cobra v1.8.0 github.com/spf13/cobra v1.8.0
@ -58,20 +58,20 @@ require (
github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203 github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203
github.com/ttacon/libphonenumber v1.2.1 github.com/ttacon/libphonenumber v1.2.1
github.com/zitadel/logging v0.6.0 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/passwap v0.5.0
github.com/zitadel/saml v0.1.3 github.com/zitadel/saml v0.1.3
github.com/zitadel/schema v1.3.0 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/google.golang.org/grpc/otelgrpc v0.51.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0
go.opentelemetry.io/otel v1.25.0 go.opentelemetry.io/otel v1.26.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0
go.opentelemetry.io/otel/exporters/prometheus v0.47.0 go.opentelemetry.io/otel/exporters/prometheus v0.48.0
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0 go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0
go.opentelemetry.io/otel/metric v1.25.0 go.opentelemetry.io/otel/metric v1.26.0
go.opentelemetry.io/otel/sdk v1.25.0 go.opentelemetry.io/otel/sdk v1.26.0
go.opentelemetry.io/otel/sdk/metric v1.25.0 go.opentelemetry.io/otel/sdk/metric v1.26.0
go.opentelemetry.io/otel/trace v1.25.0 go.opentelemetry.io/otel/trace v1.26.0
go.uber.org/mock v0.4.0 go.uber.org/mock v0.4.0
golang.org/x/crypto v0.22.0 golang.org/x/crypto v0.22.0
golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8
@ -80,9 +80,9 @@ require (
golang.org/x/sync v0.7.0 golang.org/x/sync v0.7.0
golang.org/x/text v0.14.0 golang.org/x/text v0.14.0
google.golang.org/api v0.172.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/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 sigs.k8s.io/yaml v1.4.0
) )
@ -116,7 +116,7 @@ require (
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/time v0.5.0 // indirect golang.org/x/time v0.5.0 // indirect
google.golang.org/genproto v0.0.0-20240412170617-26222e5d3d56 // 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 ( require (
@ -183,8 +183,8 @@ require (
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.19.0 github.com/prometheus/client_golang v1.19.0
github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.52.3 // indirect github.com/prometheus/common v0.53.0 // indirect
github.com/prometheus/procfs v0.13.0 // indirect github.com/prometheus/procfs v0.14.0 // indirect
github.com/rs/xid v1.5.0 // indirect github.com/rs/xid v1.5.0 // indirect
github.com/russellhaering/goxmldsig v1.4.0 // indirect github.com/russellhaering/goxmldsig v1.4.0 // indirect
github.com/sirupsen/logrus v1.9.3 github.com/sirupsen/logrus v1.9.3
@ -196,7 +196,7 @@ require (
github.com/x448/float16 v0.8.4 // indirect github.com/x448/float16 v0.8.4 // indirect
github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
go.opencensus.io v0.24.0 // 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 go.opentelemetry.io/proto/otlp v1.2.0 // indirect
golang.org/x/sys v0.19.0 golang.org/x/sys v0.19.0
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect

72
go.sum
View File

@ -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.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.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.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.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE=
github.com/prometheus/common v0.52.3/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= 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-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.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.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= 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.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.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= github.com/prometheus/procfs v0.14.0 h1:Lw4VdGGoKEZilJsayHf0B+9YgLGREba2C6xr+Fdfq6s=
github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= 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 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ=
github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= 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= 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 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= 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.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po=
github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= 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 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/russellhaering/goxmldsig v1.4.0 h1:8UcDh/xGyQiyrW+Fq5t8f+l2DLB1+zlhYzkPUJ7Qhys= 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/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 h1:t5Nnt//r+m2ZhhoTmoPX+c96pbMarqJvW1Vq6xFTank=
github.com/zitadel/logging v0.6.0/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow= 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.23.2 h1:vRUM6SKudr6WR/lqxue4cvCbgR+IdEJGVBklucKKXgk=
github.com/zitadel/oidc/v3 v3.21.0/go.mod h1:3uCwJc680oWoTBdzIppMZQS+VNxq+sVcwgodbreuatM= 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 h1:kFMoRyo0GnxtOz7j9+r/CsRwSCjHGRaAKoUe69NwPvs=
github.com/zitadel/passwap v0.5.0/go.mod h1:uqY7D3jqdTFcKsW0Q3Pcv5qDMmSHpVTzUZewUKC1KZA= github.com/zitadel/passwap v0.5.0/go.mod h1:uqY7D3jqdTFcKsW0Q3Pcv5qDMmSHpVTzUZewUKC1KZA=
github.com/zitadel/saml v0.1.3 h1:LI4DOCVyyU1qKPkzs3vrGcA5J3H4pH3+CL9zr9ShkpM= 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.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= 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.51.0 h1:A3SayB3rNyt+1S6qpI9mHPkeHTZbD7XILEqWnYZb2l0=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.50.0/go.mod h1:BMn8NB1vsxTljvuorms2hyOs8IBuuBEq0pl7ltOfy30= 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.50.0 h1:cEPbyTSEHlQR89XVlyo78gqluF8Y3oMeBkXGWzQsfXY= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0 h1:Xs2Ncz0gNihqu9iosIZ5SkBbWo5T8JhhLJFMQL1qmLI=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0/go.mod h1:DKdbWcT4GH1D0Y3Sqt/PFXt2naRKDWtU+eE6oLdFNA8= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.51.0/go.mod h1:vy+2G/6NvVMpwGX/NyLqcC41fxepnuKHk16E6IZUcJc=
go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs=
go.opentelemetry.io/otel v1.25.0/go.mod h1:Wa2ds5NOXEMkCmUou1WA7ZBfLTHWIsp034OVD7AO+Vg= go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0 h1:dT33yIHtmsqpixFsSQPwNeY5drM9wTcoL8h0FWF4oGM= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 h1:1u/AyyOqAWzy+SkPxDpahCNZParHV8Vid1RnI2clyDE=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.25.0/go.mod h1:h95q0LBGh7hlAC08X2DhSeyIG02YQ0UyioTCVAqRPmc= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0/go.mod h1:z46paqbJ9l7c9fIPCXTqTGwhQZ5XoTIsfeFYWboizjs=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.25.0 h1:vOL89uRfOCCNIjkisd0r7SEdJF3ZJFyCNY34fdZs8eU= 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.25.0/go.mod h1:8GlBGcDk8KKi7n+2S4BT/CPZQYH3erLu0/k64r1MYgo= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0/go.mod h1:wnJIG4fOqyynOnnQF/eQb4/16VlX2EJAHhHgqIqWfAo=
go.opentelemetry.io/otel/exporters/prometheus v0.47.0 h1:OL6yk1Z/pEGdDnrBbxSsH+t4FY1zXfBRGd7bjwhlMLU= go.opentelemetry.io/otel/exporters/prometheus v0.48.0 h1:sBQe3VNGUjY9IKWQC6z2lNqa5iGbDSxhs60ABwK4y0s=
go.opentelemetry.io/otel/exporters/prometheus v0.47.0/go.mod h1:xF3N4OSICZDVbbYZydz9MHFro1RjmkPUKEvar2utG+Q= go.opentelemetry.io/otel/exporters/prometheus v0.48.0/go.mod h1:DtrbMzoZWwQHyrQmCfLam5DZbnmorsGbOtTbYHycU5o=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0 h1:0vZZdECYzhTt9MKQZ5qQ0V+J3MFu4MQaQ3COfugF+FQ= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0 h1:0W5o9SzoR15ocYHEQfvfipzcNog1lBxOLfnex91Hk6s=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.25.0/go.mod h1:e7iXx3HjaSSBXfy9ykVUlupS2Vp7LBIBuT21ousM2Hk= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.26.0/go.mod h1:zVZ8nz+VSggWmnh6tTsJqXQ7rU4xLwRtna1M4x5jq58=
go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= go.opentelemetry.io/otel/metric v1.26.0 h1:7S39CLuY5Jgg9CrnA9HHiEjGMF/X2VHvoXGgSllRz30=
go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= go.opentelemetry.io/otel/metric v1.26.0/go.mod h1:SY+rHOI4cEawI9a7N1A4nIg/nTQXe1ccCNWYOJUrpX4=
go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo= go.opentelemetry.io/otel/sdk v1.26.0 h1:Y7bumHf5tAiDlRYFmGqetNcLaVUZmh4iYfmGxtmz7F8=
go.opentelemetry.io/otel/sdk v1.25.0/go.mod h1:oFgzCM2zdsxKzz6zwpTZYLLQsFwc+K0daArPdIhuxkw= go.opentelemetry.io/otel/sdk v1.26.0/go.mod h1:0p8MXpqLeJ0pzcszQQN4F0S5FVjBLgypeGSngLsmirs=
go.opentelemetry.io/otel/sdk/metric v1.25.0 h1:7CiHOy08LbrxMAp4vWpbiPcklunUshVpAvGBrdDRlGw= go.opentelemetry.io/otel/sdk/metric v1.26.0 h1:cWSks5tfriHPdWFnl+qpX3P681aAYqlZHcAyHw5aU9Y=
go.opentelemetry.io/otel/sdk/metric v1.25.0/go.mod h1:LzwoKptdbBBdYfvtGCzGwk6GWMA3aUzBOwtQpR6Nz7o= go.opentelemetry.io/otel/sdk/metric v1.26.0/go.mod h1:ClMFFknnThJCksebJwz7KIyEDHO+nTB6gK8obLy8RyE=
go.opentelemetry.io/otel/trace v1.25.0 h1:tqukZGLwQYRIFtSQM2u2+yfMVTgGVeqRLPUYx1Dq6RM= go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA=
go.opentelemetry.io/otel/trace v1.25.0/go.mod h1:hCCs70XM/ljO+BeQkyFnbK28SBIJ/Emuha+ccrCRT7I= 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 h1:pVeZGk7nXDC9O2hncA6nHldxEjm6LByfA2aN8IOkz94=
go.opentelemetry.io/proto/otlp v1.2.0/go.mod h1:gGpR8txAl5M03pDhMC79G6SdqNV26naRm/KDsgaHD8A= 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= 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-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 h1:LlcUFJ4BLmJVS4Kly+WCK7LQqcevmycHj88EPgyhNx8=
google.golang.org/genproto v0.0.0-20240412170617-26222e5d3d56/go.mod h1:n1CaIKYMIlxFt1zJE/1kU40YpSL0drGMbl0Idum1VSs= 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-20240429193739-8cf5692501f6 h1:DTJM0R8LECCgFeUwApvcEJHz85HLagW8uRENYxHh1ww=
google.golang.org/genproto/googleapis/api v0.0.0-20240412170617-26222e5d3d56/go.mod h1:wTHjrkbcS8AoQbb/0v9bFIPItZQPAsyVfgG9YPUhjAM= 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-20240412170617-26222e5d3d56 h1:zviK8GX4VlMstrK3JkexM5UHjH1VOkRebH9y3jhSBGk= google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 h1:DujSIu+2tC9Ht0aPNA7jgj23Iq8Ewi5sgkQ++wdvonE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240412170617-26222e5d3d56/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= 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.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.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= 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.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.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 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.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 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/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 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@ -196,6 +196,33 @@ func TestServer_SetExecution_Request_Include(t *testing.T) {
executionTargetsSingleTarget(targetResp.GetId()), 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 { tests := []struct {
name string name string
ctx context.Context ctx context.Context
@ -203,6 +230,15 @@ func TestServer_SetExecution_Request_Include(t *testing.T) {
want *action.SetExecutionResponse want *action.SetExecutionResponse
wantErr bool wantErr bool
}{ }{
{
name: "method, circular error",
ctx: CTX,
req: &action.SetExecutionRequest{
Condition: circularExecutionService,
Targets: executionTargetsSingleInclude(circularExecutionMethod),
},
wantErr: true,
},
{ {
name: "method, ok", name: "method, ok",
ctx: CTX, 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 { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {

View File

@ -538,6 +538,9 @@ func (s *Server) getPrivacyPolicy(ctx context.Context, orgID string) (_ *managem
PrivacyLink: queriedPrivacy.PrivacyLink, PrivacyLink: queriedPrivacy.PrivacyLink,
HelpLink: queriedPrivacy.HelpLink, HelpLink: queriedPrivacy.HelpLink,
SupportEmail: string(queriedPrivacy.SupportEmail), SupportEmail: string(queriedPrivacy.SupportEmail),
DocsLink: queriedPrivacy.DocsLink,
CustomLink: queriedPrivacy.CustomLink,
CustomLinkText: queriedPrivacy.CustomLinkText,
}, nil }, nil
} }
return nil, nil return nil, nil

View File

@ -4,7 +4,6 @@ import (
"context" "context"
"github.com/muhlemmer/gu" "github.com/muhlemmer/gu"
"github.com/zitadel/logging" "github.com/zitadel/logging"
object_pb "github.com/zitadel/zitadel/internal/api/grpc/object" object_pb "github.com/zitadel/zitadel/internal/api/grpc/object"

View File

@ -172,6 +172,7 @@ func SMTPConfigToPb(smtp *query.SMTPConfig) *settings_pb.SMTPConfig {
User: smtp.User, User: smtp.User,
Details: obj_grpc.ToViewDetailsPb(smtp.Sequence, smtp.CreationDate, smtp.ChangeDate, smtp.ResourceOwner), Details: obj_grpc.ToViewDetailsPb(smtp.Sequence, smtp.CreationDate, smtp.ChangeDate, smtp.ResourceOwner),
Id: smtp.ID, Id: smtp.ID,
State: settings_pb.SMTPConfigState(smtp.State),
} }
return mapped return mapped
} }

View File

@ -2,6 +2,7 @@ package admin
import ( import (
"github.com/crewjam/saml" "github.com/crewjam/saml"
"github.com/muhlemmer/gu"
idp_grpc "github.com/zitadel/zitadel/internal/api/grpc/idp" idp_grpc "github.com/zitadel/zitadel/internal/api/grpc/idp"
"github.com/zitadel/zitadel/internal/api/grpc/object" "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 { 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{ return command.SAMLProvider{
Name: req.Name, Name: req.Name,
Metadata: req.GetMetadataXml(), Metadata: req.GetMetadataXml(),
MetadataURL: req.GetMetadataUrl(), MetadataURL: req.GetMetadataUrl(),
Binding: bindingToCommand(req.Binding), Binding: bindingToCommand(req.Binding),
WithSignedRequest: req.WithSignedRequest, WithSignedRequest: req.WithSignedRequest,
NameIDFormat: nameIDFormat,
TransientMappingAttributeName: req.GetTransientMappingAttributeName(),
IDPOptions: idp_grpc.OptionsToCommand(req.ProviderOptions), IDPOptions: idp_grpc.OptionsToCommand(req.ProviderOptions),
} }
} }
func updateSAMLProviderToCommand(req *admin_pb.UpdateSAMLProviderRequest) command.SAMLProvider { 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{ return command.SAMLProvider{
Name: req.Name, Name: req.Name,
Metadata: req.GetMetadataXml(), Metadata: req.GetMetadataXml(),
MetadataURL: req.GetMetadataUrl(), MetadataURL: req.GetMetadataUrl(),
Binding: bindingToCommand(req.Binding), Binding: bindingToCommand(req.Binding),
WithSignedRequest: req.WithSignedRequest, WithSignedRequest: req.WithSignedRequest,
NameIDFormat: nameIDFormat,
TransientMappingAttributeName: req.GetTransientMappingAttributeName(),
IDPOptions: idp_grpc.OptionsToCommand(req.ProviderOptions), IDPOptions: idp_grpc.OptionsToCommand(req.ProviderOptions),
} }
} }

View File

@ -5,7 +5,6 @@ import (
org_grpc "github.com/zitadel/zitadel/internal/api/grpc/org" org_grpc "github.com/zitadel/zitadel/internal/api/grpc/org"
"github.com/zitadel/zitadel/internal/query" "github.com/zitadel/zitadel/internal/query"
"github.com/zitadel/zitadel/pkg/grpc/admin" "github.com/zitadel/zitadel/pkg/grpc/admin"
"github.com/zitadel/zitadel/pkg/grpc/org"
) )
func listOrgRequestToModel(req *admin.ListOrgsRequest) (*query.OrgSearchQueries, error) { func listOrgRequestToModel(req *admin.ListOrgsRequest) (*query.OrgSearchQueries, error) {
@ -18,18 +17,9 @@ func listOrgRequestToModel(req *admin.ListOrgsRequest) (*query.OrgSearchQueries,
SearchRequest: query.SearchRequest{ SearchRequest: query.SearchRequest{
Offset: offset, Offset: offset,
Limit: limit, Limit: limit,
SortingColumn: fieldNameToOrgColumn(req.SortingColumn), SortingColumn: org_grpc.FieldNameToOrgColumn(req.SortingColumn),
Asc: asc, Asc: asc,
}, },
Queries: queries, Queries: queries,
}, nil }, nil
} }
func fieldNameToOrgColumn(fieldName org.OrgFieldName) query.Column {
switch fieldName {
case org.OrgFieldName_ORG_FIELD_NAME_NAME:
return query.OrgColumnName
default:
return query.Column{}
}
}

View File

@ -11,5 +11,8 @@ func UpdatePrivacyPolicyToDomain(req *admin_pb.UpdatePrivacyPolicyRequest) *doma
PrivacyLink: req.PrivacyLink, PrivacyLink: req.PrivacyLink,
HelpLink: req.HelpLink, HelpLink: req.HelpLink,
SupportEmail: domain.EmailAddress(req.SupportEmail), SupportEmail: domain.EmailAddress(req.SupportEmail),
DocsLink: req.DocsLink,
CustomLink: req.CustomLink,
CustomLinkText: req.CustomLinkText,
} }
} }

View File

@ -269,6 +269,7 @@ func ListMyProjectOrgsRequestToQuery(req *auth_pb.ListMyProjectOrgsRequest) (*qu
Offset: offset, Offset: offset,
Limit: limit, Limit: limit,
Asc: asc, Asc: asc,
SortingColumn: org.FieldNameToOrgColumn(req.SortingColumn),
}, },
Queries: queries, Queries: queries,
}, nil }, nil

View File

@ -16,6 +16,7 @@ func systemFeaturesToCommand(req *feature_pb.SetSystemFeaturesRequest) *command.
UserSchema: req.UserSchema, UserSchema: req.UserSchema,
Actions: req.Actions, Actions: req.Actions,
TokenExchange: req.OidcTokenExchange, TokenExchange: req.OidcTokenExchange,
ImprovedPerformance: improvedPerformanceListToDomain(req.ImprovedPerformance),
} }
} }
@ -28,6 +29,7 @@ func systemFeaturesToPb(f *query.SystemFeatures) *feature_pb.GetSystemFeaturesRe
UserSchema: featureSourceToFlagPb(&f.UserSchema), UserSchema: featureSourceToFlagPb(&f.UserSchema),
OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange), OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange),
Actions: featureSourceToFlagPb(&f.Actions), Actions: featureSourceToFlagPb(&f.Actions),
ImprovedPerformance: featureSourceToImprovedPerformanceFlagPb(&f.ImprovedPerformance),
} }
} }
@ -39,6 +41,7 @@ func instanceFeaturesToCommand(req *feature_pb.SetInstanceFeaturesRequest) *comm
UserSchema: req.UserSchema, UserSchema: req.UserSchema,
TokenExchange: req.OidcTokenExchange, TokenExchange: req.OidcTokenExchange,
Actions: req.Actions, Actions: req.Actions,
ImprovedPerformance: improvedPerformanceListToDomain(req.ImprovedPerformance),
} }
} }
@ -51,6 +54,14 @@ func instanceFeaturesToPb(f *query.InstanceFeatures) *feature_pb.GetInstanceFeat
UserSchema: featureSourceToFlagPb(&f.UserSchema), UserSchema: featureSourceToFlagPb(&f.UserSchema),
OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange), OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange),
Actions: featureSourceToFlagPb(&f.Actions), 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) 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