Merge remote-tracking branch 'origin/main' into next

This commit is contained in:
Stefan Benz 2024-10-11 11:16:54 +02:00
commit 55b1188dd0
No known key found for this signature in database
GPG Key ID: 071AA751ED4F9D31
147 changed files with 8094 additions and 1896 deletions

View File

@ -2,6 +2,7 @@ name: Bug Report
description: "Create a bug report to help us improve ZITADEL." description: "Create a bug report to help us improve ZITADEL."
title: "[Bug]: " title: "[Bug]: "
labels: ["bug"] labels: ["bug"]
type: Bug
body: body:
- type: markdown - type: markdown
attributes: attributes:

View File

@ -25,15 +25,11 @@ type NewEventsTable struct {
} }
func (mig *NewEventsTable) Execute(ctx context.Context, _ eventstore.Event) error { func (mig *NewEventsTable) Execute(ctx context.Context, _ eventstore.Event) error {
migrations, err := newEventsTable.ReadDir("14/" + mig.dbClient.Type())
if err != nil {
return err
}
// if events already exists events2 is created during a setup job // if events already exists events2 is created during a setup job
var count int var count int
err = mig.dbClient.QueryRow( err := mig.dbClient.QueryRowContext(ctx,
func(row *sql.Row) error { func(row *sql.Row) error {
if err = row.Scan(&count); err != nil { if err := row.Scan(&count); err != nil {
return err return err
} }
return row.Err() return row.Err()
@ -43,16 +39,15 @@ func (mig *NewEventsTable) Execute(ctx context.Context, _ eventstore.Event) erro
if err != nil || count == 1 { if err != nil || count == 1 {
return err return err
} }
for _, migration := range migrations {
stmt, err := readStmt(newEventsTable, "14", mig.dbClient.Type(), migration.Name())
if err != nil {
return err
}
stmt = strings.ReplaceAll(stmt, "{{.username}}", mig.dbClient.Username())
logging.WithFields("migration", mig.String(), "file", migration.Name()).Debug("execute statement") statements, err := readStatements(newEventsTable, "14", mig.dbClient.Type())
if err != nil {
_, err = mig.dbClient.ExecContext(ctx, stmt) return err
}
for _, stmt := range statements {
stmt.query = strings.ReplaceAll(stmt.query, "{{.username}}", mig.dbClient.Username())
logging.WithFields("file", stmt.file, "migration", mig.String()).Info("execute statement")
_, err = mig.dbClient.ExecContext(ctx, stmt.query)
if err != nil { if err != nil {
return err return err
} }

View File

@ -21,19 +21,13 @@ type CurrentProjectionState struct {
} }
func (mig *CurrentProjectionState) Execute(ctx context.Context, _ eventstore.Event) error { func (mig *CurrentProjectionState) Execute(ctx context.Context, _ eventstore.Event) error {
migrations, err := currentProjectionState.ReadDir("15/" + mig.dbClient.Type()) statements, err := readStatements(currentProjectionState, "15", mig.dbClient.Type())
if err != nil { if err != nil {
return err return err
} }
for _, migration := range migrations { for _, stmt := range statements {
stmt, err := readStmt(currentProjectionState, "15", mig.dbClient.Type(), migration.Name()) logging.WithFields("file", stmt.file, "migration", mig.String()).Info("execute statement")
if err != nil { _, err = mig.dbClient.ExecContext(ctx, stmt.query)
return err
}
logging.WithFields("file", migration.Name(), "migration", mig.String()).Info("execute statement")
_, err = mig.dbClient.ExecContext(ctx, stmt)
if err != nil { if err != nil {
return err return err
} }

37
cmd/setup/34.go Normal file
View File

@ -0,0 +1,37 @@
package setup
import (
"context"
_ "embed"
"fmt"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/eventstore"
)
var (
//go:embed 34/cockroach/34_cache_schema.sql
addCacheSchemaCockroach string
//go:embed 34/postgres/34_cache_schema.sql
addCacheSchemaPostgres string
)
type AddCacheSchema struct {
dbClient *database.DB
}
func (mig *AddCacheSchema) Execute(ctx context.Context, _ eventstore.Event) (err error) {
switch mig.dbClient.Type() {
case "cockroach":
_, err = mig.dbClient.ExecContext(ctx, addCacheSchemaCockroach)
case "postgres":
_, err = mig.dbClient.ExecContext(ctx, addCacheSchemaPostgres)
default:
err = fmt.Errorf("add cache schema: unsupported db type %q", mig.dbClient.Type())
}
return err
}
func (mig *AddCacheSchema) String() string {
return "34_add_cache_schema"
}

View File

@ -0,0 +1,27 @@
create schema if not exists cache;
create table if not exists cache.objects (
cache_name varchar not null,
id uuid not null default gen_random_uuid(),
created_at timestamptz not null default now(),
last_used_at timestamptz not null default now(),
payload jsonb not null,
primary key(cache_name, id)
);
create table if not exists cache.string_keys(
cache_name varchar not null check (cache_name <> ''),
index_id integer not null check (index_id > 0),
index_key varchar not null check (index_key <> ''),
object_id uuid not null,
primary key (cache_name, index_id, index_key),
constraint fk_object
foreign key(cache_name, object_id)
references cache.objects(cache_name, id)
on delete cascade
);
create index if not exists string_keys_object_id_idx
on cache.string_keys (cache_name, object_id); -- for delete cascade

View File

@ -0,0 +1,29 @@
create schema if not exists cache;
create unlogged table if not exists cache.objects (
cache_name varchar not null,
id uuid not null default gen_random_uuid(),
created_at timestamptz not null default now(),
last_used_at timestamptz not null default now(),
payload jsonb not null,
primary key(cache_name, id)
)
partition by list (cache_name);
create unlogged table if not exists cache.string_keys(
cache_name varchar not null check (cache_name <> ''),
index_id integer not null check (index_id > 0),
index_key varchar not null check (index_key <> ''),
object_id uuid not null,
primary key (cache_name, index_id, index_key),
constraint fk_object
foreign key(cache_name, object_id)
references cache.objects(cache_name, id)
on delete cascade
)
partition by list (cache_name);
create index if not exists string_keys_object_id_idx
on cache.string_keys (cache_name, object_id); -- for delete cascade

39
cmd/setup/35.go Normal file
View File

@ -0,0 +1,39 @@
package setup
import (
"context"
"embed"
"fmt"
"github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/eventstore"
)
var (
//go:embed 35/*.sql
addPositionToEsWmIndex embed.FS
)
type AddPositionToIndexEsWm struct {
dbClient *database.DB
}
func (mig *AddPositionToIndexEsWm) Execute(ctx context.Context, _ eventstore.Event) error {
statements, err := readStatements(addPositionToEsWmIndex, "35", "")
if err != nil {
return err
}
for _, stmt := range statements {
logging.WithFields("file", stmt.file, "migration", mig.String()).Info("execute statement")
if _, err := mig.dbClient.ExecContext(ctx, stmt.query); err != nil {
return fmt.Errorf("%s %s: %w", mig.String(), stmt.file, err)
}
}
return nil
}
func (mig *AddPositionToIndexEsWm) String() string {
return "35_add_position_to_index_es_wm"
}

View File

@ -0,0 +1,2 @@
CREATE INDEX CONCURRENTLY IF NOT EXISTS es_wm_temp
ON eventstore.events2 (instance_id, aggregate_id, aggregate_type, event_type, "position");

View File

@ -0,0 +1 @@
DROP INDEX IF EXISTS eventstore.es_wm;

View File

@ -0,0 +1 @@
ALTER INDEX eventstore.es_wm_temp RENAME TO es_wm;

View File

@ -90,36 +90,38 @@ func MustNewConfig(v *viper.Viper) *Config {
} }
type Steps struct { type Steps struct {
s1ProjectionTable *ProjectionTable s1ProjectionTable *ProjectionTable
s2AssetsTable *AssetTable s2AssetsTable *AssetTable
FirstInstance *FirstInstance FirstInstance *FirstInstance
s5LastFailed *LastFailed s5LastFailed *LastFailed
s6OwnerRemoveColumns *OwnerRemoveColumns s6OwnerRemoveColumns *OwnerRemoveColumns
s7LogstoreTables *LogstoreTables s7LogstoreTables *LogstoreTables
s8AuthTokens *AuthTokenIndexes s8AuthTokens *AuthTokenIndexes
CorrectCreationDate *CorrectCreationDate CorrectCreationDate *CorrectCreationDate
s12AddOTPColumns *AddOTPColumns s12AddOTPColumns *AddOTPColumns
s13FixQuotaProjection *FixQuotaConstraints s13FixQuotaProjection *FixQuotaConstraints
s14NewEventsTable *NewEventsTable s14NewEventsTable *NewEventsTable
s15CurrentStates *CurrentProjectionState s15CurrentStates *CurrentProjectionState
s16UniqueConstraintsLower *UniqueConstraintToLower s16UniqueConstraintsLower *UniqueConstraintToLower
s17AddOffsetToUniqueConstraints *AddOffsetToCurrentStates s17AddOffsetToUniqueConstraints *AddOffsetToCurrentStates
s18AddLowerFieldsToLoginNames *AddLowerFieldsToLoginNames s18AddLowerFieldsToLoginNames *AddLowerFieldsToLoginNames
s19AddCurrentStatesIndex *AddCurrentSequencesIndex s19AddCurrentStatesIndex *AddCurrentSequencesIndex
s20AddByUserSessionIndex *AddByUserIndexToSession s20AddByUserSessionIndex *AddByUserIndexToSession
s21AddBlockFieldToLimits *AddBlockFieldToLimits s21AddBlockFieldToLimits *AddBlockFieldToLimits
s22ActiveInstancesIndex *ActiveInstanceEvents s22ActiveInstancesIndex *ActiveInstanceEvents
s23CorrectGlobalUniqueConstraints *CorrectGlobalUniqueConstraints s23CorrectGlobalUniqueConstraints *CorrectGlobalUniqueConstraints
s24AddActorToAuthTokens *AddActorToAuthTokens s24AddActorToAuthTokens *AddActorToAuthTokens
s25User11AddLowerFieldsToVerifiedEmail *User11AddLowerFieldsToVerifiedEmail s25User11AddLowerFieldsToVerifiedEmail *User11AddLowerFieldsToVerifiedEmail
s26AuthUsers3 *AuthUsers3 s26AuthUsers3 *AuthUsers3
s27IDPTemplate6SAMLNameIDFormat *IDPTemplate6SAMLNameIDFormat s27IDPTemplate6SAMLNameIDFormat *IDPTemplate6SAMLNameIDFormat
s28AddFieldTable *AddFieldTable s28AddFieldTable *AddFieldTable
s29FillFieldsForProjectGrant *FillFieldsForProjectGrant s29FillFieldsForProjectGrant *FillFieldsForProjectGrant
s30FillFieldsForOrgDomainVerified *FillFieldsForOrgDomainVerified s30FillFieldsForOrgDomainVerified *FillFieldsForOrgDomainVerified
s31AddAggregateIndexToFields *AddAggregateIndexToFields s31AddAggregateIndexToFields *AddAggregateIndexToFields
s32AddAuthSessionID *AddAuthSessionID s32AddAuthSessionID *AddAuthSessionID
s33SMSConfigs3TwilioAddVerifyServiceSid *SMSConfigs3TwilioAddVerifyServiceSid s33SMSConfigs3TwilioAddVerifyServiceSid *SMSConfigs3TwilioAddVerifyServiceSid
s34AddCacheSchema *AddCacheSchema
s35AddPositionToIndexEsWm *AddPositionToIndexEsWm
} }
func MustNewSteps(v *viper.Viper) *Steps { func MustNewSteps(v *viper.Viper) *Steps {

View File

@ -5,6 +5,7 @@ import (
"embed" "embed"
_ "embed" _ "embed"
"net/http" "net/http"
"path/filepath"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
@ -162,6 +163,8 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
steps.s31AddAggregateIndexToFields = &AddAggregateIndexToFields{dbClient: esPusherDBClient} steps.s31AddAggregateIndexToFields = &AddAggregateIndexToFields{dbClient: esPusherDBClient}
steps.s32AddAuthSessionID = &AddAuthSessionID{dbClient: esPusherDBClient} steps.s32AddAuthSessionID = &AddAuthSessionID{dbClient: esPusherDBClient}
steps.s33SMSConfigs3TwilioAddVerifyServiceSid = &SMSConfigs3TwilioAddVerifyServiceSid{dbClient: esPusherDBClient} steps.s33SMSConfigs3TwilioAddVerifyServiceSid = &SMSConfigs3TwilioAddVerifyServiceSid{dbClient: esPusherDBClient}
steps.s34AddCacheSchema = &AddCacheSchema{dbClient: queryDBClient}
steps.s35AddPositionToIndexEsWm = &AddPositionToIndexEsWm{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")
@ -204,6 +207,8 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
steps.s26AuthUsers3, steps.s26AuthUsers3,
steps.s29FillFieldsForProjectGrant, steps.s29FillFieldsForProjectGrant,
steps.s30FillFieldsForOrgDomainVerified, steps.s30FillFieldsForOrgDomainVerified,
steps.s34AddCacheSchema,
steps.s35AddPositionToIndexEsWm,
} { } {
mustExecuteMigration(ctx, eventstoreClient, step, "migration failed") mustExecuteMigration(ctx, eventstoreClient, step, "migration failed")
} }
@ -243,11 +248,41 @@ func mustExecuteMigration(ctx context.Context, eventstoreClient *eventstore.Even
logging.WithFields("name", step.String()).OnError(err).Fatal(errorMsg) logging.WithFields("name", step.String()).OnError(err).Fatal(errorMsg)
} }
// readStmt reads a single file from the embedded FS,
// under the folder/typ/filename path.
// Typ describes the database dialect and may be omitted if no
// dialect specific migration is specified.
func readStmt(fs embed.FS, folder, typ, filename string) (string, error) { func readStmt(fs embed.FS, folder, typ, filename string) (string, error) {
stmt, err := fs.ReadFile(folder + "/" + typ + "/" + filename) stmt, err := fs.ReadFile(filepath.Join(folder, typ, filename))
return string(stmt), err return string(stmt), err
} }
type statement struct {
file string
query string
}
// readStatements reads all files from the embedded FS,
// under the folder/type path.
// Typ describes the database dialect and may be omitted if no
// dialect specific migration is specified.
func readStatements(fs embed.FS, folder, typ string) ([]statement, error) {
basePath := filepath.Join(folder, typ)
dir, err := fs.ReadDir(basePath)
if err != nil {
return nil, err
}
statements := make([]statement, len(dir))
for i, file := range dir {
statements[i].file = file.Name()
statements[i].query, err = readStmt(fs, folder, typ, file.Name())
if err != nil {
return nil, err
}
}
return statements, nil
}
func initProjections( func initProjections(
ctx context.Context, ctx context.Context,
eventstoreClient *eventstore.Eventstore, eventstoreClient *eventstore.Eventstore,

View File

@ -87,6 +87,6 @@
"prettier": "^3.1.1", "prettier": "^3.1.1",
"prettier-plugin-organize-imports": "^4.0.0", "prettier-plugin-organize-imports": "^4.0.0",
"protractor": "~7.0.0", "protractor": "~7.0.0",
"typescript": "^5.1.6" "typescript": "5.1"
} }
} }

View File

@ -16,6 +16,7 @@ import localeZh from '@angular/common/locales/zh';
import localeRu from '@angular/common/locales/ru'; import localeRu from '@angular/common/locales/ru';
import localeNl from '@angular/common/locales/nl'; import localeNl from '@angular/common/locales/nl';
import localeSv from '@angular/common/locales/sv'; import localeSv from '@angular/common/locales/sv';
import localeHu from '@angular/common/locales/hu';
import { APP_INITIALIZER, NgModule } from '@angular/core'; import { APP_INITIALIZER, NgModule } from '@angular/core';
import { MatNativeDateModule } from '@angular/material/core'; import { MatNativeDateModule } from '@angular/material/core';
import { MatDialogModule } from '@angular/material/dialog'; import { MatDialogModule } from '@angular/material/dialog';
@ -105,6 +106,8 @@ registerLocaleData(localeNl);
i18nIsoCountries.registerLocale(require('i18n-iso-countries/langs/nl.json')); i18nIsoCountries.registerLocale(require('i18n-iso-countries/langs/nl.json'));
registerLocaleData(localeSv); registerLocaleData(localeSv);
i18nIsoCountries.registerLocale(require('i18n-iso-countries/langs/sv.json')); i18nIsoCountries.registerLocale(require('i18n-iso-countries/langs/sv.json'));
registerLocaleData(localeHu);
i18nIsoCountries.registerLocale(require('i18n-iso-countries/langs/hu.json'));
export class WebpackTranslateLoader implements TranslateLoader { export class WebpackTranslateLoader implements TranslateLoader {
getTranslation(lang: string): Observable<any> { getTranslation(lang: string): Observable<any> {

View File

@ -198,8 +198,10 @@ export class ProviderSamlSpComponent {
req.setId(this.provider?.id || this.justCreated$.value); req.setId(this.provider?.id || this.justCreated$.value);
req.setName(this.name?.value); req.setName(this.name?.value);
if (this.metadataXml?.value) { if (this.metadataXml?.value) {
req.setMetadataUrl('');
req.setMetadataXml(this.metadataXml?.value); req.setMetadataXml(this.metadataXml?.value);
} else { } else {
req.setMetadataXml('');
req.setMetadataUrl(this.metadataUrl?.value); req.setMetadataUrl(this.metadataUrl?.value);
} }
req.setWithSignedRequest(this.withSignedRequest?.value); req.setWithSignedRequest(this.withSignedRequest?.value);
@ -210,7 +212,6 @@ export class ProviderSamlSpComponent {
req.setTransientMappingAttributeName(this.transientMapping?.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)
@ -234,8 +235,10 @@ export class ProviderSamlSpComponent {
: new AdminAddSAMLProviderRequest(); : new AdminAddSAMLProviderRequest();
req.setName(this.name?.value); req.setName(this.name?.value);
if (this.metadataXml?.value) { if (this.metadataXml?.value) {
req.setMetadataUrl('');
req.setMetadataXml(this.metadataXml?.value); req.setMetadataXml(this.metadataXml?.value);
} else { } else {
req.setMetadataXml('');
req.setMetadataUrl(this.metadataUrl?.value); req.setMetadataUrl(this.metadataUrl?.value);
} }
req.setProviderOptions(this.options); req.setProviderOptions(this.options);

View File

@ -15,6 +15,7 @@ export const supportedLanguages = [
'ru', 'ru',
'nl', 'nl',
'sv', 'sv',
'hu',
]; ];
export const supportedLanguagesRegexp: RegExp = /de|en|es|fr|id|it|ja|pl|zh|bg|pt|mk|cs|ru|nl|sv/; export const supportedLanguagesRegexp: RegExp = /de|en|es|fr|id|it|ja|pl|zh|bg|pt|mk|cs|ru|nl|sv|hu/;
export const fallbackLanguage: string = 'en'; export const fallbackLanguage: string = 'en';

View File

@ -1382,7 +1382,8 @@
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska", "sv": "Svenska",
"id": "Bahasa Indonesia" "id": "Bahasa Indonesia",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

View File

@ -1383,7 +1383,8 @@
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska", "sv": "Svenska",
"id": "Bahasa Indonesia" "id": "Bahasa Indonesia",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

View File

@ -1383,7 +1383,8 @@
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska", "sv": "Svenska",
"id": "Bahasa Indonesia" "id": "Bahasa Indonesia",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

View File

@ -1383,7 +1383,8 @@
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska", "sv": "Svenska",
"id": "Bahasa Indonesia" "id": "Bahasa Indonesia",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

View File

@ -1384,7 +1384,8 @@
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska", "sv": "Svenska",
"id": "Bahasa Indonesia" "id": "Bahasa Indonesia",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

View File

@ -1383,7 +1383,8 @@
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska", "sv": "Svenska",
"id": "Bahasa Indonesia" "id": "Bahasa Indonesia",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

File diff suppressed because it is too large Load Diff

View File

@ -1261,7 +1261,8 @@
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska", "sv": "Svenska",
"id": "Bahasa Indonesia" "id": "Bahasa Indonesia",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

View File

@ -1383,7 +1383,8 @@
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska", "sv": "Svenska",
"id": "Bahasa Indonesia" "id": "Bahasa Indonesia",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

View File

@ -1383,7 +1383,8 @@
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska", "sv": "Svenska",
"id": "Bahasa Indonesia" "id": "Bahasa Indonesia",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

View File

@ -1384,7 +1384,8 @@
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska", "sv": "Svenska",
"id": "Bahasa Indonesia" "id": "Bahasa Indonesia",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

View File

@ -1382,7 +1382,8 @@
"cs": "Čeština", "cs": "Čeština",
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska" "sv": "Svenska",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

View File

@ -1382,7 +1382,8 @@
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska", "sv": "Svenska",
"id": "Bahasa Indonesia" "id": "Bahasa Indonesia",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

View File

@ -1384,7 +1384,8 @@
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska", "sv": "Svenska",
"id": "Bahasa Indonesia" "id": "Bahasa Indonesia",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

View File

@ -1427,7 +1427,8 @@
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska", "sv": "Svenska",
"id": "Bahasa Indonesia" "id": "Bahasa Indonesia",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

View File

@ -1387,7 +1387,8 @@
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska", "sv": "Svenska",
"id": "Bahasa Indonesia" "id": "Bahasa Indonesia",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

View File

@ -1383,7 +1383,8 @@
"ru": "Русский", "ru": "Русский",
"nl": "Nederlands", "nl": "Nederlands",
"sv": "Svenska", "sv": "Svenska",
"id": "Bahasa Indonesia" "id": "Bahasa Indonesia",
"hu": "Magyar"
} }
}, },
"SMTP": { "SMTP": {

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
--- ---
title: Actions v2 example execution locally title: Test Actions Locally
--- ---
In this guide, you will create a ZITADEL execution and target. After a user is created through the API, the target is called. In this guide, you will create a ZITADEL execution and target. After a user is created through the API, the target is called.
@ -52,7 +52,7 @@ What happens here is only a target which prints out the received request, which
As you see in the example above the target is created with HTTP and port '8090' and if we want to use it as webhook, the target can be created as follows: As you see in the example above the target is created with HTTP and port '8090' and if we want to use it as webhook, the target can be created as follows:
[Create a target](/apis/resources/action_service_v3/action-service-create-target) [Create a target](/apis/resources/action_service_v3/zitadel-actions-create-target)
```shell ```shell
curl -L -X POST 'https://$CUSTOM-DOMAIN/v3alpha/targets' \ curl -L -X POST 'https://$CUSTOM-DOMAIN/v3alpha/targets' \
@ -75,7 +75,7 @@ Save the returned ID to set in the execution.
To call the target just created before, with the intention to print the request used for user creation by the user V2 API, we define an execution with a method condition. To call the target just created before, with the intention to print the request used for user creation by the user V2 API, we define an execution with a method condition.
[Set an execution](/apis/resources/action_service_v3/action-service-set-execution) [Set an execution](/apis/resources/action_service_v3/zitadel-actions-set-execution)
```shell ```shell
curl -L -X PUT 'https://$CUSTOM-DOMAIN/v3alpha/executions' \ curl -L -X PUT 'https://$CUSTOM-DOMAIN/v3alpha/executions' \
@ -116,7 +116,7 @@ curl -L -X PUT 'https://$CUSTOM-DOMAIN/v2/users/human' \
}' }'
``` ```
Should print out something like, also described under [Sent information Request](./introduction#sent-information-request): Should print out something like, also described under [Sent information Request](./usage#sent-information-request):
```shell ```shell
{ {
"fullMethod": "/zitadel.user.v2.UserService/AddHumanUser", "fullMethod": "/zitadel.user.v2.UserService/AddHumanUser",

View File

@ -1,8 +1,19 @@
--- ---
title: Actions V2 title: Using Actions
--- ---
This page describes the options you have when defining ZITADEL Actions V2. The Action API provides a flexible mechanism for customizing and extending the functionality of ZITADEL. By allowing you to define targets and executions, you can implement custom workflows triggered on an API requests and responses, events or specific functions.
**How it works:**
- Create Target
- Set Execution with condition and target
- Custom Code will be triggered and executed
**Use Cases:**
- User Management: Automate provisioning user data to external systems when users are crreated, updated or deleted.
- Security: Implement IP blocking or rate limiting based on API usage patterns.
- Extend Workflows: Automatically setup resources in your application, when a new organization in ZITADEL is created.
- Token extension: Add custom claims to the tokens.
## Endpoints ## Endpoints
@ -51,7 +62,7 @@ There are different types of Targets:
`InterruptOnError` means that the Execution gets interrupted if any of the calls return with a status code >= 400, and the next Target will not be called anymore. `InterruptOnError` means that the Execution gets interrupted if any of the calls return with a status code >= 400, and the next Target will not be called anymore.
The API documentation to create a target can be found [here](/apis/resources/action_service_v3/action-service-create-target) The API documentation to create a target can be found [here](/apis/resources/action_service_v3/zitadel-actions-create-target)
## Execution ## Execution
@ -65,7 +76,7 @@ The condition can be defined for 4 types of processes:
- `Functions`, handling specific functionality in the logic of ZITADEL - `Functions`, handling specific functionality in the logic of ZITADEL
- `Events`, after a specific event happened and was stored in ZITADEL - `Events`, after a specific event happened and was stored in ZITADEL
The API documentation to set an Execution can be found [here](/apis/resources/action_service_v3/action-service-set-execution) The API documentation to set an Execution can be found [here](/apis/resources/action_service_v3/zitadel-actions-set-execution)
### Condition Best Match ### Condition Best Match
@ -147,19 +158,19 @@ For Request and Response there are 3 levels the condition can be defined:
- `All`, handling any request or response under the ZITADEL API - `All`, handling any request or response under the ZITADEL API
The available conditions can be found under: The available conditions can be found under:
- [All available Methods](/apis/resources/action_service_v3/action-service-list-execution-methods), for example `/zitadel.user.v2.UserService/AddHumanUser` - [All available Methods](/apis/resources/action_service_v3/zitadel-actions-list-execution-methods), for example `/zitadel.user.v2.UserService/AddHumanUser`
- [All available Services](/apis/resources/action_service_v3/action-service-list-execution-services), for example `zitadel.user.v2.UserService` - [All available Services](/apis/resources/action_service_v3/zitadel-actions-list-execution-services), for example `zitadel.user.v2.UserService`
### Condition for Functions ### Condition for Functions
Replace the current Actions with the following flows: Replace the current Actions with the following flows:
- [Internal Authentication](../actions/internal-authentication) - [Internal Authentication](/apis/actions/internal-authentication)
- [External Authentication](../actions/external-authentication) - [External Authentication](/apis/actions/external-authentication)
- [Complement Token](../actions/complement-token) - [Complement Token](/apis/actions/complement-token)
- [Customize SAML Response](../actions/customize-samlresponse) - [Customize SAML Response](/apis/actions/customize-samlresponse)
The available conditions can be found under [all available Functions](/apis/resources/action_service_v3/action-service-list-execution-functions). The available conditions can be found under [all available Functions](/apis/resources/action_service_v3/zitadel-actions-list-execution-functions).
### Condition for Events ### Condition for Events

View File

@ -303,7 +303,6 @@ For easy copying to your reverse proxy configuration, here is the list of URL pa
/saml/v2/ /saml/v2/
/oauth/v2/ /oauth/v2/
/device /device
/oidc/v1/
/.well-known/openid-configuration /.well-known/openid-configuration
/openapi/ /openapi/
/idps/callback /idps/callback

View File

@ -219,10 +219,11 @@ Send your `client_id` and `client_secret` as parameters in the body:
</TabItem> </TabItem>
<TabItem value="none"> <TabItem value="none">
Send your `code_verifier` for us to recompute the `code_challenge` of the authorization request. Send your `client_id` and `code_verifier` for us to recompute the `code_challenge` of the authorization request.
| Parameter | Description | | Parameter | Description |
| ------------- | ------------------------------------------------------------ | | ------------- | ------------------------------------------------------------ |
| client_id | client_id of the application |
| code_verifier | code_verifier previously used to generate the code_challenge | | code_verifier | code_verifier previously used to generate the code_challenge |
</TabItem> </TabItem>

View File

@ -50,6 +50,7 @@ ZITADEL is available in the following languages
- Russian (ru) - Russian (ru)
- Dutch (nl) - Dutch (nl)
- Swedish (sv) - Swedish (sv)
- Hungarian (hu)
A language is displayed based on your agent's language header. A language is displayed based on your agent's language header.
If a users language header doesn't match any of the supported or [restricted](#restrict-languages) languages, the instances default language will be used. If a users language header doesn't match any of the supported or [restricted](#restrict-languages) languages, the instances default language will be used.

View File

@ -31,7 +31,7 @@ LATEST=$(curl -i https://github.com/zitadel/zitadel/releases/latest | grep locat
## Run ZITADEL ## Run ZITADEL
```bash ```bash
ZITADEL_DATABASE_POSTGRES_HOST=localhost ZITADEL_DATABASE_POSTGRES_PORT=5432 ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=zitadel ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE=disable ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=root ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=disable ZITADEL_EXTERNALSECURE=false zitadel start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled ZITADEL_DATABASE_POSTGRES_HOST=localhost ZITADEL_DATABASE_POSTGRES_PORT=5432 ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=zitadel ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE=disable ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=root ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD=postgres ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=disable ZITADEL_EXTERNALSECURE=false zitadel start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled
``` ```
<DefaultUser components={props.components} /> <DefaultUser components={props.components} />

View File

@ -43,7 +43,7 @@ LATEST=$(curl -i https://github.com/zitadel/zitadel/releases/latest | grep locat
## Run ZITADEL ## Run ZITADEL
```bash ```bash
ZITADEL_DATABASE_POSTGRES_HOST=localhost ZITADEL_DATABASE_POSTGRES_PORT=5432 ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=zitadel ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE=disable ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=$(whoami) ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=disable ZITADEL_EXTERNALSECURE=false zitadel start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled ZITADEL_DATABASE_POSTGRES_HOST=localhost ZITADEL_DATABASE_POSTGRES_PORT=5432 ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=zitadel ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE=disable ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=$(whoami) ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD=postgres ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=disable ZITADEL_EXTERNALSECURE=false zitadel start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled
``` ```
<DefaultUser components={props.components} /> <DefaultUser components={props.components} />

View File

@ -7,7 +7,7 @@ http {
http2 on; http2 on;
location / { location / {
grpc_pass grpc://zitadel-disabled-tls:8080; grpc_pass grpc://zitadel-disabled-tls:8080;
grpc_set_header Host $host:$server_port; grpc_set_header Host $host;
} }
} }
} }

View File

@ -9,7 +9,7 @@ http {
ssl_certificate_key /etc/certs/selfsigned.key; ssl_certificate_key /etc/certs/selfsigned.key;
location / { location / {
grpc_pass grpcs://zitadel-enabled-tls:8080; grpc_pass grpcs://zitadel-enabled-tls:8080;
grpc_set_header Host $host:$server_port; grpc_set_header Host $host;
} }
} }
} }

View File

@ -9,7 +9,7 @@ http {
ssl_certificate_key /etc/certs/selfsigned.key; ssl_certificate_key /etc/certs/selfsigned.key;
location / { location / {
grpc_pass grpc://zitadel-external-tls:8080; grpc_pass grpc://zitadel-external-tls:8080;
grpc_set_header Host $host:$server_port; grpc_set_header Host $host;
} }
} }
} }

View File

@ -745,10 +745,20 @@ module.exports = {
slug: "/apis/resources/action_service_v3", slug: "/apis/resources/action_service_v3",
description: description:
"This API is intended to manage custom executions and targets (previously known as actions) in a ZITADEL instance.\n" + "This API is intended to manage custom executions and targets (previously known as actions) in a ZITADEL instance.\n" +
"The version 3 of actions provide much more options to customize ZITADELs behaviour than previous action versions.\n" +
"Also, v3 actions are available instance-wide, whereas previous actions had to be managed for each organization individually\n" +
"ZITADEL doesn't restrict the implementation languages, tooling and runtime for v3 action executions anymore.\n" +
"Instead, it calls external endpoints which are implemented and maintained by action v3 users.\n" +
"\n" + "\n" +
"This project is in Preview state. It can AND will continue breaking until the services provide the same functionality as the current actions.", "This project is in Preview state. It can AND will continue breaking until the services provide the same functionality as the current actions.",
}, },
items: require("./docs/apis/resources/action_service_v3/sidebar.ts"), items: [{
type: "doc",
id: "apis/actions/v3/usage",
}, {
type: "doc",
id: "apis/actions/v3/testing-locally",
}].concat(require("./docs/apis/resources/action_service_v3/sidebar.ts")),
}, },
{ {
type: "category", type: "category",
@ -815,12 +825,6 @@ module.exports = {
"apis/actions/objects", "apis/actions/objects",
], ],
}, },
{
type: "category",
label: "Actions V2",
collapsed: false,
items: ["apis/actionsv2/introduction", "apis/actionsv2/execution-local"],
},
{ {
type: "doc", type: "doc",
label: "gRPC Status Codes", label: "gRPC Status Codes",

View File

@ -24,6 +24,8 @@
{ "source": "/docs/apis/auth/:slug*", "destination": "/docs/apis/resources/auth/:slug*", "permanent": true }, { "source": "/docs/apis/auth/:slug*", "destination": "/docs/apis/resources/auth/:slug*", "permanent": true },
{ "source": "/docs/apis/system/:slug*", "destination": "/docs/apis/resources/system/:slug*", "permanent": true }, { "source": "/docs/apis/system/:slug*", "destination": "/docs/apis/resources/system/:slug*", "permanent": true },
{ "source": "/docs/apis/admin/:slug*", "destination": "/docs/apis/resources/admin/:slug*", "permanent": true }, { "source": "/docs/apis/admin/:slug*", "destination": "/docs/apis/resources/admin/:slug*", "permanent": true },
{ "source": "/docs/apis/actionsv2/introduction", "destination": "/docs/apis/actions/v3/usage", "permanent": true },
{ "source": "/docs/apis/actionsv2/execution-local", "destination": "/docs/apis/actions/v3/testing-locally", "permanent": true },
{ "source": "/docs/guides/integrate/human-users", "destination": "/docs/guides/integrate/login", "permanent": true }, { "source": "/docs/guides/integrate/human-users", "destination": "/docs/guides/integrate/login", "permanent": true },
{ "source": "/docs/guides/solution-scenarios/device-authorization", "destination": "/docs/guides/integrate/login/oidc/device-authorization", "permanent": true }, { "source": "/docs/guides/solution-scenarios/device-authorization", "destination": "/docs/guides/integrate/login/oidc/device-authorization", "permanent": true },
{ "source": "/docs/guides/integrate/oauth-recommended-flows", "destination": "/docs/guides/integrate/login/oidc/oauth-recommended-flows", "permanent": true }, { "source": "/docs/guides/integrate/oauth-recommended-flows", "destination": "/docs/guides/integrate/login/oidc/oauth-recommended-flows", "permanent": true },

9
go.mod
View File

@ -38,7 +38,7 @@ require (
github.com/h2non/gock v1.2.0 github.com/h2non/gock v1.2.0
github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/improbable-eng/grpc-web v0.15.0 github.com/improbable-eng/grpc-web v0.15.0
github.com/jackc/pgx/v5 v5.6.0 github.com/jackc/pgx/v5 v5.7.0
github.com/jarcoal/jpath v0.0.0-20140328210829-f76b8b2dbf52 github.com/jarcoal/jpath v0.0.0-20140328210829-f76b8b2dbf52
github.com/jinzhu/gorm v1.9.16 github.com/jinzhu/gorm v1.9.16
github.com/k3a/html2text v1.2.1 github.com/k3a/html2text v1.2.1
@ -49,6 +49,7 @@ require (
github.com/muhlemmer/gu v0.3.1 github.com/muhlemmer/gu v0.3.1
github.com/muhlemmer/httpforwarded v0.1.0 github.com/muhlemmer/httpforwarded v0.1.0
github.com/nicksnyder/go-i18n/v2 v2.4.0 github.com/nicksnyder/go-i18n/v2 v2.4.0
github.com/pashagolub/pgxmock/v4 v4.3.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.11.0 github.com/rs/cors v1.11.0
@ -76,12 +77,12 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.28.0 go.opentelemetry.io/otel/sdk/metric v1.28.0
go.opentelemetry.io/otel/trace v1.28.0 go.opentelemetry.io/otel/trace v1.28.0
go.uber.org/mock v0.4.0 go.uber.org/mock v0.4.0
golang.org/x/crypto v0.25.0 golang.org/x/crypto v0.27.0
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
golang.org/x/net v0.26.0 golang.org/x/net v0.26.0
golang.org/x/oauth2 v0.22.0 golang.org/x/oauth2 v0.22.0
golang.org/x/sync v0.8.0 golang.org/x/sync v0.8.0
golang.org/x/text v0.17.0 golang.org/x/text v0.18.0
google.golang.org/api v0.187.0 google.golang.org/api v0.187.0
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094
google.golang.org/grpc v1.65.0 google.golang.org/grpc v1.65.0
@ -169,7 +170,7 @@ require (
github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jonboulle/clockwork v0.4.0 github.com/jonboulle/clockwork v0.4.0
github.com/klauspost/compress v1.17.9 // indirect github.com/klauspost/compress v1.17.9 // indirect

18
go.sum
View File

@ -400,10 +400,10 @@ github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLf
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY= github.com/jackc/pgx/v5 v5.7.0 h1:FG6VLIdzvAPhnYqP14sQ2xhFLkiUQHCs6ySqO91kF4g=
github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw= github.com/jackc/pgx/v5 v5.7.0/go.mod h1:awP1KNnjylvpxHuHP63gzjhnGkI1iw+PMoIwvoleN/8=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jarcoal/jpath v0.0.0-20140328210829-f76b8b2dbf52 h1:jny9eqYPwkG8IVy7foUoRjQmFLcArCSz+uPsL6KS0HQ= github.com/jarcoal/jpath v0.0.0-20140328210829-f76b8b2dbf52 h1:jny9eqYPwkG8IVy7foUoRjQmFLcArCSz+uPsL6KS0HQ=
@ -567,6 +567,8 @@ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pashagolub/pgxmock/v4 v4.3.0 h1:DqT7fk0OCK6H0GvqtcMsLpv8cIwWqdxWgfZNLeHCb/s=
github.com/pashagolub/pgxmock/v4 v4.3.0/go.mod h1:9VoVHXwS3XR/yPtKGzwQvwZX1kzGB9sM8SviDcHDa3A=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
@ -791,8 +793,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
@ -932,8 +934,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=

View File

@ -42,6 +42,8 @@ func TestMain(m *testing.M) {
} }
func TestServer_AddOrganization(t *testing.T) { func TestServer_AddOrganization(t *testing.T) {
t.Parallel()
idpResp := Instance.AddGenericOAuthProvider(CTX, Instance.DefaultOrg.Id) idpResp := Instance.AddGenericOAuthProvider(CTX, Instance.DefaultOrg.Id)
tests := []struct { tests := []struct {

View File

@ -26,6 +26,8 @@ type orgAttr struct {
} }
func TestServer_ListOrganizations(t *testing.T) { func TestServer_ListOrganizations(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *org.ListOrganizationsRequest req *org.ListOrganizationsRequest
@ -37,6 +39,38 @@ func TestServer_ListOrganizations(t *testing.T) {
want *org.ListOrganizationsResponse want *org.ListOrganizationsResponse
wantErr bool wantErr bool
}{ }{
{
name: "list org by default, ok",
args: args{
CTX,
&org.ListOrganizationsRequest{
Queries: []*org.SearchQuery{
DefaultOrganizationQuery(),
},
},
nil,
},
want: &org.ListOrganizationsResponse{
Details: &object.ListDetails{
TotalResult: 1,
Timestamp: timestamppb.Now(),
},
SortingColumn: 0,
Result: []*org.Organization{
{
Id: Instance.DefaultOrg.Id,
Name: Instance.DefaultOrg.Name,
PrimaryDomain: Instance.DefaultOrg.PrimaryDomain,
State: org.OrganizationState_ORGANIZATION_STATE_ACTIVE,
Details: &object.Details{
Sequence: Instance.DefaultOrg.Details.Sequence,
ChangeDate: Instance.DefaultOrg.Details.ChangeDate,
ResourceOwner: Instance.DefaultOrg.Details.ResourceOwner,
},
},
},
},
},
{ {
name: "list org by id, ok, multiple", name: "list org by id, ok, multiple",
args: args{ args: args{
@ -401,6 +435,12 @@ func TestServer_ListOrganizations(t *testing.T) {
} }
} }
func DefaultOrganizationQuery() *org.SearchQuery {
return &org.SearchQuery{Query: &org.SearchQuery_DefaultQuery{
DefaultQuery: &org.DefaultOrganizationQuery{},
}}
}
func OrganizationIdQuery(resourceowner string) *org.SearchQuery { func OrganizationIdQuery(resourceowner string) *org.SearchQuery {
return &org.SearchQuery{Query: &org.SearchQuery_IdQuery{ return &org.SearchQuery{Query: &org.SearchQuery_IdQuery{
IdQuery: &org.OrganizationIDQuery{ IdQuery: &org.OrganizationIDQuery{

View File

@ -3,6 +3,7 @@ package org
import ( import (
"context" "context"
"github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/grpc/object/v2" "github.com/zitadel/zitadel/internal/api/grpc/object/v2"
"github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/query" "github.com/zitadel/zitadel/internal/query"
@ -11,7 +12,7 @@ import (
) )
func (s *Server) ListOrganizations(ctx context.Context, req *org.ListOrganizationsRequest) (*org.ListOrganizationsResponse, error) { func (s *Server) ListOrganizations(ctx context.Context, req *org.ListOrganizationsRequest) (*org.ListOrganizationsResponse, error) {
queries, err := listOrgRequestToModel(req) queries, err := listOrgRequestToModel(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -25,9 +26,9 @@ func (s *Server) ListOrganizations(ctx context.Context, req *org.ListOrganizatio
}, nil }, nil
} }
func listOrgRequestToModel(req *org.ListOrganizationsRequest) (*query.OrgSearchQueries, error) { func listOrgRequestToModel(ctx context.Context, req *org.ListOrganizationsRequest) (*query.OrgSearchQueries, error) {
offset, limit, asc := object.ListQueryToQuery(req.Query) offset, limit, asc := object.ListQueryToQuery(req.Query)
queries, err := orgQueriesToQuery(req.Queries) queries, err := orgQueriesToQuery(ctx, req.Queries)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -42,10 +43,10 @@ func listOrgRequestToModel(req *org.ListOrganizationsRequest) (*query.OrgSearchQ
}, nil }, nil
} }
func orgQueriesToQuery(queries []*org.SearchQuery) (_ []query.SearchQuery, err error) { func orgQueriesToQuery(ctx context.Context, queries []*org.SearchQuery) (_ []query.SearchQuery, err error) {
q := make([]query.SearchQuery, len(queries)) q := make([]query.SearchQuery, len(queries))
for i, query := range queries { for i, query := range queries {
q[i], err = orgQueryToQuery(query) q[i], err = orgQueryToQuery(ctx, query)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -53,7 +54,7 @@ func orgQueriesToQuery(queries []*org.SearchQuery) (_ []query.SearchQuery, err e
return q, nil return q, nil
} }
func orgQueryToQuery(orgQuery *org.SearchQuery) (query.SearchQuery, error) { func orgQueryToQuery(ctx context.Context, orgQuery *org.SearchQuery) (query.SearchQuery, error) {
switch q := orgQuery.Query.(type) { switch q := orgQuery.Query.(type) {
case *org.SearchQuery_DomainQuery: case *org.SearchQuery_DomainQuery:
return query.NewOrgDomainSearchQuery(object.TextMethodToQuery(q.DomainQuery.Method), q.DomainQuery.Domain) return query.NewOrgDomainSearchQuery(object.TextMethodToQuery(q.DomainQuery.Method), q.DomainQuery.Domain)
@ -63,6 +64,8 @@ func orgQueryToQuery(orgQuery *org.SearchQuery) (query.SearchQuery, error) {
return query.NewOrgStateSearchQuery(orgStateToDomain(q.StateQuery.State)) return query.NewOrgStateSearchQuery(orgStateToDomain(q.StateQuery.State))
case *org.SearchQuery_IdQuery: case *org.SearchQuery_IdQuery:
return query.NewOrgIDSearchQuery(q.IdQuery.Id) return query.NewOrgIDSearchQuery(q.IdQuery.Id)
case *org.SearchQuery_DefaultQuery:
return query.NewOrgIDSearchQuery(authz.GetInstance(ctx).DefaultOrganisationID())
default: default:
return nil, zerrors.ThrowInvalidArgument(nil, "ORG-vR9nC", "List.Query.Invalid") return nil, zerrors.ThrowInvalidArgument(nil, "ORG-vR9nC", "List.Query.Invalid")
} }

View File

@ -13,11 +13,13 @@ import (
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
"github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/internal/integration"
object "github.com/zitadel/zitadel/pkg/grpc/object/v2" "github.com/zitadel/zitadel/pkg/grpc/object/v2"
user "github.com/zitadel/zitadel/pkg/grpc/user/v2" "github.com/zitadel/zitadel/pkg/grpc/user/v2"
) )
func TestServer_SetEmail(t *testing.T) { func TestServer_SetEmail(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
tests := []struct { tests := []struct {
@ -144,6 +146,8 @@ func TestServer_SetEmail(t *testing.T) {
} }
func TestServer_ResendEmailCode(t *testing.T) { func TestServer_ResendEmailCode(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId() verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId()
@ -245,6 +249,8 @@ func TestServer_ResendEmailCode(t *testing.T) {
} }
func TestServer_VerifyEmail(t *testing.T) { func TestServer_VerifyEmail(t *testing.T) {
t.Parallel()
userResp := Instance.CreateHumanUser(CTX) userResp := Instance.CreateHumanUser(CTX)
tests := []struct { tests := []struct {
name string name string

View File

@ -19,6 +19,8 @@ import (
) )
func TestServer_AddIDPLink(t *testing.T) { func TestServer_AddIDPLink(t *testing.T) {
t.Parallel()
idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)
type args struct { type args struct {
ctx context.Context ctx context.Context
@ -99,6 +101,8 @@ func TestServer_AddIDPLink(t *testing.T) {
} }
func TestServer_ListIDPLinks(t *testing.T) { func TestServer_ListIDPLinks(t *testing.T) {
t.Parallel()
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListIDPLinks%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListIDPLinks%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
instanceIdpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) instanceIdpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)
@ -258,6 +262,8 @@ func TestServer_ListIDPLinks(t *testing.T) {
} }
func TestServer_RemoveIDPLink(t *testing.T) { func TestServer_RemoveIDPLink(t *testing.T) {
t.Parallel()
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListIDPLinks%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListIDPLinks%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
instanceIdpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) instanceIdpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)

View File

@ -15,6 +15,8 @@ import (
) )
func TestServer_AddOTPSMS(t *testing.T) { func TestServer_AddOTPSMS(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID) Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
@ -121,6 +123,8 @@ func TestServer_AddOTPSMS(t *testing.T) {
} }
func TestServer_RemoveOTPSMS(t *testing.T) { func TestServer_RemoveOTPSMS(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID) Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
@ -187,6 +191,8 @@ func TestServer_RemoveOTPSMS(t *testing.T) {
} }
func TestServer_AddOTPEmail(t *testing.T) { func TestServer_AddOTPEmail(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID) Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
@ -295,6 +301,8 @@ func TestServer_AddOTPEmail(t *testing.T) {
} }
func TestServer_RemoveOTPEmail(t *testing.T) { func TestServer_RemoveOTPEmail(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID) Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)

View File

@ -19,6 +19,8 @@ import (
) )
func TestServer_RegisterPasskey(t *testing.T) { func TestServer_RegisterPasskey(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
reg, err := Client.CreatePasskeyRegistrationLink(CTX, &user.CreatePasskeyRegistrationLinkRequest{ reg, err := Client.CreatePasskeyRegistrationLink(CTX, &user.CreatePasskeyRegistrationLinkRequest{
UserId: userID, UserId: userID,
@ -139,6 +141,8 @@ func TestServer_RegisterPasskey(t *testing.T) {
} }
func TestServer_VerifyPasskeyRegistration(t *testing.T) { func TestServer_VerifyPasskeyRegistration(t *testing.T) {
t.Parallel()
userID, pkr := userWithPasskeyRegistered(t) userID, pkr := userWithPasskeyRegistered(t)
attestationResponse, err := Instance.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) attestationResponse, err := Instance.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions())
@ -215,6 +219,8 @@ func TestServer_VerifyPasskeyRegistration(t *testing.T) {
} }
func TestServer_CreatePasskeyRegistrationLink(t *testing.T) { func TestServer_CreatePasskeyRegistrationLink(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
type args struct { type args struct {
@ -348,6 +354,8 @@ func passkeyVerify(t *testing.T, userID string, pkr *user.RegisterPasskeyRespons
} }
func TestServer_RemovePasskey(t *testing.T) { func TestServer_RemovePasskey(t *testing.T) {
t.Parallel()
userIDWithout := Instance.CreateHumanUser(CTX).GetUserId() userIDWithout := Instance.CreateHumanUser(CTX).GetUserId()
userIDRegistered, pkrRegistered := userWithPasskeyRegistered(t) userIDRegistered, pkrRegistered := userWithPasskeyRegistered(t)
userIDVerified, passkeyIDVerified := userWithPasskeyVerified(t) userIDVerified, passkeyIDVerified := userWithPasskeyVerified(t)
@ -453,6 +461,8 @@ func TestServer_RemovePasskey(t *testing.T) {
} }
func TestServer_ListPasskeys(t *testing.T) { func TestServer_ListPasskeys(t *testing.T) {
t.Parallel()
userIDWithout := Instance.CreateHumanUser(CTX).GetUserId() userIDWithout := Instance.CreateHumanUser(CTX).GetUserId()
userIDRegistered, _ := userWithPasskeyRegistered(t) userIDRegistered, _ := userWithPasskeyRegistered(t)
userIDVerified, passkeyIDVerified := userWithPasskeyVerified(t) userIDVerified, passkeyIDVerified := userWithPasskeyVerified(t)

View File

@ -12,11 +12,13 @@ import (
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
"github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/internal/integration"
object "github.com/zitadel/zitadel/pkg/grpc/object/v2" "github.com/zitadel/zitadel/pkg/grpc/object/v2"
user "github.com/zitadel/zitadel/pkg/grpc/user/v2" "github.com/zitadel/zitadel/pkg/grpc/user/v2"
) )
func TestServer_RequestPasswordReset(t *testing.T) { func TestServer_RequestPasswordReset(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
tests := []struct { tests := []struct {
@ -104,6 +106,8 @@ func TestServer_RequestPasswordReset(t *testing.T) {
} }
func TestServer_SetPassword(t *testing.T) { func TestServer_SetPassword(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.SetPasswordRequest req *user.SetPasswordRequest

View File

@ -14,11 +14,13 @@ import (
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
"github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/internal/integration"
object "github.com/zitadel/zitadel/pkg/grpc/object/v2" "github.com/zitadel/zitadel/pkg/grpc/object/v2"
user "github.com/zitadel/zitadel/pkg/grpc/user/v2" "github.com/zitadel/zitadel/pkg/grpc/user/v2"
) )
func TestServer_SetPhone(t *testing.T) { func TestServer_SetPhone(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
tests := []struct { tests := []struct {
@ -122,6 +124,8 @@ func TestServer_SetPhone(t *testing.T) {
} }
func TestServer_ResendPhoneCode(t *testing.T) { func TestServer_ResendPhoneCode(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId() verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId()
@ -196,6 +200,8 @@ func TestServer_ResendPhoneCode(t *testing.T) {
} }
func TestServer_VerifyPhone(t *testing.T) { func TestServer_VerifyPhone(t *testing.T) {
t.Parallel()
userResp := Instance.CreateHumanUser(CTX) userResp := Instance.CreateHumanUser(CTX)
tests := []struct { tests := []struct {
name string name string
@ -248,6 +254,8 @@ func TestServer_VerifyPhone(t *testing.T) {
} }
func TestServer_RemovePhone(t *testing.T) { func TestServer_RemovePhone(t *testing.T) {
t.Parallel()
userResp := Instance.CreateHumanUser(CTX) userResp := Instance.CreateHumanUser(CTX)
failResp := Instance.CreateHumanUserNoPhone(CTX) failResp := Instance.CreateHumanUserNoPhone(CTX)
otherUser := Instance.CreateHumanUser(CTX).GetUserId() otherUser := Instance.CreateHumanUser(CTX).GetUserId()

View File

@ -19,6 +19,8 @@ import (
) )
func TestServer_GetUserByID(t *testing.T) { func TestServer_GetUserByID(t *testing.T) {
t.Parallel()
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
type args struct { type args struct {
ctx context.Context ctx context.Context
@ -187,6 +189,8 @@ func TestServer_GetUserByID(t *testing.T) {
} }
func TestServer_GetUserByID_Permission(t *testing.T) { func TestServer_GetUserByID_Permission(t *testing.T) {
t.Parallel()
timeNow := time.Now().UTC() timeNow := time.Now().UTC()
newOrgOwnerEmail := fmt.Sprintf("%d@permission.get.com", timeNow.UnixNano()) newOrgOwnerEmail := fmt.Sprintf("%d@permission.get.com", timeNow.UnixNano())
newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetHuman%d", time.Now().UnixNano()), newOrgOwnerEmail)
@ -329,6 +333,8 @@ type userAttr struct {
} }
func TestServer_ListUsers(t *testing.T) { func TestServer_ListUsers(t *testing.T) {
t.Parallel()
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListUsersOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListUsersOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
userResp := Instance.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listusers.com", time.Now().UnixNano())) userResp := Instance.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listusers.com", time.Now().UnixNano()))
type args struct { type args struct {

View File

@ -18,6 +18,8 @@ import (
) )
func TestServer_RegisterTOTP(t *testing.T) { func TestServer_RegisterTOTP(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID) Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
@ -104,6 +106,8 @@ func TestServer_RegisterTOTP(t *testing.T) {
} }
func TestServer_VerifyTOTPRegistration(t *testing.T) { func TestServer_VerifyTOTPRegistration(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID) Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
@ -207,6 +211,8 @@ func TestServer_VerifyTOTPRegistration(t *testing.T) {
} }
func TestServer_RemoveTOTP(t *testing.T) { func TestServer_RemoveTOTP(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID) Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)

View File

@ -17,6 +17,8 @@ import (
) )
func TestServer_RegisterU2F(t *testing.T) { func TestServer_RegisterU2F(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
otherUser := Instance.CreateHumanUser(CTX).GetUserId() otherUser := Instance.CreateHumanUser(CTX).GetUserId()
@ -106,6 +108,8 @@ func TestServer_RegisterU2F(t *testing.T) {
} }
func TestServer_VerifyU2FRegistration(t *testing.T) { func TestServer_VerifyU2FRegistration(t *testing.T) {
t.Parallel()
ctx, userID, pkr := ctxFromNewUserWithRegisteredU2F(t) ctx, userID, pkr := ctxFromNewUserWithRegisteredU2F(t)
attestationResponse, err := Instance.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions()) attestationResponse, err := Instance.WebAuthN.CreateAttestationResponse(pkr.GetPublicKeyCredentialCreationOptions())
@ -211,6 +215,8 @@ func ctxFromNewUserWithVerifiedU2F(t *testing.T) (context.Context, string, strin
} }
func TestServer_RemoveU2F(t *testing.T) { func TestServer_RemoveU2F(t *testing.T) {
t.Parallel()
userIDWithout := Instance.CreateHumanUser(CTX).GetUserId() userIDWithout := Instance.CreateHumanUser(CTX).GetUserId()
ctxRegistered, userIDRegistered, pkrRegistered := ctxFromNewUserWithRegisteredU2F(t) ctxRegistered, userIDRegistered, pkrRegistered := ctxFromNewUserWithRegisteredU2F(t)
_, userIDVerified, u2fVerified := ctxFromNewUserWithVerifiedU2F(t) _, userIDVerified, u2fVerified := ctxFromNewUserWithVerifiedU2F(t)

View File

@ -18,9 +18,11 @@ import (
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
"github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/internal/integration"
"github.com/zitadel/zitadel/pkg/grpc/auth"
"github.com/zitadel/zitadel/pkg/grpc/idp" "github.com/zitadel/zitadel/pkg/grpc/idp"
mgmt "github.com/zitadel/zitadel/pkg/grpc/management" mgmt "github.com/zitadel/zitadel/pkg/grpc/management"
"github.com/zitadel/zitadel/pkg/grpc/object/v2" "github.com/zitadel/zitadel/pkg/grpc/object/v2"
user_v1 "github.com/zitadel/zitadel/pkg/grpc/user"
"github.com/zitadel/zitadel/pkg/grpc/user/v2" "github.com/zitadel/zitadel/pkg/grpc/user/v2"
) )
@ -50,6 +52,8 @@ func TestMain(m *testing.M) {
} }
func TestServer_AddHumanUser(t *testing.T) { func TestServer_AddHumanUser(t *testing.T) {
t.Parallel()
idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)
type args struct { type args struct {
ctx context.Context ctx context.Context
@ -672,6 +676,8 @@ func TestServer_AddHumanUser(t *testing.T) {
} }
func TestServer_AddHumanUser_Permission(t *testing.T) { func TestServer_AddHumanUser_Permission(t *testing.T) {
t.Parallel()
newOrgOwnerEmail := fmt.Sprintf("%d@permission.com", time.Now().UnixNano()) newOrgOwnerEmail := fmt.Sprintf("%d@permission.com", time.Now().UnixNano())
newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("AddHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("AddHuman%d", time.Now().UnixNano()), newOrgOwnerEmail)
type args struct { type args struct {
@ -865,6 +871,8 @@ func TestServer_AddHumanUser_Permission(t *testing.T) {
} }
func TestServer_UpdateHumanUser(t *testing.T) { func TestServer_UpdateHumanUser(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.UpdateHumanUserRequest req *user.UpdateHumanUserRequest
@ -1221,6 +1229,8 @@ func TestServer_UpdateHumanUser(t *testing.T) {
} }
func TestServer_UpdateHumanUser_Permission(t *testing.T) { func TestServer_UpdateHumanUser_Permission(t *testing.T) {
t.Parallel()
newOrgOwnerEmail := fmt.Sprintf("%d@permission.update.com", time.Now().UnixNano()) newOrgOwnerEmail := fmt.Sprintf("%d@permission.update.com", time.Now().UnixNano())
newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("UpdateHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("UpdateHuman%d", time.Now().UnixNano()), newOrgOwnerEmail)
newUserID := newOrg.CreatedAdmins[0].GetUserId() newUserID := newOrg.CreatedAdmins[0].GetUserId()
@ -1304,6 +1314,8 @@ func TestServer_UpdateHumanUser_Permission(t *testing.T) {
} }
func TestServer_LockUser(t *testing.T) { func TestServer_LockUser(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.LockUserRequest req *user.LockUserRequest
@ -1412,6 +1424,8 @@ func TestServer_LockUser(t *testing.T) {
} }
func TestServer_UnLockUser(t *testing.T) { func TestServer_UnLockUser(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.UnlockUserRequest req *user.UnlockUserRequest
@ -1520,6 +1534,8 @@ func TestServer_UnLockUser(t *testing.T) {
} }
func TestServer_DeactivateUser(t *testing.T) { func TestServer_DeactivateUser(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.DeactivateUserRequest req *user.DeactivateUserRequest
@ -1628,6 +1644,8 @@ func TestServer_DeactivateUser(t *testing.T) {
} }
func TestServer_ReactivateUser(t *testing.T) { func TestServer_ReactivateUser(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.ReactivateUserRequest req *user.ReactivateUserRequest
@ -1736,6 +1754,8 @@ func TestServer_ReactivateUser(t *testing.T) {
} }
func TestServer_DeleteUser(t *testing.T) { func TestServer_DeleteUser(t *testing.T) {
t.Parallel()
projectResp, err := Instance.CreateProject(CTX) projectResp, err := Instance.CreateProject(CTX)
require.NoError(t, err) require.NoError(t, err)
type args struct { type args struct {
@ -1835,6 +1855,8 @@ func TestServer_DeleteUser(t *testing.T) {
} }
func TestServer_StartIdentityProviderIntent(t *testing.T) { func TestServer_StartIdentityProviderIntent(t *testing.T) {
t.Parallel()
idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)
orgIdpResp := Instance.AddOrgGenericOAuthProvider(CTX, Instance.DefaultOrg.Id) orgIdpResp := Instance.AddOrgGenericOAuthProvider(CTX, Instance.DefaultOrg.Id)
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("NotDefaultOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("NotDefaultOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
@ -2099,6 +2121,8 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) {
/* /*
func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
t.Parallel()
idpID := Instance.AddGenericOAuthProvider(t, CTX) idpID := Instance.AddGenericOAuthProvider(t, CTX)
intentID := Instance.CreateIntent(t, CTX, idpID) intentID := Instance.CreateIntent(t, CTX, idpID)
successfulID, token, changeDate, sequence := Instance.CreateSuccessfulOAuthIntent(t, CTX, idpID, "", "id") successfulID, token, changeDate, sequence := Instance.CreateSuccessfulOAuthIntent(t, CTX, idpID, "", "id")
@ -2358,7 +2382,37 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
} }
*/ */
func ctxFromNewUserWithRegisteredPasswordlessLegacy(t *testing.T) (context.Context, string, *auth.AddMyPasswordlessResponse) {
userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
ctx := integration.WithAuthorizationToken(CTX, sessionToken)
pkr, err := Instance.Client.Auth.AddMyPasswordless(ctx, &auth.AddMyPasswordlessRequest{})
require.NoError(t, err)
require.NotEmpty(t, pkr.GetKey())
return ctx, userID, pkr
}
func ctxFromNewUserWithVerifiedPasswordlessLegacy(t *testing.T) (context.Context, string) {
ctx, userID, pkr := ctxFromNewUserWithRegisteredPasswordlessLegacy(t)
attestationResponse, err := Instance.WebAuthN.CreateAttestationResponseData(pkr.GetKey().GetPublicKey())
require.NoError(t, err)
_, err = Instance.Client.Auth.VerifyMyPasswordless(ctx, &auth.VerifyMyPasswordlessRequest{
Verification: &user_v1.WebAuthNVerification{
TokenName: "Mickey",
PublicKeyCredential: attestationResponse,
},
})
require.NoError(t, err)
return ctx, userID
}
func TestServer_ListAuthenticationMethodTypes(t *testing.T) { func TestServer_ListAuthenticationMethodTypes(t *testing.T) {
t.Parallel()
userIDWithoutAuth := Instance.CreateHumanUser(CTX).GetUserId() userIDWithoutAuth := Instance.CreateHumanUser(CTX).GetUserId()
userIDWithPasskey := Instance.CreateHumanUser(CTX).GetUserId() userIDWithPasskey := Instance.CreateHumanUser(CTX).GetUserId()
@ -2395,6 +2449,9 @@ func TestServer_ListAuthenticationMethodTypes(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
_, userLegacyID := ctxFromNewUserWithVerifiedPasswordlessLegacy(t)
require.NoError(t, err)
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.ListAuthenticationMethodTypesRequest req *user.ListAuthenticationMethodTypesRequest
@ -2435,6 +2492,81 @@ func TestServer_ListAuthenticationMethodTypes(t *testing.T) {
}, },
}, },
}, },
{
name: "with auth (passkey) with domain",
args: args{
CTX,
&user.ListAuthenticationMethodTypesRequest{
UserId: userIDWithPasskey,
DomainQuery: &user.DomainQuery{
Domain: Instance.Domain,
},
},
},
want: &user.ListAuthenticationMethodTypesResponse{
Details: &object.ListDetails{
TotalResult: 1,
},
AuthMethodTypes: []user.AuthenticationMethodType{
user.AuthenticationMethodType_AUTHENTICATION_METHOD_TYPE_PASSKEY,
},
},
},
{
name: "with auth (passkey) with wrong domain",
args: args{
CTX,
&user.ListAuthenticationMethodTypesRequest{
UserId: userIDWithPasskey,
DomainQuery: &user.DomainQuery{
Domain: "notexistent",
},
},
},
want: &user.ListAuthenticationMethodTypesResponse{
Details: &object.ListDetails{
TotalResult: 0,
},
},
},
{
name: "with auth (passkey) with legacy",
args: args{
CTX,
&user.ListAuthenticationMethodTypesRequest{
UserId: userLegacyID,
DomainQuery: &user.DomainQuery{
Domain: "notexistent",
},
},
},
want: &user.ListAuthenticationMethodTypesResponse{
Details: &object.ListDetails{
TotalResult: 0,
},
},
},
{
name: "with auth (passkey) with legacy included",
args: args{
CTX,
&user.ListAuthenticationMethodTypesRequest{
UserId: userLegacyID,
DomainQuery: &user.DomainQuery{
Domain: "notexistent",
IncludeWithoutDomain: true,
},
},
},
want: &user.ListAuthenticationMethodTypesResponse{
Details: &object.ListDetails{
TotalResult: 1,
},
AuthMethodTypes: []user.AuthenticationMethodType{
user.AuthenticationMethodType_AUTHENTICATION_METHOD_TYPE_PASSKEY,
},
},
},
{ {
name: "multiple auth", name: "multiple auth",
args: args{ args: args{
@ -2453,6 +2585,47 @@ func TestServer_ListAuthenticationMethodTypes(t *testing.T) {
}, },
}, },
}, },
{
name: "multiple auth with domain",
args: args{
CTX,
&user.ListAuthenticationMethodTypesRequest{
UserId: userMultipleAuth,
DomainQuery: &user.DomainQuery{
Domain: Instance.Domain,
},
},
},
want: &user.ListAuthenticationMethodTypesResponse{
Details: &object.ListDetails{
TotalResult: 2,
},
AuthMethodTypes: []user.AuthenticationMethodType{
user.AuthenticationMethodType_AUTHENTICATION_METHOD_TYPE_PASSKEY,
user.AuthenticationMethodType_AUTHENTICATION_METHOD_TYPE_IDP,
},
},
},
{
name: "multiple auth with wrong domain",
args: args{
CTX,
&user.ListAuthenticationMethodTypesRequest{
UserId: userMultipleAuth,
DomainQuery: &user.DomainQuery{
Domain: "notexistent",
},
},
},
want: &user.ListAuthenticationMethodTypesResponse{
Details: &object.ListDetails{
TotalResult: 1,
},
AuthMethodTypes: []user.AuthenticationMethodType{
user.AuthenticationMethodType_AUTHENTICATION_METHOD_TYPE_IDP,
},
},
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
@ -2480,6 +2653,8 @@ func TestServer_ListAuthenticationMethodTypes(t *testing.T) {
} }
func TestServer_CreateInviteCode(t *testing.T) { func TestServer_CreateInviteCode(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.CreateInviteCodeRequest req *user.CreateInviteCodeRequest
@ -2610,6 +2785,8 @@ func TestServer_CreateInviteCode(t *testing.T) {
} }
func TestServer_ResendInviteCode(t *testing.T) { func TestServer_ResendInviteCode(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.ResendInviteCodeRequest req *user.ResendInviteCodeRequest
@ -2698,6 +2875,8 @@ func TestServer_ResendInviteCode(t *testing.T) {
} }
func TestServer_VerifyInviteCode(t *testing.T) { func TestServer_VerifyInviteCode(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.VerifyInviteCodeRequest req *user.VerifyInviteCodeRequest

View File

@ -587,7 +587,7 @@ func (s *Server) checkIntentToken(token string, intentID string) error {
} }
func (s *Server) ListAuthenticationMethodTypes(ctx context.Context, req *user.ListAuthenticationMethodTypesRequest) (*user.ListAuthenticationMethodTypesResponse, error) { func (s *Server) ListAuthenticationMethodTypes(ctx context.Context, req *user.ListAuthenticationMethodTypesRequest) (*user.ListAuthenticationMethodTypesResponse, error) {
authMethods, err := s.query.ListUserAuthMethodTypes(ctx, req.GetUserId(), true) authMethods, err := s.query.ListUserAuthMethodTypes(ctx, req.GetUserId(), true, req.GetDomainQuery().GetIncludeWithoutDomain(), req.GetDomainQuery().GetDomain())
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -18,6 +18,8 @@ import (
) )
func TestServer_SetEmail(t *testing.T) { func TestServer_SetEmail(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
tests := []struct { tests := []struct {
@ -144,6 +146,8 @@ func TestServer_SetEmail(t *testing.T) {
} }
func TestServer_ResendEmailCode(t *testing.T) { func TestServer_ResendEmailCode(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId() verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId()
@ -245,6 +249,8 @@ func TestServer_ResendEmailCode(t *testing.T) {
} }
func TestServer_VerifyEmail(t *testing.T) { func TestServer_VerifyEmail(t *testing.T) {
t.Parallel()
userResp := Instance.CreateHumanUser(CTX) userResp := Instance.CreateHumanUser(CTX)
tests := []struct { tests := []struct {
name string name string

View File

@ -15,6 +15,8 @@ import (
) )
func TestServer_AddOTPSMS(t *testing.T) { func TestServer_AddOTPSMS(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID) Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
@ -121,6 +123,8 @@ func TestServer_AddOTPSMS(t *testing.T) {
} }
func TestServer_RemoveOTPSMS(t *testing.T) { func TestServer_RemoveOTPSMS(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID) Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
@ -187,6 +191,8 @@ func TestServer_RemoveOTPSMS(t *testing.T) {
} }
func TestServer_AddOTPEmail(t *testing.T) { func TestServer_AddOTPEmail(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID) Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
@ -295,6 +301,8 @@ func TestServer_AddOTPEmail(t *testing.T) {
} }
func TestServer_RemoveOTPEmail(t *testing.T) { func TestServer_RemoveOTPEmail(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID) Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)

View File

@ -18,6 +18,8 @@ import (
) )
func TestServer_RegisterPasskey(t *testing.T) { func TestServer_RegisterPasskey(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
reg, err := Client.CreatePasskeyRegistrationLink(CTX, &user.CreatePasskeyRegistrationLinkRequest{ reg, err := Client.CreatePasskeyRegistrationLink(CTX, &user.CreatePasskeyRegistrationLinkRequest{
UserId: userID, UserId: userID,
@ -138,6 +140,8 @@ func TestServer_RegisterPasskey(t *testing.T) {
} }
func TestServer_VerifyPasskeyRegistration(t *testing.T) { func TestServer_VerifyPasskeyRegistration(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
reg, err := Client.CreatePasskeyRegistrationLink(CTX, &user.CreatePasskeyRegistrationLinkRequest{ reg, err := Client.CreatePasskeyRegistrationLink(CTX, &user.CreatePasskeyRegistrationLinkRequest{
UserId: userID, UserId: userID,
@ -226,6 +230,8 @@ func TestServer_VerifyPasskeyRegistration(t *testing.T) {
} }
func TestServer_CreatePasskeyRegistrationLink(t *testing.T) { func TestServer_CreatePasskeyRegistrationLink(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
type args struct { type args struct {

View File

@ -17,6 +17,8 @@ import (
) )
func TestServer_RequestPasswordReset(t *testing.T) { func TestServer_RequestPasswordReset(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
tests := []struct { tests := []struct {
@ -104,6 +106,8 @@ func TestServer_RequestPasswordReset(t *testing.T) {
} }
func TestServer_SetPassword(t *testing.T) { func TestServer_SetPassword(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.SetPasswordRequest req *user.SetPasswordRequest

View File

@ -19,6 +19,8 @@ import (
) )
func TestServer_SetPhone(t *testing.T) { func TestServer_SetPhone(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
tests := []struct { tests := []struct {
@ -122,6 +124,8 @@ func TestServer_SetPhone(t *testing.T) {
} }
func TestServer_ResendPhoneCode(t *testing.T) { func TestServer_ResendPhoneCode(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId() verifiedUserID := Instance.CreateHumanUserVerified(CTX, Instance.DefaultOrg.Id, fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())).GetUserId()
@ -196,6 +200,8 @@ func TestServer_ResendPhoneCode(t *testing.T) {
} }
func TestServer_VerifyPhone(t *testing.T) { func TestServer_VerifyPhone(t *testing.T) {
t.Parallel()
userResp := Instance.CreateHumanUser(CTX) userResp := Instance.CreateHumanUser(CTX)
tests := []struct { tests := []struct {
name string name string
@ -248,6 +254,8 @@ func TestServer_VerifyPhone(t *testing.T) {
} }
func TestServer_RemovePhone(t *testing.T) { func TestServer_RemovePhone(t *testing.T) {
t.Parallel()
userResp := Instance.CreateHumanUser(CTX) userResp := Instance.CreateHumanUser(CTX)
failResp := Instance.CreateHumanUserNoPhone(CTX) failResp := Instance.CreateHumanUserNoPhone(CTX)
otherUser := Instance.CreateHumanUser(CTX).GetUserId() otherUser := Instance.CreateHumanUser(CTX).GetUserId()

View File

@ -28,6 +28,8 @@ func detailsV2ToV2beta(obj *object.Details) *object_v2beta.Details {
} }
func TestServer_GetUserByID(t *testing.T) { func TestServer_GetUserByID(t *testing.T) {
t.Parallel()
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
type args struct { type args struct {
ctx context.Context ctx context.Context
@ -196,6 +198,8 @@ func TestServer_GetUserByID(t *testing.T) {
} }
func TestServer_GetUserByID_Permission(t *testing.T) { func TestServer_GetUserByID_Permission(t *testing.T) {
t.Parallel()
timeNow := time.Now().UTC() timeNow := time.Now().UTC()
newOrgOwnerEmail := fmt.Sprintf("%d@permission.get.com", timeNow.UnixNano()) newOrgOwnerEmail := fmt.Sprintf("%d@permission.get.com", timeNow.UnixNano())
newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetHuman%d", time.Now().UnixNano()), newOrgOwnerEmail)
@ -338,6 +342,8 @@ type userAttr struct {
} }
func TestServer_ListUsers(t *testing.T) { func TestServer_ListUsers(t *testing.T) {
t.Parallel()
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListUsersOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListUsersOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
userResp := Instance.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listusers.com", time.Now().UnixNano())) userResp := Instance.CreateHumanUserVerified(IamCTX, orgResp.OrganizationId, fmt.Sprintf("%d@listusers.com", time.Now().UnixNano()))
type args struct { type args struct {

View File

@ -18,6 +18,8 @@ import (
) )
func TestServer_RegisterTOTP(t *testing.T) { func TestServer_RegisterTOTP(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID) Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
@ -104,6 +106,8 @@ func TestServer_RegisterTOTP(t *testing.T) {
} }
func TestServer_VerifyTOTPRegistration(t *testing.T) { func TestServer_VerifyTOTPRegistration(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID) Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)
@ -212,6 +216,8 @@ func TestServer_VerifyTOTPRegistration(t *testing.T) {
} }
func TestServer_RemoveTOTP(t *testing.T) { func TestServer_RemoveTOTP(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID) Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)

View File

@ -17,6 +17,8 @@ import (
) )
func TestServer_RegisterU2F(t *testing.T) { func TestServer_RegisterU2F(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
otherUser := Instance.CreateHumanUser(CTX).GetUserId() otherUser := Instance.CreateHumanUser(CTX).GetUserId()
@ -106,6 +108,8 @@ func TestServer_RegisterU2F(t *testing.T) {
} }
func TestServer_VerifyU2FRegistration(t *testing.T) { func TestServer_VerifyU2FRegistration(t *testing.T) {
t.Parallel()
userID := Instance.CreateHumanUser(CTX).GetUserId() userID := Instance.CreateHumanUser(CTX).GetUserId()
Instance.RegisterUserPasskey(CTX, userID) Instance.RegisterUserPasskey(CTX, userID)
_, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID) _, sessionToken, _, _ := Instance.CreateVerifiedWebAuthNSession(t, CTX, userID)

View File

@ -50,6 +50,8 @@ func TestMain(m *testing.M) {
} }
func TestServer_AddHumanUser(t *testing.T) { func TestServer_AddHumanUser(t *testing.T) {
t.Parallel()
idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)
type args struct { type args struct {
ctx context.Context ctx context.Context
@ -631,6 +633,8 @@ func TestServer_AddHumanUser(t *testing.T) {
} }
func TestServer_AddHumanUser_Permission(t *testing.T) { func TestServer_AddHumanUser_Permission(t *testing.T) {
t.Parallel()
newOrgOwnerEmail := fmt.Sprintf("%d@permission.com", time.Now().UnixNano()) newOrgOwnerEmail := fmt.Sprintf("%d@permission.com", time.Now().UnixNano())
newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("AddHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("AddHuman%d", time.Now().UnixNano()), newOrgOwnerEmail)
type args struct { type args struct {
@ -824,6 +828,8 @@ func TestServer_AddHumanUser_Permission(t *testing.T) {
} }
func TestServer_UpdateHumanUser(t *testing.T) { func TestServer_UpdateHumanUser(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.UpdateHumanUserRequest req *user.UpdateHumanUserRequest
@ -1180,6 +1186,8 @@ func TestServer_UpdateHumanUser(t *testing.T) {
} }
func TestServer_UpdateHumanUser_Permission(t *testing.T) { func TestServer_UpdateHumanUser_Permission(t *testing.T) {
t.Parallel()
newOrgOwnerEmail := fmt.Sprintf("%d@permission.update.com", time.Now().UnixNano()) newOrgOwnerEmail := fmt.Sprintf("%d@permission.update.com", time.Now().UnixNano())
newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("UpdateHuman%d", time.Now().UnixNano()), newOrgOwnerEmail) newOrg := Instance.CreateOrganization(IamCTX, fmt.Sprintf("UpdateHuman%d", time.Now().UnixNano()), newOrgOwnerEmail)
newUserID := newOrg.CreatedAdmins[0].GetUserId() newUserID := newOrg.CreatedAdmins[0].GetUserId()
@ -1263,6 +1271,8 @@ func TestServer_UpdateHumanUser_Permission(t *testing.T) {
} }
func TestServer_LockUser(t *testing.T) { func TestServer_LockUser(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.LockUserRequest req *user.LockUserRequest
@ -1371,6 +1381,8 @@ func TestServer_LockUser(t *testing.T) {
} }
func TestServer_UnLockUser(t *testing.T) { func TestServer_UnLockUser(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.UnlockUserRequest req *user.UnlockUserRequest
@ -1479,6 +1491,8 @@ func TestServer_UnLockUser(t *testing.T) {
} }
func TestServer_DeactivateUser(t *testing.T) { func TestServer_DeactivateUser(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.DeactivateUserRequest req *user.DeactivateUserRequest
@ -1587,6 +1601,8 @@ func TestServer_DeactivateUser(t *testing.T) {
} }
func TestServer_ReactivateUser(t *testing.T) { func TestServer_ReactivateUser(t *testing.T) {
t.Parallel()
type args struct { type args struct {
ctx context.Context ctx context.Context
req *user.ReactivateUserRequest req *user.ReactivateUserRequest
@ -1695,6 +1711,8 @@ func TestServer_ReactivateUser(t *testing.T) {
} }
func TestServer_DeleteUser(t *testing.T) { func TestServer_DeleteUser(t *testing.T) {
t.Parallel()
projectResp, err := Instance.CreateProject(CTX) projectResp, err := Instance.CreateProject(CTX)
require.NoError(t, err) require.NoError(t, err)
type args struct { type args struct {
@ -1794,6 +1812,8 @@ func TestServer_DeleteUser(t *testing.T) {
} }
func TestServer_AddIDPLink(t *testing.T) { func TestServer_AddIDPLink(t *testing.T) {
t.Parallel()
idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)
type args struct { type args struct {
ctx context.Context ctx context.Context
@ -1874,6 +1894,8 @@ func TestServer_AddIDPLink(t *testing.T) {
} }
func TestServer_StartIdentityProviderIntent(t *testing.T) { func TestServer_StartIdentityProviderIntent(t *testing.T) {
t.Parallel()
idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id) idpResp := Instance.AddGenericOAuthProvider(IamCTX, Instance.DefaultOrg.Id)
orgIdpID := Instance.AddOrgGenericOAuthProvider(CTX, Instance.DefaultOrg.Id) orgIdpID := Instance.AddOrgGenericOAuthProvider(CTX, Instance.DefaultOrg.Id)
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("NotDefaultOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())) orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("NotDefaultOrg%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
@ -2138,6 +2160,8 @@ func TestServer_StartIdentityProviderIntent(t *testing.T) {
/* /*
func TestServer_RetrieveIdentityProviderIntent(t *testing.T) { func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
t.Parallel()
idpID := Instance.AddGenericOAuthProvider(t, CTX) idpID := Instance.AddGenericOAuthProvider(t, CTX)
intentID := Instance.CreateIntent(t, CTX, idpID) intentID := Instance.CreateIntent(t, CTX, idpID)
successfulID, token, changeDate, sequence := Instance.CreateSuccessfulOAuthIntent(t, CTX, idpID.Id, "", "id") successfulID, token, changeDate, sequence := Instance.CreateSuccessfulOAuthIntent(t, CTX, idpID.Id, "", "id")
@ -2398,6 +2422,8 @@ func TestServer_RetrieveIdentityProviderIntent(t *testing.T) {
*/ */
func TestServer_ListAuthenticationMethodTypes(t *testing.T) { func TestServer_ListAuthenticationMethodTypes(t *testing.T) {
t.Parallel()
userIDWithoutAuth := Instance.CreateHumanUser(CTX).GetUserId() userIDWithoutAuth := Instance.CreateHumanUser(CTX).GetUserId()
userIDWithPasskey := Instance.CreateHumanUser(CTX).GetUserId() userIDWithPasskey := Instance.CreateHumanUser(CTX).GetUserId()

View File

@ -590,7 +590,7 @@ func (s *Server) checkIntentToken(token string, intentID string) error {
} }
func (s *Server) ListAuthenticationMethodTypes(ctx context.Context, req *user.ListAuthenticationMethodTypesRequest) (*user.ListAuthenticationMethodTypesResponse, error) { func (s *Server) ListAuthenticationMethodTypes(ctx context.Context, req *user.ListAuthenticationMethodTypesRequest) (*user.ListAuthenticationMethodTypesResponse, error) {
authMethods, err := s.query.ListUserAuthMethodTypes(ctx, req.GetUserId(), true) authMethods, err := s.query.ListUserAuthMethodTypes(ctx, req.GetUserId(), true, false, "")
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -72,7 +72,7 @@ func (l *Login) handleMailVerification(w http.ResponseWriter, r *http.Request) {
} }
func (l *Login) checkUserNoFirstFactor(ctx context.Context, userID string) bool { func (l *Login) checkUserNoFirstFactor(ctx context.Context, userID string) bool {
authMethods, err := l.query.ListUserAuthMethodTypes(setUserContext(ctx, userID, ""), userID, false) authMethods, err := l.query.ListUserAuthMethodTypes(setUserContext(ctx, userID, ""), userID, false, false, "")
if err != nil { if err != nil {
logging.WithFields("userID", userID).OnError(err).Warn("unable to load user's auth methods for mail verification") logging.WithFields("userID", userID).OnError(err).Warn("unable to load user's auth methods for mail verification")
return false return false

View File

@ -259,6 +259,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: Пол GenderLabel: Пол
Female: Женски пол Female: Женски пол
Male: Мъжки Male: Мъжки
@ -299,6 +300,7 @@ ExternalRegistrationUserOverview:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
TosAndPrivacyLabel: Правила и условия TosAndPrivacyLabel: Правила и условия
TosConfirm: Приемам TosConfirm: Приемам
TosLinkText: TOS TosLinkText: TOS
@ -368,6 +370,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
DeviceAuth: DeviceAuth:
Title: Упълномощаване на устройството Title: Упълномощаване на устройството
UserCode: UserCode:

View File

@ -263,6 +263,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: Pohlaví GenderLabel: Pohlaví
Female: Žena Female: Žena
Male: Muž Male: Muž
@ -304,6 +305,7 @@ ExternalRegistrationUserOverview:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
TosAndPrivacyLabel: Obchodní podmínky TosAndPrivacyLabel: Obchodní podmínky
TosConfirm: Souhlasím s TosConfirm: Souhlasím s
TosLinkText: obchodními podmínkami TosLinkText: obchodními podmínkami
@ -379,6 +381,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
DeviceAuth: DeviceAuth:
Title: Autorizace zařízení Title: Autorizace zařízení
UserCode: UserCode:

View File

@ -262,6 +262,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: Geschlecht GenderLabel: Geschlecht
Female: weiblich Female: weiblich
Male: männlich Male: männlich
@ -303,6 +304,7 @@ ExternalRegistrationUserOverview:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
TosAndPrivacyLabel: Allgemeine Geschäftsbedingungen und Datenschutz TosAndPrivacyLabel: Allgemeine Geschäftsbedingungen und Datenschutz
TosConfirm: Ich akzeptiere die TosConfirm: Ich akzeptiere die
TosLinkText: AGB TosLinkText: AGB
@ -378,6 +380,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
DeviceAuth: DeviceAuth:
Title: Gerät verbinden Title: Gerät verbinden
UserCode: UserCode:

View File

@ -263,6 +263,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: Gender GenderLabel: Gender
Female: Female Female: Female
Male: Male Male: Male
@ -304,6 +305,7 @@ ExternalRegistrationUserOverview:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
TosAndPrivacyLabel: Terms and conditions TosAndPrivacyLabel: Terms and conditions
TosConfirm: I accept the TosConfirm: I accept the
TosLinkText: TOS TosLinkText: TOS
@ -379,6 +381,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
DeviceAuth: DeviceAuth:
Title: Device Authorization Title: Device Authorization
UserCode: UserCode:

View File

@ -263,6 +263,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: Género GenderLabel: Género
Female: Mujer Female: Mujer
Male: Hombre Male: Hombre
@ -304,6 +305,7 @@ ExternalRegistrationUserOverview:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
TosAndPrivacyLabel: Términos y condiciones TosAndPrivacyLabel: Términos y condiciones
TosConfirm: Acepto los TosConfirm: Acepto los
TosLinkText: TDS TosLinkText: TDS
@ -379,6 +381,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
Footer: Footer:
PoweredBy: Powered By PoweredBy: Powered By

View File

@ -263,6 +263,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: Genre GenderLabel: Genre
Female: Femme Female: Femme
Male: Homme Male: Homme
@ -304,6 +305,7 @@ ExternalRegistrationUserOverview:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
TosAndPrivacyLabel: Termes et conditions TosAndPrivacyLabel: Termes et conditions
TosConfirm: J'accepte les TosConfirm: J'accepte les
TosLinkText: TOS TosLinkText: TOS
@ -379,6 +381,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
DeviceAuth: DeviceAuth:
Title: Autorisation de l'appareil Title: Autorisation de l'appareil

View File

@ -0,0 +1,477 @@
Login:
Title: Üdv újra itt!
Description: Add meg a bejelentkezési adataidat.
TitleLinking: Felhasználó összekapcsolása bejelentkezéssel
DescriptionLinking: Add meg a bejelentkezési adataidat a külső felhasználó összekapcsolásához.
LoginNameLabel: Bejelentkezési név
UsernamePlaceHolder: felhasználónév
LoginnamePlaceHolder: felhasználónév@domain
ExternalUserDescription: Jelentkezz be külső felhasználóval.
MustBeMemberOfOrg: A felhasználónak az {{.OrgName}} szervezet tagjának kell lennie.
RegisterButtonText: Regisztráció
NextButtonText: Következő
LDAP:
Title: Bejelentkezés
Description: Add meg a bejelentkezési adataidat.
LoginNameLabel: Bejelentkezési név
PasswordLabel: Jelszó
NextButtonText: Következő
SelectAccount:
Title: Fiók kiválasztása
Description: Használd a fiókodat
TitleLinking: Fiók kiválasztása a felhasználó összekapcsolásához
DescriptionLinking: Válaszd ki a fiókodat, hogy összekapcsold a külső felhasználóddal.
OtherUser: Másik felhasználó
SessionState0: aktív
SessionState1: Kijelentkezve
MustBeMemberOfOrg: A felhasználónak a {{.OrgName}} szervezet tagjának kell lennie.
Password:
Title: Jelszó
Description: Add meg a bejelentkezési adataidat.
PasswordLabel: Jelszó
MinLength: Legalább
MinLengthp2: karakter hosszúnak kell lennie.
MaxLength: Kevesebb, mint 70 karakter hosszúnak kell lennie.
HasUppercase: Tartalmaznia kell egy nagybetűt.
HasLowercase: Tartalmaznia kell egy kisbetűt.
HasNumber: Tartalmaznia kell egy számot.
HasSymbol: Tartalmaznia kell egy szimbólumot.
Confirmation: A jelszó megerősítése egyezik.
ResetLinkText: Jelszó visszaállítása
BackButtonText: Vissza
NextButtonText: Következő
UsernameChange:
Title: Felhasználónév megváltoztatása
Description: Állítsd be az új felhasználóneved
UsernameLabel: Felhasználónév
CancelButtonText: Mégse
NextButtonText: Következő
UsernameChangeDone:
Title: Felhasználónév megváltoztatva
Description: A felhasználóneved sikeresen megváltozott.
NextButtonText: Következő
InitPassword:
Title: Jelszó beállítása
Description: Kaptál egy kódot, amit az alábbi űrlapon meg kell adnod az új jelszavad beállításához.
CodeLabel: Kód
NewPasswordLabel: Új jelszó
NewPasswordConfirmLabel: Jelszó megerősítése
ResendButtonText: Kód újraküldése
NextButtonText: Következő
InitPasswordDone:
Title: Jelszó beállítva
Description: A jelszót sikeresen beállítottad
NextButtonText: Következő
CancelButtonText: Mégse
InitUser:
Title: Felhasználó aktiválása
Description: Igazold az e-mailed az alábbi kóddal és állítsd be a jelszavad.
CodeLabel: Kód
NewPasswordLabel: Új jelszó
NewPasswordConfirm: Jelszó megerősítése
NextButtonText: Következő
ResendButtonText: Kód újraküldése
InitUserDone:
Title: Felhasználó aktiválva
Description: Az email ellenőrzése sikeres volt és a jelszó beállítása megtörtént
NextButtonText: Következő
CancelButtonText: Mégsem
InviteUser:
Title: Felhasználó aktiválása
Description: Ellenőrizd az emailed az alábbi kóddal és állítsd be a jelszavad.
CodeLabel: Kód
NewPasswordLabel: Új jelszó
NewPasswordConfirm: Jelszó megerősítése
NextButtonText: Következő
ResendButtonText: Kód újraküldése
InitMFAPrompt:
Title: 2-faktoros beállítás
Description: A 2-faktoros hitelesítés további biztonságot nyújt a felhasználói fiókodhoz. Ez biztosítja, hogy csak te férhetsz hozzá a fiókodhoz.
Provider0: Hitelesítő alkalmazás (pl. Google/Microsoft Authenticator, Authy)
Provider1: Eszközfüggő (pl. FaceID, Windows Hello, Ujjlenyomat)
Provider3: OTP SMS
Provider4: OTP Email
NextButtonText: Következő
SkipButtonText: Kihagyás
InitMFAOTP:
Title: 2-faktoros ellenőrzés
Description: Hozd létre a 2-faktorodat. Töltsd le az authenticator appot, ha még nincs.
OTPDescription: Olvasd be a kódot az authenticator appoddal (pl. Google/Microsoft Authenticator, Authy), vagy másold be a titkos kódot és írd be a generált kódot alulra.
SecretLabel: Titkos
CodeLabel: Kód
NextButtonText: Következő
CancelButtonText: Mégsem
InitMFAOTPSMS:
Title: Kétfaktoros hitelesítés
DescriptionPhone: Hozd létre a kétfaktoros hitelesítést. Add meg a telefonszámod a hitelesítéshez.
DescriptionCode: Hozd létre a kétfaktoros hitelesítést. Add meg a kapott kódot a telefonszámod hitelesítéséhez.
PhoneLabel: Telefon
CodeLabel: Kód
EditButtonText: Szerkesztés
ResendButtonText: Kód újraküldése
NextButtonText: Tovább
InitMFAU2F:
Title: Biztonsági kulcs hozzáadása
Description: A biztonsági kulcs egy olyan hitelesítési módszer, amely beépíthető a telefonodba, használható Bluetooth-szal vagy közvetlenül a számítógéped USB-portjához csatlakoztatható.
TokenNameLabel: A biztonsági kulcs / eszköz neve
NotSupported: A WebAuthN nem támogatott a böngésződben. Kérlek, győződj meg róla, hogy a legújabb verziót használod, vagy használj egy másik böngészőt (pl. Chrome, Safari, Firefox)
RegisterTokenButtonText: Biztonsági kulcs hozzáadása
ErrorRetry: Próbáld újra, hozz létre egy új kihívást, vagy válassz egy másik módszert.
InitMFADone:
Title: 2-faktoros hitelesítés igazolva
Description: Szuper! Sikeresen beállítottad a 2-faktoros hitelesítést, és így sokkal biztonságosabbá tetted a fiókodat. A faktort minden bejelentkezéskor meg kell adni.
NextButtonText: Következő
CancelButtonText: Mégse
MFAProvider:
Provider0: Hitelesítő alkalmazás (pl. Google/Microsoft Authenticator, Authy)
Provider1: Eszközfüggő (pl. FaceID, Windows Hello, Ujjlenyomat)
Provider3: OTP SMS
Provider4: OTP Email
ChooseOther: vagy válassz egy másik lehetőséget
VerifyMFAOTP:
Title: Kétlépcsős azonosítás ellenőrzése
Description: Ellenőrizd a második azonosítódat
CodeLabel: Kód
NextButtonText: Következő
VerifyOTP:
Title: Kétlépcsős azonosítás ellenőrzése
Description: Ellenőrizd a második azonosítódat
CodeLabel: Kód
ResendButtonText: Kód újraküldése
NextButtonText: Következő
VerifyMFAU2F:
Title: Kétlépcsős hitelesítés
Description: Hitelesítsd a kétlépcsős ellenőrzést a regisztrált eszközzel (például FaceID, Windows Hello, ujjlenyomat)
NotSupported: A böngésződ nem támogatja a WebAuthN-t. Győződj meg róla, hogy a legújabb verziót használod, vagy válts egy támogatott böngészőre (Chrome, Safari, Firefox)
ErrorRetry: Próbáld újra, készíts új kérést vagy válassz másik módszert.
ValidateTokenButtonText: Kétlépcsős hitelesítés ellenőrzése
Passwordless:
Title: Jelszó nélküli bejelentkezés
Description: Jelentkezz be az eszközöd által biztosított hitelesítési módszerekkel, mint például FaceID, Windows Hello vagy ujjlenyomat.
NotSupported: A böngésződ nem támogatja a WebAuthN-t. Kérlek, győződj meg róla, hogy naprakész, vagy használj másikat (például Chrome, Safari, Firefox)
ErrorRetry: Próbáld újra, hozz létre egy új kihívást vagy válassz egy másik módszert.
LoginWithPwButtonText: Bejelentkezés jelszóval
ValidateTokenButtonText: Bejelentkezés jelszó nélküli módszerrel
PasswordlessPrompt:
Title: Jelszó nélküli beállítás
Description: Szeretnéd beállítani a jelszó nélküli bejelentkezést? (Eszközöd hitelesítési módszerei, például FaceID, Windows Hello vagy ujjlenyomat)
DescriptionInit: Be kell állítanod a jelszó nélküli bejelentkezést. Használd a kapott linket az eszközöd regisztrálásához.
PasswordlessButtonText: Használd a jelszó nélküli módszert
NextButtonText: Következő
SkipButtonText: Kihagy
PasswordlessRegistration:
Title: Jelszó nélküli beállítás
Description: Add meg az azonosításodat egy név megadásával (pl. MyMobilePhone, MacBook, stb.), majd kattints a lentebb található 'Register passwordless' gombra.
TokenNameLabel: Az eszköz neve
NotSupported: A böngésződ nem támogatja a WebAuthN-t. Kérjük, győződj meg róla, hogy naprakész, vagy használj egy másik böngészőt (pl. Chrome, Safari, Firefox)
RegisterTokenButtonText: Register passwordless
ErrorRetry: Próbáld újra, hozz létre egy új kihívást, vagy válassz egy másik módszert.
PasswordlessRegistrationDone:
Title: Passwordless beállítás
Description: Az eszközt a passwordless sikeresen hozzáadtad.
DescriptionClose: Most bezárhatod ezt az ablakot.
NextButtonText: Következő
CancelButtonText: Mégse
PasswordChange:
Title: Jelszó megváltoztatása
Description: Változtasd meg a jelszavad. Add meg a régi és az új jelszavad.
ExpiredDescription: A jelszavad lejárt, és meg kell változtatnod. Add meg a régi és az új jelszavad.
OldPasswordLabel: Régi jelszó
NewPasswordLabel: Új jelszó
NewPasswordConfirmLabel: Jelszó megerősítése
CancelButtonText: Mégse
NextButtonText: Következő
Footer: Lábléc
PasswordChangeDone:
Title: Jelszó megváltoztatása
Description: A jelszavad sikeresen megváltozott.
NextButtonText: Tovább
PasswordResetDone:
Title: Jelszó-visszaállítási link elküldve
Description: Ellenőrizd az emailjeidet a jelszó visszaállításához.
NextButtonText: Tovább
EmailVerification:
Title: E-mail megerősítés
Description: Küldtünk neked egy e-mailt a címed megerősítéséhez. Kérjük, írd be a kódot az alábbi űrlapba.
CodeLabel: Kód
NextButtonText: Tovább
ResendButtonText: Kód újraküldése
EmailVerificationDone:
Title: E-mail ellenőrzés
Description: Az e-mail címedet sikeresen ellenőriztük.
NextButtonText: Következő
CancelButtonText: Mégse
LoginButtonText: Bejelentkezés
RegisterOption:
Title: Regisztrációs lehetőségek
Description: Válaszd ki, hogyan szeretnél regisztrálni
RegisterUsernamePasswordButtonText: Felhasználónévvel és jelszóval
ExternalLoginDescription: vagy regisztrálj egy külső felhasználóval
LoginButtonText: Bejelentkezés
RegistrationUser:
Title: Regisztráció
Description: Add meg az adataidat. Az email címed lesz a bejelentkezési neved.
DescriptionOrgRegister: Add meg az adataidat.
EmailLabel: E-mail
UsernameLabel: Felhasználónév
FirstnameLabel: Keresztnév
LastnameLabel: Vezetéknév
LanguageLabel: Nyelv
German: Német
English: Angol
Italian: Olasz
French: Francia
Chinese: Egyszerűsített Kínai
Polish: Lengyel
Japanese: Japán
Spanish: Spanyol
Bulgarian: Bolgár
Portuguese: Portugál
Macedonian: Macedón
Czech: Cseh
Russian: Orosz
Dutch: Holland
Swedish: Svéd
Indonesian: Indonéz
Hungarian: Magyar
GenderLabel: Nem
Female:
Male: Férfi
Diverse: diverz / X
PasswordLabel: Jelszó
PasswordConfirmLabel: Jelszó megerősítése
TosAndPrivacyLabel: Felhasználási feltételek
TosConfirm: Elfogadom a
TosLinkText: Általános Szerződési Feltételeket (ÁSZF)
PrivacyConfirm: Elfogadom a
PrivacyLinkText: adatvédelmi szabályzatot
ExternalLogin: vagy regisztrálj külső felhasználóként
BackButtonText: Bejelentkezés
NextButtonText: Következő
ExternalRegistrationUserOverview:
Title: Külső felhasználói regisztráció
Description: Átvettük a felhasználói adataidat a kiválasztott szolgáltatótól. Most megváltoztathatod vagy kiegészítheted őket.
EmailLabel: E-mail
UsernameLabel: Felhasználónév
FirstnameLabel: Keresztnév
LastnameLabel: Vezetéknév
NicknameLabel: Becenév
PhoneLabel: Telefonszám
LanguageLabel: Nyelv
German: Német
English: Angol
Italian: Olasz
French: Francia
Chinese: Egyszerűsített kínai
Polish: Lengyel
Japanese: Japán
Spanish: Spanyol
Bulgarian: Bolgár
Portuguese: Portugál
Macedonian: Macedón
Czech: Cseh
Russian: Orosz
Dutch: Holland
Swedish: Svéd
Indonesian: Indonéz
Hungarian: Magyar
TosAndPrivacyLabel: Felhasználási feltételek
TosConfirm: Elfogadom a
TosLinkText: TOS
PrivacyConfirm: Elfogadom a
PrivacyLinkText: adatvédelmi nyilatkozatot
ExternalLogin: vagy regisztrálj külső felhasználóval
BackButtonText: Elutasít
NextButtonText: Mentés
RegistrationOrg:
Title: Szervezet regisztráció
Description: Add meg a szervezet nevét és a felhasználói adatokat.
OrgNameLabel: Szervezet neve
EmailLabel: E-mail
UsernameLabel: Felhasználónév
FirstnameLabel: Keresztnév
LastnameLabel: Vezetéknév
PasswordLabel: Jelszó
PasswordConfirmLabel: Jelszó megerősítése
TosAndPrivacyLabel: Felhasználási feltételek
TosConfirm: Elfogadom a
TosLinkText: TOS-t
PrivacyConfirm: Elfogadom a
PrivacyLinkText: adatvédelmi irányelveket
SaveButtonText: Szervezet létrehozása
LoginSuccess:
Title: Sikeres bejelentkezés
AutoRedirectDescription: Automatikusan vissza leszel irányítva az alkalmazásodhoz. Ha nem, kattints az alábbi gombra. Ezután bezárhatod az ablakot.
RedirectedDescription: Most már bezárhatod ezt az ablakot.
NextButtonText: Következő
LogoutDone:
Title: Kijelentkezve
Description: Sikeresen kijelentkeztél.
LoginButtonText: Bejelentkezés
LinkingUserPrompt:
Title: Meglévő felhasználó megtalálva
Description: Szeretnéd összekapcsolni a meglévő fiókodat
LinkButtonText: Összekapcsolás
OtherButtonText: Egyéb lehetőségek
LinkingUsersDone:
Title: Felhasználó összekapcsolása
Description: Felhasználó összekapcsolva.
CancelButtonText: Mégse
NextButtonText: Következő
ExternalNotFound:
Title: Külső felhasználó nem található
Description: Külső felhasználó nem található. Szeretnéd összekapcsolni a felhasználódat vagy automatikusan regisztrálni egy újat?
LinkButtonText: Összekapcsolás
AutoRegisterButtonText: Regisztráció
TosAndPrivacyLabel: Felhasználási feltételek
TosConfirm: Elfogadom a
TosLinkText: SZF-et
PrivacyConfirm: Elfogadom a
PrivacyLinkText: adatvédelmi szabályzatot
German: Német
English: Angol
Italian: Olasz
French: Francia
Chinese: Egyszerűsített kínai
Polish: Lengyel
Japanese: Japán
Spanish: Spanyol
Bulgarian: Bolgár
Portuguese: Portugál
Macedonian: Macedón
Czech: Cseh
Russian: Orosz
Dutch: Holland
Swedish: Svéd
Indonesian: Indonéz
Hungarian: Magyar
DeviceAuth:
Title: Eszköz engedélyezése
UserCode:
Label: Felhasználói kód
Description: Add meg az eszközön megjelenített felhasználói kódot.
ButtonNext: Következő
Action:
Description: Eszköz hozzáférés engedélyezése.
GrantDevice: az eszközhöz való hozzáférést engedélyezed
AccessToScopes: hozzáférés az alábbi tartományokhoz
Button:
Allow: Engedélyez
Deny: Megtagad
Done:
Description: Kész.
Approved: Az eszköz engedélyezése jóváhagyva. Most visszatérhetsz az eszközhöz.
Denied: Az eszköz engedélyezése megtagadva. Most visszatérhetsz az eszközhöz.
Footer:
PoweredBy: Működteti
Tos: Felhasználási feltételek
PrivacyPolicy: Adatvédelmi irányelvek
Help: Segítség
SupportEmail: Támogatási e-mail
SignIn: Jelentkezz be a {{.Provider}} segítségével
Errors:
Internal: Belső hiba történt
AuthRequest:
NotFound: Nem található hitelesítési kérés
UserAgentNotCorresponding: A felhasználói ügynök nem egyezik
UserAgentNotFound: Felhasználói ügynök azonosító nem található
TokenNotFound: Token nem található
RequestTypeNotSupported: A kérés típusa nem támogatott
MissingParameters: Kötelező paraméterek hiányoznak
User:
NotFound: A felhasználó nem található
AlreadyExists: A felhasználó már létezik
Inactive: A felhasználó inaktív
NotFoundOnOrg: A felhasználó nem található a kiválasztott szervezetben
NotAllowedOrg: A felhasználó nem tagja a szükséges szervezetnek
NotMatchingUserID: A felhasználó és az authrequest-ben szereplő felhasználó nem egyezik
UserIDMissing: A felhasználói azonosító üres
Invalid: Érvénytelen felhasználói adatok
DomainNotAllowedAsUsername: A domain már foglalt és nem használható
NotAllowedToLink: A felhasználó számára nem engedélyezett a külső bejelentkezési szolgáltatóval való kapcsolat
Profile:
NotFound: Profil nem található
NotChanged: Profil nem változott
Empty: Profil üres
FirstNameEmpty: A profilban a keresztnév üres
LastNameEmpty: A profilban a vezetéknév üres
IDMissing: Hiányzik a profil azonosító
Email:
NotFound: Email nem található
Invalid: Érvénytelen email
AlreadyVerified: Az email már ellenőrizve van
NotChanged: Az email nem változott
Empty: Az email üres
IDMissing: Az email azonosító hiányzik
Phone:
NotFound: A telefon nem található
Invalid: A telefon érvénytelen
AlreadyVerified: A telefon már ellenőrizve van
Empty: A telefon üres
NotChanged: A telefon nem változott
Address:
NotFound: A cím nem található
NotChanged: A cím nem változott
Username:
AlreadyExists: A felhasználónév már foglalt
Reserved: A felhasználónév már foglalt
Empty: A felhasználónév üres
Password:
ConfirmationWrong: A jelszó megerősítése helytelen
Empty: A jelszó üres
Invalid: A jelszó érvénytelen
InvalidAndLocked: A jelszó érvénytelen és a felhasználó zárolva van, vedd fel a kapcsolatot az adminisztrátoroddal.
NotChanged: Az új jelszó nem lehet azonos a jelenlegi jelszavaddal
UsernameOrPassword:
Invalid: A felhasználónév vagy a jelszó érvénytelen
PasswordComplexityPolicy:
NotFound: A jelszóházirend nem található
MinLength: A jelszó túl rövid
HasLower: A jelszónak kisbetűt kell tartalmaznia
HasUpper: A jelszónak nagybetűt kell tartalmaznia
HasNumber: A jelszónak számot kell tartalmaznia
HasSymbol: A jelszónak szimbólumot kell tartalmaznia
Code:
Expired: A kód lejárt
Invalid: A kód érvénytelen
Empty: A kód üres
CryptoCodeNil: A kriptográfiai kód nil
NotFound: Nem találom a kódot
GeneratorAlgNotSupported: Nem támogatott generáló algoritmus
EmailVerify:
UserIDEmpty: A felhasználói azonosító üres
ExternalData:
CouldNotRead: A külső adatokat nem sikerült helyesen beolvasni
MFA:
NoProviders: Nincsenek elérhető többfaktoros szolgáltatók
OTP:
AlreadyReady: A többfaktoros OTP (OneTimePassword) már be van állítva
NotExisting: A többfaktoros OTP (OneTimePassword) nem létezik
InvalidCode: Érvénytelen kód
NotReady: A többfaktoros OTP (OneTimePassword) nem áll készen
Locked: A felhasználó zárolva van
SomethingWentWrong: Valami elromlott
NotActive: A felhasználó nem aktív
ExternalIDP:
IDPTypeNotImplemented: Az IDP típus nincs megvalósítva
NotAllowed: Az külső bejelentkezési szolgáltató nem engedélyezett
IDPConfigIDEmpty: Az azonosítószolgáltató ID üres
ExternalUserIDEmpty: A külső felhasználói azonosító üres
UserDisplayNameEmpty: A felhasználó megjelenítendő neve üres
NoExternalUserData: Nem érkezett külső felhasználói adat
CreationNotAllowed: Új felhasználó létrehozása nem engedélyezett ezen a szolgáltatón
LinkingNotAllowed: A felhasználó összekapcsolása nem engedélyezett ezen a szolgáltatón
NoOptionAllowed: Sem új felhasználó létrehozása, sem összekapcsolás nem engedélyezett ezen a szolgáltatón. Kérjük, lépj kapcsolatba az adminisztrátoroddal.
GrantRequired: Bejelentkezés nem lehetséges. A felhasználónak legalább egy jogosultsággal kell rendelkeznie az alkalmazáson. Kérlek, lépj kapcsolatba az adminisztrátoroddal.
ProjectRequired: Bejelentkezés nem lehetséges. A felhasználó szervezetének engedélyezve kell lennie a projektre. Kérlek, lépj kapcsolatba az adminisztrátoroddal.
IdentityProvider:
InvalidConfig: Az Identity Provider konfiguráció érvénytelen
IAM:
LockoutPolicy:
NotExisting: A Lockout Policy nem létezik
Org:
LoginPolicy:
RegistrationNotAllowed: A regisztráció nem engedélyezett
DeviceAuth:
NotExisting: A felhasználói kód nem létezik
optional: (opcionális)

View File

@ -233,6 +233,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: Jenis kelamin GenderLabel: Jenis kelamin
Female: Perempuan Female: Perempuan
Male: Pria Male: Pria
@ -342,6 +343,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
DeviceAuth: DeviceAuth:
Title: Otorisasi Perangkat Title: Otorisasi Perangkat
UserCode: UserCode:

View File

@ -263,6 +263,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: Genere GenderLabel: Genere
Female: Femminile Female: Femminile
Male: Maschile Male: Maschile
@ -379,6 +380,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
DeviceAuth: DeviceAuth:
Title: Autorizzazione del dispositivo Title: Autorizzazione del dispositivo

View File

@ -255,6 +255,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: 性別 GenderLabel: 性別
Female: 女性 Female: 女性
Male: 男性 Male: 男性
@ -296,6 +297,7 @@ ExternalRegistrationUserOverview:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
TosAndPrivacyLabel: 利用規約 TosAndPrivacyLabel: 利用規約
TosConfirm: 私は利用規約を承諾します。 TosConfirm: 私は利用規約を承諾します。
TosLinkText: TOS TosLinkText: TOS
@ -371,6 +373,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
DeviceAuth: DeviceAuth:
Title: デバイス認証 Title: デバイス認証

View File

@ -263,6 +263,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: Пол GenderLabel: Пол
Female: Женски Female: Женски
Male: Машки Male: Машки
@ -304,6 +305,7 @@ ExternalRegistrationUserOverview:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
TosAndPrivacyLabel: Правила и услови TosAndPrivacyLabel: Правила и услови
TosConfirm: Се согласувам со TosConfirm: Се согласувам со
TosLinkText: правилата за користење TosLinkText: правилата за користење
@ -379,6 +381,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
DeviceAuth: DeviceAuth:
Title: Овластување преку уред Title: Овластување преку уред

View File

@ -263,6 +263,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: Geslacht GenderLabel: Geslacht
Female: Vrouw Female: Vrouw
Male: Man Male: Man
@ -304,6 +305,7 @@ ExternalRegistrationUserOverview:
Nederlands: Nederlands Nederlands: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
TosAndPrivacyLabel: Algemene voorwaarden TosAndPrivacyLabel: Algemene voorwaarden
TosConfirm: Ik accepteer de TosConfirm: Ik accepteer de
TosLinkText: AV TosLinkText: AV
@ -379,6 +381,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
DeviceAuth: DeviceAuth:
Title: Apparaat Autorisatie Title: Apparaat Autorisatie
UserCode: UserCode:

View File

@ -263,6 +263,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: Płeć GenderLabel: Płeć
Female: Kobieta Female: Kobieta
Male: Mężczyzna Male: Mężczyzna
@ -304,6 +305,7 @@ ExternalRegistrationUserOverview:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
TosAndPrivacyLabel: Warunki i zasady TosAndPrivacyLabel: Warunki i zasady
TosConfirm: Akceptuję TosConfirm: Akceptuję
TosLinkText: Warunki korzystania TosLinkText: Warunki korzystania
@ -379,6 +381,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
DeviceAuth: DeviceAuth:
Title: Autoryzacja urządzenia Title: Autoryzacja urządzenia

View File

@ -259,6 +259,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: Gênero GenderLabel: Gênero
Female: Feminino Female: Feminino
Male: Masculino Male: Masculino
@ -300,6 +301,7 @@ ExternalRegistrationUserOverview:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
TosAndPrivacyLabel: Termos e condições TosAndPrivacyLabel: Termos e condições
TosConfirm: Eu aceito os TosConfirm: Eu aceito os
TosLinkText: termos de serviço TosLinkText: termos de serviço
@ -375,6 +377,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
DeviceAuth: DeviceAuth:
Title: Autorização de dispositivo Title: Autorização de dispositivo

View File

@ -262,6 +262,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: Пол GenderLabel: Пол
Female: Женский Female: Женский
Male: Мужской Male: Мужской
@ -303,6 +304,7 @@ ExternalRegistrationUserOverview:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
TosAndPrivacyLabel: Условия использования TosAndPrivacyLabel: Условия использования
TosConfirm: Я согласен с TosConfirm: Я согласен с
TosLinkText: Пользовательским соглашением TosLinkText: Пользовательским соглашением
@ -378,6 +380,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
DeviceAuth: DeviceAuth:
Title: Авторизация устройства Title: Авторизация устройства

View File

@ -263,6 +263,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: Kön GenderLabel: Kön
Female: Man Female: Man
Male: Kvinna Male: Kvinna
@ -304,6 +305,7 @@ ExternalRegistrationUserOverview:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
TosAndPrivacyLabel: Användarvillkor TosAndPrivacyLabel: Användarvillkor
TosConfirm: Jag accepterar TosConfirm: Jag accepterar
TosLinkText: Användarvillkoren TosLinkText: Användarvillkoren
@ -379,6 +381,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
DeviceAuth: DeviceAuth:
Title: Tillgång från hårdvaruenhet Title: Tillgång från hårdvaruenhet
UserCode: UserCode:

View File

@ -263,6 +263,7 @@ RegistrationUser:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
GenderLabel: 性别 GenderLabel: 性别
Female: 女性 Female: 女性
Male: 男性 Male: 男性
@ -304,6 +305,7 @@ ExternalRegistrationUserOverview:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
TosAndPrivacyLabel: 条款和条款 TosAndPrivacyLabel: 条款和条款
TosConfirm: 我接受 TosConfirm: 我接受
TosLinkText: 服务条款 TosLinkText: 服务条款
@ -379,6 +381,7 @@ ExternalNotFound:
Dutch: Nederlands Dutch: Nederlands
Swedish: Svenska Swedish: Svenska
Indonesian: Bahasa Indonesia Indonesian: Bahasa Indonesia
Hungarian: Magyar
DeviceAuth: DeviceAuth:
Title: 设备授权 Title: 设备授权
UserCode: UserCode:

View File

@ -96,6 +96,8 @@
</option> </option>
<option value="sv" id="sv" {{if (selectedLanguage "sv")}} selected {{end}}>{{t "ExternalNotFound.Swedish"}} <option value="sv" id="sv" {{if (selectedLanguage "sv")}} selected {{end}}>{{t "ExternalNotFound.Swedish"}}
</option> </option>
<option value="hu" id="hu" {{if (selectedLanguage "hu")}} selected {{end}}>{{t "ExternalNotFound.Hungarian"}}
</option>
</select> </select>
</div> </div>
</div> </div>

View File

@ -726,7 +726,7 @@ func (repo *AuthRequestRepo) fillPolicies(ctx context.Context, request *domain.A
request.DefaultTranslations = defaultLoginTranslations request.DefaultTranslations = defaultLoginTranslations
} }
if len(request.OrgTranslations) == 0 || request.PolicyOrgID() != orgID { if len(request.OrgTranslations) == 0 || request.PolicyOrgID() != orgID {
orgLoginTranslations, err := repo.getLoginTexts(ctx, orgID) orgLoginTranslations, err := repo.getLoginTexts(ctx, request.PrivateLabelingOrgID(orgID))
if err != nil { if err != nil {
return err return err
} }
@ -785,9 +785,12 @@ func (repo *AuthRequestRepo) checkLoginName(ctx context.Context, request *domain
} }
// the user was either not found or not active // the user was either not found or not active
// so check if the loginname suffix matches a verified org domain // so check if the loginname suffix matches a verified org domain
ok, errDomainDiscovery := repo.checkDomainDiscovery(ctx, request, loginNameInput) // but only if no org was requested (by id or domain)
if errDomainDiscovery != nil || ok { if request.RequestedOrgID == "" {
return errDomainDiscovery ok, errDomainDiscovery := repo.checkDomainDiscovery(ctx, request, loginNameInput)
if errDomainDiscovery != nil || ok {
return errDomainDiscovery
}
} }
// let's once again check if the user was just inactive // let's once again check if the user was just inactive
if user != nil && user.State == int32(domain.UserStateInactive) { if user != nil && user.State == int32(domain.UserStateInactive) {

View File

@ -6,6 +6,7 @@ import (
"time" "time"
"github.com/zitadel/logging" "github.com/zitadel/logging"
"github.com/zitadel/zitadel/internal/database/postgres"
) )
// Cache stores objects with a value of type `V`. // Cache stores objects with a value of type `V`.
@ -55,9 +56,6 @@ type Cache[I, K comparable, V Entry[I, K]] interface {
// Truncate deletes all cached objects. // Truncate deletes all cached objects.
Truncate(ctx context.Context) error Truncate(ctx context.Context) error
// Close the cache. Subsequent calls to the cache are not allowed.
Close(ctx context.Context) error
} }
// Entry contains a value of type `V` to be cached. // Entry contains a value of type `V` to be cached.
@ -75,8 +73,8 @@ type Entry[I, K comparable] interface {
type CachesConfig struct { type CachesConfig struct {
Connectors struct { Connectors struct {
Memory MemoryConnectorConfig Memory MemoryConnectorConfig
// SQL database.Config Postgres PostgresConnectorConfig
// Redis redis.Config? // Redis redis.Config?
} }
Instance *CacheConfig Instance *CacheConfig
@ -104,3 +102,9 @@ type MemoryConnectorConfig struct {
Enabled bool Enabled bool
AutoPrune AutoPruneConfig AutoPrune AutoPruneConfig
} }
type PostgresConnectorConfig struct {
Enabled bool
AutoPrune AutoPruneConfig
Connection postgres.Config
}

View File

@ -109,15 +109,11 @@ func (c *mapCache[I, K, V]) Prune(ctx context.Context) error {
func (c *mapCache[I, K, V]) Truncate(ctx context.Context) error { func (c *mapCache[I, K, V]) Truncate(ctx context.Context) error {
for name, index := range c.indexMap { for name, index := range c.indexMap {
index.Truncate() index.Truncate()
c.logger.DebugContext(ctx, "map cache clear", "index", name) c.logger.DebugContext(ctx, "map cache truncate", "index", name)
} }
return nil return nil
} }
func (c *mapCache[I, K, V]) Close(ctx context.Context) error {
return ctx.Err()
}
type index[K comparable, V any] struct { type index[K comparable, V any] struct {
mutex sync.RWMutex mutex sync.RWMutex
config *cache.CacheConfig config *cache.CacheConfig

View File

@ -49,7 +49,6 @@ func Test_mapCache_Get(t *testing.T) {
AddSource: true, AddSource: true,
}, },
}) })
defer c.Close(context.Background())
obj := &testObject{ obj := &testObject{
id: "id", id: "id",
names: []string{"foo", "bar"}, names: []string{"foo", "bar"},
@ -112,7 +111,6 @@ func Test_mapCache_Invalidate(t *testing.T) {
AddSource: true, AddSource: true,
}, },
}) })
defer c.Close(context.Background())
obj := &testObject{ obj := &testObject{
id: "id", id: "id",
names: []string{"foo", "bar"}, names: []string{"foo", "bar"},
@ -134,7 +132,6 @@ func Test_mapCache_Delete(t *testing.T) {
AddSource: true, AddSource: true,
}, },
}) })
defer c.Close(context.Background())
obj := &testObject{ obj := &testObject{
id: "id", id: "id",
names: []string{"foo", "bar"}, names: []string{"foo", "bar"},
@ -168,7 +165,6 @@ func Test_mapCache_Prune(t *testing.T) {
AddSource: true, AddSource: true,
}, },
}) })
defer c.Close(context.Background())
objects := []*testObject{ objects := []*testObject{
{ {
@ -205,7 +201,6 @@ func Test_mapCache_Truncate(t *testing.T) {
AddSource: true, AddSource: true,
}, },
}) })
defer c.Close(context.Background())
objects := []*testObject{ objects := []*testObject{
{ {
id: "id1", id: "id1",

View File

@ -19,4 +19,3 @@ func (noop[I, K, V]) Invalidate(context.Context, I, ...K) (err error) { return }
func (noop[I, K, V]) Delete(context.Context, I, ...K) (err error) { return } func (noop[I, K, V]) Delete(context.Context, I, ...K) (err error) { return }
func (noop[I, K, V]) Prune(context.Context) (err error) { return } func (noop[I, K, V]) Prune(context.Context) (err error) { return }
func (noop[I, K, V]) Truncate(context.Context) (err error) { return } func (noop[I, K, V]) Truncate(context.Context) (err error) { return }
func (noop[I, K, V]) Close(context.Context) (err error) { return }

View File

@ -0,0 +1,7 @@
create unlogged table if not exists cache.objects_{{ . }}
partition of cache.objects
for values in ('{{ . }}');
create unlogged table if not exists cache.string_keys_{{ . }}
partition of cache.string_keys
for values in ('{{ . }}');

5
internal/cache/pg/delete.sql vendored Normal file
View File

@ -0,0 +1,5 @@
delete from cache.string_keys k
where k.cache_name = $1
and k.index_id = $2
and k.index_key = any($3)
;

19
internal/cache/pg/get.sql vendored Normal file
View File

@ -0,0 +1,19 @@
update cache.objects
set last_used_at = now()
where cache_name = $1
and (
select object_id
from cache.string_keys k
where cache_name = $1
and index_id = $2
and index_key = $3
) = id
and case when $4::interval > '0s'
then created_at > now()-$4::interval -- max age
else true
end
and case when $5::interval > '0s'
then last_used_at > now()-$5::interval -- last use
else true
end
returning payload;

9
internal/cache/pg/invalidate.sql vendored Normal file
View File

@ -0,0 +1,9 @@
delete from cache.objects o
using cache.string_keys k
where k.cache_name = $1
and k.index_id = $2
and k.index_key = any($3)
and o.cache_name = k.cache_name
and o.id = k.object_id
;

Some files were not shown because too many files have changed in this diff Show More