diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml b/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml
index fb15beb726..a975c0b995 100644
--- a/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml
+++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.yaml
@@ -40,7 +40,7 @@ body:
label: Database
description: What database are you using? (self-hosters only)
options:
- - CockroachDB
+ - CockroachDB (Zitadel v2)
- PostgreSQL
- Other (describe below!)
- type: input
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 265902feff..979911d5ab 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,3 +1,8 @@
+
+
# Which Problems Are Solved
Replace this example text with a concise list of problems that this PR solves.
diff --git a/.github/workflows/core-integration-test.yml b/.github/workflows/core-integration-test.yml
index d889d7a5ff..e33ffec3d5 100644
--- a/.github/workflows/core-integration-test.yml
+++ b/.github/workflows/core-integration-test.yml
@@ -73,7 +73,6 @@ jobs:
if: ${{ steps.cache.outputs.cache-hit != 'true' }}
env:
ZITADEL_MASTERKEY: MasterkeyNeedsToHave32Characters
- INTEGRATION_DB_FLAVOR: postgres
run: make core_integration_test
-
name: upload server logs
@@ -99,71 +98,3 @@ jobs:
with:
key: integration-test-postgres-${{ inputs.core_cache_key }}
path: ${{ steps.go-cache-path.outputs.GO_CACHE_PATH }}
-
- # TODO: produces the following output: ERROR: unknown command "cockroach start-single-node --insecure" for "cockroach"
- # cockroach:
- # runs-on: ubuntu-latest
- # services:
- # cockroach:
- # image: cockroachdb/cockroach:latest
- # ports:
- # - 26257:26257
- # - 8080:8080
- # env:
- # COCKROACH_ARGS: "start-single-node --insecure"
- # options: >-
- # --health-cmd "curl http://localhost:8080/health?ready=1 || exit 1"
- # --health-interval 10s
- # --health-timeout 5s
- # --health-retries 5
- # --health-start-period 10s
- # steps:
- # -
- # uses: actions/checkout@v4
- # -
- # uses: actions/setup-go@v5
- # with:
- # go-version: ${{ inputs.go_version }}
- # -
- # uses: actions/cache/restore@v4
- # timeout-minutes: 1
- # name: restore core
- # with:
- # path: ${{ inputs.core_cache_path }}
- # key: ${{ inputs.core_cache_key }}
- # fail-on-cache-miss: true
- # -
- # id: go-cache-path
- # name: set cache path
- # run: echo "GO_CACHE_PATH=$(go env GOCACHE)" >> $GITHUB_OUTPUT
- # -
- # uses: actions/cache/restore@v4
- # id: cache
- # timeout-minutes: 1
- # name: restore previous results
- # with:
- # key: integration-test-crdb-${{ inputs.core_cache_key }}
- # restore-keys: |
- # integration-test-crdb-core-
- # path: ${{ steps.go-cache-path.outputs.GO_CACHE_PATH }}
- # -
- # name: test
- # if: ${{ steps.cache.outputs.cache-hit != 'true' }}
- # env:
- # ZITADEL_MASTERKEY: MasterkeyNeedsToHave32Characters
- # INTEGRATION_DB_FLAVOR: cockroach
- # run: make core_integration_test
- # -
- # name: publish coverage
- # uses: codecov/codecov-action@v4.3.0
- # with:
- # file: profile.cov
- # name: core-integration-tests-cockroach
- # flags: core-integration-tests-cockroach
- # -
- # uses: actions/cache/save@v4
- # name: cache results
- # if: ${{ steps.cache.outputs.cache-hit != 'true' }}
- # with:
- # key: integration-test-crdb-${{ inputs.core_cache_key }}
- # path: ${{ steps.go-cache-path.outputs.GO_CACHE_PATH }}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 17aee6bbe9..23469d4209 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,7 +36,6 @@ load-test/.keys
# dumps
.backups
-cockroach-data/*
.local/*
.build/
@@ -71,7 +70,6 @@ zitadel-*-*
# local
build/local/*.env
-migrations/cockroach/migrate_cloud.go
.notifications
/.artifacts/*
!/.artifacts/zitadel
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6fafd3dd6f..ce8b9aff89 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -165,7 +165,7 @@ ZITADEL serves traffic as soon as you can see the following log line:
### Backend/login
By executing the commands from this section, you run everything you need to develop the ZITADEL backend locally.
-Using [Docker Compose](https://docs.docker.com/compose/), you run a [CockroachDB](https://www.cockroachlabs.com/docs/stable/start-a-local-cluster-in-docker-mac.html) on your local machine.
+Using [Docker Compose](https://docs.docker.com/compose/), you run a [PostgreSQL](https://www.postgresql.org/download/) on your local machine.
With [make](https://www.gnu.org/software/make/), you build a debuggable ZITADEL binary and run it using [delve](https://github.com/go-delve/delve).
Then, you test your changes via the console your binary is serving at http://localhost:8080 and by verifying the database.
Once you are happy with your changes, you run end-to-end tests and tear everything down.
@@ -200,7 +200,7 @@ make compile
You can now run and debug the binary in .artifacts/zitadel/zitadel using your favourite IDE, for example GoLand.
You can test if ZITADEL does what you expect by using the UI at http://localhost:8080/ui/console.
-Also, you can verify the data by running `cockroach sql --database zitadel --insecure` and running SQL queries.
+Also, you can verify the data by running `psql "host=localhost dbname=zitadel sslmode=disable"` and running SQL queries.
#### Run Local Unit Tests
@@ -216,12 +216,6 @@ Integration tests are run as gRPC clients against a running ZITADEL server binar
The server binary is typically [build with coverage enabled](https://go.dev/doc/build-cover).
It is also possible to run a ZITADEL sever in a debugger and run the integrations tests like that. In order to run the server, a database is required.
-The database flavor can **optionally** be set in the environment to `cockroach` or `postgres`. The default is `postgres`.
-
-```bash
-export INTEGRATION_DB_FLAVOR="cockroach"
-```
-
In order to prepare the local system, the following will bring up the database, builds a coverage binary, initializes the database and starts the sever.
```bash
@@ -306,7 +300,7 @@ docker compose --file ./e2e/config/host.docker.internal/docker-compose.yaml down
### Console
By executing the commands from this section, you run everything you need to develop the console locally.
-Using [Docker Compose](https://docs.docker.com/compose/), you run [CockroachDB](https://www.cockroachlabs.com/docs/stable/start-a-local-cluster-in-docker-mac.html) and the [latest release of ZITADEL](https://github.com/zitadel/zitadel/releases/latest) on your local machine.
+Using [Docker Compose](https://docs.docker.com/compose/), you run [PostgreSQL](https://www.postgresql.org/download/) and the [latest release of ZITADEL](https://github.com/zitadel/zitadel/releases/latest) on your local machine.
You use the ZITADEL container as backend for your console.
The console is run in your [Node](https://nodejs.org/en/about/) environment using [a local development server for Angular](https://angular.io/cli/serve#ng-serve), so you have fast feedback about your changes.
diff --git a/LICENSE b/LICENSE
index a1ea99bb88..bae94e189e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,201 +1,661 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
+ GNU AFFERO GENERAL PUBLIC LICENSE
+ Version 3, 19 November 2007
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
- 1. Definitions.
+ Preamble
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
+ The GNU Affero General Public License is a free, copyleft license for
+software and other kinds of works, specifically designed to ensure
+cooperation with the community in the case of network server software.
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+our General Public Licenses are intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
+ Developers that use our General Public Licenses protect your rights
+with two steps: (1) assert copyright on the software, and (2) offer
+you this License which gives you legal permission to copy, distribute
+and/or modify the software.
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
+ A secondary benefit of defending all users' freedom is that
+improvements made in alternate versions of the program, if they
+receive widespread use, become available for other developers to
+incorporate. Many developers of free software are heartened and
+encouraged by the resulting cooperation. However, in the case of
+software used on network servers, this result may fail to come about.
+The GNU General Public License permits making a modified version and
+letting the public access it on a server without ever releasing its
+source code to the public.
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
+ The GNU Affero General Public License is designed specifically to
+ensure that, in such cases, the modified source code becomes available
+to the community. It requires the operator of a network server to
+provide the source code of the modified version running there to the
+users of that server. Therefore, public use of a modified version, on
+a publicly accessible server, gives the public access to the source
+code of the modified version.
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
+ An older license, called the Affero General Public License and
+published by Affero, was designed to accomplish similar goals. This is
+a different license, not a version of the Affero GPL, but Affero has
+released a new version of the Affero GPL which permits relicensing under
+this license.
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
+ The precise terms and conditions for copying, distribution and
+modification follow.
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
+ TERMS AND CONDITIONS
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
+ 0. Definitions.
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
+ "This License" refers to version 3 of the GNU Affero General Public License.
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
+ 1. Source Code.
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
- END OF TERMS AND CONDITIONS
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
- APPENDIX: How to apply the Apache License to your work.
+ The Corresponding Source for a work in source code form is that
+same work.
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
+ 2. Basic Permissions.
- Copyright 2020 CAOS AG
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
- http://www.apache.org/licenses/LICENSE-2.0
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Remote Network Interaction; Use with the GNU General Public License.
+
+ Notwithstanding any other provision of this License, if you modify the
+Program, your modified version must prominently offer all users
+interacting with it remotely through a computer network (if your version
+supports such interaction) an opportunity to receive the Corresponding
+Source of your version by providing access to the Corresponding Source
+from a network server at no charge, through some standard or customary
+means of facilitating copying of software. This Corresponding Source
+shall include the Corresponding Source for any work covered by version 3
+of the GNU General Public License that is incorporated pursuant to the
+following paragraph.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the work with which it is combined will remain governed by version
+3 of the GNU General Public License.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU Affero General Public License from time to time. Such new versions
+will be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU Affero General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU Affero General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU Affero General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If your software can interact with users remotely through a computer
+network, you should also make sure that it provides a way for users to
+get its source. For example, if your program is a web application, its
+interface could display a "Source" link that leads users to an archive
+of the code. There are many ways you could offer source, and different
+solutions will be better for different programs; see section 13 for the
+specific requirements.
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU AGPL, see
+.
\ No newline at end of file
diff --git a/LICENSING.md b/LICENSING.md
new file mode 100644
index 0000000000..9cad2082f8
--- /dev/null
+++ b/LICENSING.md
@@ -0,0 +1,25 @@
+# Licensing Policy
+
+This repository is licensed under the [GNU Affero General Public License v3.0](LICENSE) (AGPL-3.0-only). We use the [SPDX License List](https://spdx.org/licenses/) for standard license naming.
+
+## AGPL-3.0-only Compliance
+
+ZITADEL is open-source software intended for community use. Determining your application's compliance with the AGPL-3.0-only license is your responsibility.
+
+**We strongly recommend consulting with legal counsel or licensing specialists to ensure your usage of ZITADEL, and any other integrated open-source projects, adheres to their respective licenses. AGPL-3.0-only compliance can be complex.**
+
+If your application triggers AGPL-3.0-only obligations and you wish to avoid them (e.g., you do not plan to open-source your modifications or application), please [contact us](https://zitadel.com/contact) to discuss commercial licensing options. Using ZITADEL without verifying your license compliance is at your own risk.
+
+## Exceptions to AGPL-3.0-only
+
+The following files and directories, including their subdirectories, are licensed under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0):
+
+```
+proto/
+```
+
+## Community Contributions
+
+To maintain a clear licensing structure and facilitate community contributions, all contributions must be licensed under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0) to be accepted. By submitting a contribution, you agree to this licensing.
+
+This approach avoids the need for a Contributor License Agreement (CLA) while ensuring clarity regarding license terms. We will only accept contributions licensed under Apache 2.0.
diff --git a/Makefile b/Makefile
index 27e76c0614..b5145cef3d 100644
--- a/Makefile
+++ b/Makefile
@@ -8,10 +8,9 @@ COMMIT_SHA ?= $(shell git rev-parse HEAD)
ZITADEL_IMAGE ?= zitadel:local
GOCOVERDIR = tmp/coverage
-INTEGRATION_DB_FLAVOR ?= postgres
ZITADEL_MASTERKEY ?= MasterkeyNeedsToHave32Characters
-export GOCOVERDIR INTEGRATION_DB_FLAVOR ZITADEL_MASTERKEY
+export GOCOVERDIR ZITADEL_MASTERKEY
.PHONY: compile
compile: core_build console_build compile_pipeline
@@ -113,7 +112,7 @@ core_unit_test:
.PHONY: core_integration_db_up
core_integration_db_up:
- docker compose -f internal/integration/config/docker-compose.yaml up --pull always --wait $${INTEGRATION_DB_FLAVOR} cache
+ docker compose -f internal/integration/config/docker-compose.yaml up --pull always --wait cache
.PHONY: core_integration_db_down
core_integration_db_down:
@@ -123,13 +122,13 @@ core_integration_db_down:
core_integration_setup:
go build -cover -race -tags integration -o zitadel.test main.go
mkdir -p $${GOCOVERDIR}
- GORACE="halt_on_error=1" ./zitadel.test init --config internal/integration/config/zitadel.yaml --config internal/integration/config/${INTEGRATION_DB_FLAVOR}.yaml
- GORACE="halt_on_error=1" ./zitadel.test setup --masterkeyFromEnv --init-projections --config internal/integration/config/zitadel.yaml --config internal/integration/config/${INTEGRATION_DB_FLAVOR}.yaml --steps internal/integration/config/steps.yaml
+ GORACE="halt_on_error=1" ./zitadel.test init --config internal/integration/config/zitadel.yaml --config internal/integration/config/postgres.yaml
+ GORACE="halt_on_error=1" ./zitadel.test setup --masterkeyFromEnv --init-projections --config internal/integration/config/zitadel.yaml --config internal/integration/config/postgres.yaml --steps internal/integration/config/steps.yaml
.PHONY: core_integration_server_start
core_integration_server_start: core_integration_setup
GORACE="log_path=tmp/race.log" \
- ./zitadel.test start --masterkeyFromEnv --config internal/integration/config/zitadel.yaml --config internal/integration/config/${INTEGRATION_DB_FLAVOR}.yaml \
+ ./zitadel.test start --masterkeyFromEnv --config internal/integration/config/zitadel.yaml --config internal/integration/config/postgres.yaml \
> tmp/zitadel.log 2>&1 \
& printf $$! > tmp/zitadel.pid
diff --git a/README.md b/README.md
index d7eabeb240..285e50964c 100644
--- a/README.md
+++ b/README.md
@@ -107,7 +107,7 @@ Yet it offers everything you need for a customer identity ([CIAM](https://zitade
- [Actions](https://zitadel.com/docs/apis/actions/introduction) to react on events with custom code and extended ZITADEL for you needs
- [Branding](https://zitadel.com/docs/guides/manage/customize/branding) for a uniform user experience across multiple organizations
- [Self-service](https://zitadel.com/docs/concepts/features/selfservice) for end-users, business customers, and administrators
-- [CockroachDB](https://www.cockroachlabs.com/) or a [Postgres](https://www.postgresql.org/) database as reliable and widespread storage option
+- [Postgres](https://www.postgresql.org/) database as reliable and widespread storage option
## Features
@@ -151,7 +151,7 @@ Self-Service
- [Administration UI (Console)](https://zitadel.com/docs/guides/manage/console/overview)
Deployment
-- [Postgres](https://zitadel.com/docs/self-hosting/manage/database#postgres) (version >= 14) or [CockroachDB](https://zitadel.com/docs/self-hosting/manage/database#cockroach) (version latest stable)
+- [Postgres](https://zitadel.com/docs/self-hosting/manage/database#postgres) (version >= 14)
- [Zero Downtime Updates](https://zitadel.com/docs/concepts/architecture/solution#zero-downtime-updates)
- [High scalability](https://zitadel.com/docs/self-hosting/manage/production)
diff --git a/build/workflow.Dockerfile b/build/workflow.Dockerfile
index 47866f2691..2286531192 100644
--- a/build/workflow.Dockerfile
+++ b/build/workflow.Dockerfile
@@ -199,7 +199,6 @@ ENV PATH="/go/bin:/usr/local/go/bin:${PATH}"
WORKDIR /go/src/github.com/zitadel/zitadel
# default vars
-ENV DB_FLAVOR=postgres
ENV POSTGRES_USER=zitadel
ENV POSTGRES_DB=zitadel
ENV POSTGRES_PASSWORD=postgres
@@ -231,12 +230,6 @@ COPY --from=test-core-unit /go/src/github.com/zitadel/zitadel/profile.cov /cover
# integration test core
# #######################################
FROM test-core-base AS test-core-integration
-ENV DB_FLAVOR=cockroach
-
-# install cockroach
-COPY --from=cockroachdb/cockroach:latest-v24.3 /cockroach/cockroach /usr/local/bin/
-ENV COCKROACH_BINARY=/cockroach/cockroach
-
ENV ZITADEL_MASTERKEY=MasterkeyNeedsToHave32Characters
COPY build/core-integration-test.sh /usr/local/bin/run-tests.sh
diff --git a/cmd/defaults.yaml b/cmd/defaults.yaml
index b95cb6d74b..30e037c80f 100644
--- a/cmd/defaults.yaml
+++ b/cmd/defaults.yaml
@@ -113,67 +113,36 @@ PublicHostHeaders: # ZITADEL_PUBLICHOSTHEADERS
WebAuthNName: ZITADEL # ZITADEL_WEBAUTHNNAME
Database:
- # CockroachDB is the default database of ZITADEL
- cockroach:
- Host: localhost # ZITADEL_DATABASE_COCKROACH_HOST
- Port: 26257 # ZITADEL_DATABASE_COCKROACH_PORT
- Database: zitadel # ZITADEL_DATABASE_COCKROACH_DATABASE
- MaxOpenConns: 5 # ZITADEL_DATABASE_COCKROACH_MAXOPENCONNS
- MaxIdleConns: 2 # ZITADEL_DATABASE_COCKROACH_MAXIDLECONNS
- MaxConnLifetime: 30m # ZITADEL_DATABASE_COCKROACH_MAXCONNLIFETIME
- MaxConnIdleTime: 5m # ZITADEL_DATABASE_COCKROACH_MAXCONNIDLETIME
- Options: "" # ZITADEL_DATABASE_COCKROACH_OPTIONS
+ # Postgres is the default database of ZITADEL
+ postgres:
+ Host: localhost # ZITADEL_DATABASE_POSTGRES_HOST
+ Port: 5432 # ZITADEL_DATABASE_POSTGRES_PORT
+ Database: zitadel # ZITADEL_DATABASE_POSTGRES_DATABASE
+ MaxOpenConns: 10 # ZITADEL_DATABASE_POSTGRES_MAXOPENCONNS
+ MaxIdleConns: 5 # ZITADEL_DATABASE_POSTGRES_MAXIDLECONNS
+ MaxConnLifetime: 30m # ZITADEL_DATABASE_POSTGRES_MAXCONNLIFETIME
+ MaxConnIdleTime: 5m # ZITADEL_DATABASE_POSTGRES_MAXCONNIDLETIME
+ Options: "" # ZITADEL_DATABASE_POSTGRES_OPTIONS
User:
- Username: zitadel # ZITADEL_DATABASE_COCKROACH_USER_USERNAME
- Password: "" # ZITADEL_DATABASE_COCKROACH_USER_PASSWORD
+ Username: zitadel # ZITADEL_DATABASE_POSTGRES_USER_USERNAME
+ Password: "" # ZITADEL_DATABASE_POSTGRES_USER_PASSWORD
SSL:
- Mode: disable # ZITADEL_DATABASE_COCKROACH_USER_SSL_MODE
- RootCert: "" # ZITADEL_DATABASE_COCKROACH_USER_SSL_ROOTCERT
- Cert: "" # ZITADEL_DATABASE_COCKROACH_USER_SSL_CERT
- Key: "" # ZITADEL_DATABASE_COCKROACH_USER_SSL_KEY
+ Mode: disable # ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE
+ RootCert: "" # ZITADEL_DATABASE_POSTGRES_USER_SSL_ROOTCERT
+ Cert: "" # ZITADEL_DATABASE_POSTGRES_USER_SSL_CERT
+ Key: "" # ZITADEL_DATABASE_POSTGRES_USER_SSL_KEY
Admin:
# By default, ExistingDatabase is not specified in the connection string
# If the connection resolves to a database that is not existing in your system, configure an existing one here
- # It is used in zitadel init to connect to cockroach and create a dedicated database for ZITADEL.
- ExistingDatabase: # ZITADEL_DATABASE_COCKROACH_ADMIN_EXISTINGDATABASE
- Username: root # ZITADEL_DATABASE_COCKROACH_ADMIN_USERNAME
- Password: "" # ZITADEL_DATABASE_COCKROACH_ADMIN_PASSWORD
- SSL:
- Mode: disable # ZITADEL_DATABASE_COCKROACH_ADMIN_SSL_MODE
- RootCert: "" # ZITADEL_DATABASE_COCKROACH_ADMIN_SSL_ROOTCERT
- Cert: "" # ZITADEL_DATABASE_COCKROACH_ADMIN_SSL_CERT
- Key: "" # ZITADEL_DATABASE_COCKROACH_ADMIN_SSL_KEY
- # Postgres is used as soon as a value is set
- # The values describe the possible fields to set values
- postgres:
- Host: # ZITADEL_DATABASE_POSTGRES_HOST
- Port: # ZITADEL_DATABASE_POSTGRES_PORT
- Database: # ZITADEL_DATABASE_POSTGRES_DATABASE
- MaxOpenConns: # ZITADEL_DATABASE_POSTGRES_MAXOPENCONNS
- MaxIdleConns: # ZITADEL_DATABASE_POSTGRES_MAXIDLECONNS
- MaxConnLifetime: # ZITADEL_DATABASE_POSTGRES_MAXCONNLIFETIME
- MaxConnIdleTime: # ZITADEL_DATABASE_POSTGRES_MAXCONNIDLETIME
- Options: # ZITADEL_DATABASE_POSTGRES_OPTIONS
- User:
- Username: # ZITADEL_DATABASE_POSTGRES_USER_USERNAME
- Password: # ZITADEL_DATABASE_POSTGRES_USER_PASSWORD
- SSL:
- Mode: # ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE
- RootCert: # ZITADEL_DATABASE_POSTGRES_USER_SSL_ROOTCERT
- Cert: # ZITADEL_DATABASE_POSTGRES_USER_SSL_CERT
- Key: # ZITADEL_DATABASE_POSTGRES_USER_SSL_KEY
- Admin:
- # The default ExistingDatabase is postgres
- # If your db system doesn't have a database named postgres, configure an existing database here
# It is used in zitadel init to connect to postgres and create a dedicated database for ZITADEL.
ExistingDatabase: # ZITADEL_DATABASE_POSTGRES_ADMIN_EXISTINGDATABASE
- Username: # ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME
- Password: # ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD
+ Username: postgres # ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME
+ Password: postgres # ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD
SSL:
- Mode: # ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE
- RootCert: # ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_ROOTCERT
- Cert: # ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_CERT
- Key: # ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_KEY
+ Mode: disable # ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE
+ RootCert: "" # ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_ROOTCERT
+ Cert: "" # ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_CERT
+ Key: "" # ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_KEY
# Caches are EXPERIMENTAL. The following config may have breaking changes in the future.
# If no config is provided, caching is disabled by default.
@@ -447,19 +416,30 @@ Projections:
Notifications:
# Notifications can be processed by either a sequential mode (legacy) or a new parallel mode.
# The parallel mode is currently only recommended for Postgres databases.
- # For CockroachDB, the sequential mode is recommended, see: https://github.com/zitadel/zitadel/issues/9002
# If legacy mode is enabled, the worker config below is ignored.
LegacyEnabled: true # ZITADEL_NOTIFICATIONS_LEGACYENABLED
# The amount of workers processing the notification request events.
# If set to 0, no notification request events will be handled. This can be useful when running in
# multi binary / pod setup and allowing only certain executables to process the events.
- Workers: 1 # ZITADEL_NOTIFIACATIONS_WORKERS
+ Workers: 1 # ZITADEL_NOTIFICATIONS_WORKERS
# The maximum duration a job can do it's work before it is considered as failed.
- TransactionDuration: 10s # ZITADEL_NOTIFIACATIONS_TRANSACTIONDURATION
+ TransactionDuration: 10s # ZITADEL_NOTIFICATIONS_TRANSACTIONDURATION
# Automatically cancel the notification after the amount of failed attempts
- MaxAttempts: 3 # ZITADEL_NOTIFIACATIONS_MAXATTEMPTS
+ MaxAttempts: 3 # ZITADEL_NOTIFICATIONS_MAXATTEMPTS
# Automatically cancel the notification if it cannot be handled within a specific time
- MaxTtl: 5m # ZITADEL_NOTIFIACATIONS_MAXTTL
+ MaxTtl: 5m # ZITADEL_NOTIFICATIONS_MAXTTL
+
+Executions:
+ # The amount of workers processing the execution request events.
+ # If set to 0, no execution request events will be handled. This can be useful when running in
+ # multi binary / pod setup and allowing only certain executables to process the events.
+ Workers: 1 # ZITADEL_EXECUTIONS_WORKERS
+ # The maximum duration a job can do it's work before it is considered as failed.
+ # This maximum duration is prioritized in case that the sum of the target's timeouts is higher,
+ # to limit the runtime of a singular execution.
+ TransactionDuration: 10s # ZITADEL_EXECUTIONS_TRANSACTIONDURATION
+ # Automatically cancel the notification if it cannot be handled within a specific time
+ MaxTtl: 5m # ZITADEL_EXECUTIONS_MAXTTL
Auth:
# See Projections.BulkLimit
@@ -1733,6 +1713,298 @@ InternalAuthZ:
- "user.grant.read"
- "user.membership.read"
+SystemAuthZ:
+ RolePermissionMappings:
+ - Role: "SYSTEM_OWNER"
+ Permissions:
+ - "system.instance.read"
+ - "system.instance.write"
+ - "system.instance.delete"
+ - "system.domain.read"
+ - "system.domain.write"
+ - "system.domain.delete"
+ - "system.debug.read"
+ - "system.debug.write"
+ - "system.debug.delete"
+ - "system.feature.read"
+ - "system.feature.write"
+ - "system.feature.delete"
+ - "system.limits.write"
+ - "system.limits.delete"
+ - "system.quota.write"
+ - "system.quota.delete"
+ - "system.iam.member.read"
+ - Role: "SYSTEM_OWNER_VIEWER"
+ Permissions:
+ - "system.instance.read"
+ - "system.domain.read"
+ - "system.debug.read"
+ - "system.feature.read"
+ - "system.iam.member.read"
+ - Role: "IAM_OWNER"
+ Permissions:
+ - "iam.read"
+ - "iam.write"
+ - "iam.policy.read"
+ - "iam.policy.write"
+ - "iam.policy.delete"
+ - "iam.member.read"
+ - "iam.member.write"
+ - "iam.member.delete"
+ - "iam.idp.read"
+ - "iam.idp.write"
+ - "iam.idp.delete"
+ - "iam.action.read"
+ - "iam.action.write"
+ - "iam.action.delete"
+ - "iam.flow.read"
+ - "iam.flow.write"
+ - "iam.flow.delete"
+ - "iam.feature.read"
+ - "iam.feature.write"
+ - "iam.feature.delete"
+ - "iam.restrictions.read"
+ - "iam.restrictions.write"
+ - "iam.web_key.write"
+ - "iam.web_key.delete"
+ - "iam.web_key.read"
+ - "iam.debug.write"
+ - "iam.debug.read"
+ - "org.read"
+ - "org.global.read"
+ - "org.create"
+ - "org.write"
+ - "org.delete"
+ - "org.member.read"
+ - "org.member.write"
+ - "org.member.delete"
+ - "org.idp.read"
+ - "org.idp.write"
+ - "org.idp.delete"
+ - "org.action.read"
+ - "org.action.write"
+ - "org.action.delete"
+ - "org.flow.read"
+ - "org.flow.write"
+ - "org.flow.delete"
+ - "org.feature.read"
+ - "org.feature.write"
+ - "org.feature.delete"
+ - "user.read"
+ - "user.global.read"
+ - "user.write"
+ - "user.delete"
+ - "user.grant.read"
+ - "user.grant.write"
+ - "user.grant.delete"
+ - "user.membership.read"
+ - "user.credential.write"
+ - "user.passkey.write"
+ - "user.feature.read"
+ - "user.feature.write"
+ - "user.feature.delete"
+ - "policy.read"
+ - "policy.write"
+ - "policy.delete"
+ - "project.read"
+ - "project.create"
+ - "project.write"
+ - "project.delete"
+ - "project.member.read"
+ - "project.member.write"
+ - "project.member.delete"
+ - "project.role.read"
+ - "project.role.write"
+ - "project.role.delete"
+ - "project.app.read"
+ - "project.app.write"
+ - "project.app.delete"
+ - "project.grant.read"
+ - "project.grant.write"
+ - "project.grant.delete"
+ - "project.grant.member.read"
+ - "project.grant.member.write"
+ - "project.grant.member.delete"
+ - "events.read"
+ - "milestones.read"
+ - "session.read"
+ - "session.delete"
+ - "action.target.read"
+ - "action.target.write"
+ - "action.target.delete"
+ - "action.execution.read"
+ - "action.execution.write"
+ - "userschema.read"
+ - "userschema.write"
+ - "userschema.delete"
+ - "session.read"
+ - "session.delete"
+ - Role: "IAM_OWNER_VIEWER"
+ Permissions:
+ - "iam.read"
+ - "iam.policy.read"
+ - "iam.member.read"
+ - "iam.idp.read"
+ - "iam.action.read"
+ - "iam.flow.read"
+ - "iam.restrictions.read"
+ - "iam.feature.read"
+ - "iam.web_key.read"
+ - "iam.debug.read"
+ - "org.read"
+ - "org.member.read"
+ - "org.idp.read"
+ - "org.action.read"
+ - "org.flow.read"
+ - "org.feature.read"
+ - "user.read"
+ - "user.global.read"
+ - "user.grant.read"
+ - "user.membership.read"
+ - "user.feature.read"
+ - "policy.read"
+ - "project.read"
+ - "project.member.read"
+ - "project.role.read"
+ - "project.app.read"
+ - "project.grant.read"
+ - "project.grant.member.read"
+ - "events.read"
+ - "milestones.read"
+ - "action.target.read"
+ - "action.execution.read"
+ - "userschema.read"
+ - "session.read"
+ - Role: "IAM_ORG_MANAGER"
+ Permissions:
+ - "org.read"
+ - "org.global.read"
+ - "org.create"
+ - "org.write"
+ - "org.delete"
+ - "org.member.read"
+ - "org.member.write"
+ - "org.member.delete"
+ - "org.idp.read"
+ - "org.idp.write"
+ - "org.idp.delete"
+ - "org.action.read"
+ - "org.action.write"
+ - "org.action.delete"
+ - "org.flow.read"
+ - "org.flow.write"
+ - "org.flow.delete"
+ - "org.feature.read"
+ - "org.feature.write"
+ - "org.feature.delete"
+ - "user.read"
+ - "user.global.read"
+ - "user.write"
+ - "user.delete"
+ - "user.grant.read"
+ - "user.grant.write"
+ - "user.grant.delete"
+ - "user.membership.read"
+ - "user.credential.write"
+ - "user.passkey.write"
+ - "user.feature.read"
+ - "user.feature.write"
+ - "user.feature.delete"
+ - "policy.read"
+ - "policy.write"
+ - "policy.delete"
+ - "project.read"
+ - "project.create"
+ - "project.write"
+ - "project.delete"
+ - "project.member.read"
+ - "project.member.write"
+ - "project.member.delete"
+ - "project.role.read"
+ - "project.role.write"
+ - "project.role.delete"
+ - "project.app.read"
+ - "project.app.write"
+ - "project.app.delete"
+ - "project.grant.read"
+ - "project.grant.write"
+ - "project.grant.delete"
+ - "project.grant.member.read"
+ - "project.grant.member.write"
+ - "project.grant.member.delete"
+ - "session.delete"
+ - Role: "IAM_USER_MANAGER"
+ Permissions:
+ - "org.read"
+ - "org.global.read"
+ - "org.member.read"
+ - "org.member.delete"
+ - "user.read"
+ - "user.global.read"
+ - "user.write"
+ - "user.delete"
+ - "user.grant.read"
+ - "user.grant.write"
+ - "user.grant.delete"
+ - "user.membership.read"
+ - "user.passkey.write"
+ - "user.feature.read"
+ - "user.feature.write"
+ - "user.feature.delete"
+ - "project.read"
+ - "project.member.read"
+ - "project.role.read"
+ - "project.app.read"
+ - "project.grant.read"
+ - "project.grant.write"
+ - "project.grant.delete"
+ - "project.grant.member.read"
+ - "session.delete"
+ - Role: "IAM_ADMIN_IMPERSONATOR"
+ Permissions:
+ - "admin.impersonation"
+ - "impersonation"
+ - Role: "IAM_END_USER_IMPERSONATOR"
+ Permissions:
+ - "impersonation"
+ - Role: "IAM_LOGIN_CLIENT"
+ Permissions:
+ - "iam.read"
+ - "iam.policy.read"
+ - "iam.member.read"
+ - "iam.member.write"
+ - "iam.idp.read"
+ - "iam.feature.read"
+ - "iam.restrictions.read"
+ - "org.read"
+ - "org.member.read"
+ - "org.member.write"
+ - "org.idp.read"
+ - "org.feature.read"
+ - "user.read"
+ - "user.write"
+ - "user.grant.read"
+ - "user.grant.write"
+ - "user.membership.read"
+ - "user.credential.write"
+ - "user.passkey.write"
+ - "user.feature.read"
+ - "policy.read"
+ - "project.read"
+ - "project.member.read"
+ - "project.member.write"
+ - "project.role.read"
+ - "project.app.read"
+ - "project.member.read"
+ - "project.member.write"
+ - "project.grant.read"
+ - "project.grant.member.read"
+ - "project.grant.member.write"
+ - "session.read"
+ - "session.link"
+ - "session.delete"
+ - "userschema.read"
+
# If a new projection is introduced it will be prefilled during the setup process (if enabled)
# This can prevent serving outdated data after a version upgrade, but might require a longer setup / upgrade process:
# https://zitadel.com/docs/self-hosting/manage/updating_scaling
diff --git a/cmd/initialise/config.go b/cmd/initialise/config.go
index 3fe7173860..899018ddcb 100644
--- a/cmd/initialise/config.go
+++ b/cmd/initialise/config.go
@@ -19,7 +19,7 @@ func MustNewConfig(v *viper.Viper) *Config {
config := new(Config)
err := v.Unmarshal(config,
viper.DecodeHook(mapstructure.ComposeDecodeHookFunc(
- database.DecodeHook,
+ database.DecodeHook(false),
mapstructure.TextUnmarshallerHookFunc(),
)),
)
diff --git a/cmd/initialise/init.go b/cmd/initialise/init.go
index 02fd481eab..cc505325a9 100644
--- a/cmd/initialise/init.go
+++ b/cmd/initialise/init.go
@@ -12,20 +12,17 @@ import (
)
var (
- //go:embed sql/cockroach/*
- //go:embed sql/postgres/*
+ //go:embed sql/*.sql
stmts embed.FS
createUserStmt string
grantStmt string
- settingsStmt string
databaseStmt string
createEventstoreStmt string
createProjectionsStmt string
createSystemStmt string
createEncryptionKeysStmt string
createEventsStmt string
- createSystemSequenceStmt string
createUniqueConstraints string
roleAlreadyExistsCode = "42710"
@@ -39,7 +36,7 @@ func New() *cobra.Command {
Long: `Sets up the minimum requirements to start ZITADEL.
Prerequisites:
-- database (PostgreSql or cockroachdb)
+- PostgreSql database
The user provided by flags needs privileges to
- create the database if it does not exist
@@ -53,7 +50,7 @@ The user provided by flags needs privileges to
},
}
- cmd.AddCommand(newZitadel(), newDatabase(), newUser(), newGrant(), newSettings())
+ cmd.AddCommand(newZitadel(), newDatabase(), newUser(), newGrant())
return cmd
}
@@ -62,7 +59,6 @@ func InitAll(ctx context.Context, config *Config) {
VerifyUser(config.Database.Username(), config.Database.Password()),
VerifyDatabase(config.Database.DatabaseName()),
VerifyGrant(config.Database.DatabaseName(), config.Database.Username()),
- VerifySettings(config.Database.DatabaseName(), config.Database.Username()),
)
logging.OnError(err).Fatal("unable to initialize the database")
@@ -73,7 +69,7 @@ func InitAll(ctx context.Context, config *Config) {
func initialise(ctx context.Context, config database.Config, steps ...func(context.Context, *database.DB) error) error {
logging.Info("initialization started")
- err := ReadStmts(config.Type())
+ err := ReadStmts()
if err != nil {
return err
}
@@ -97,58 +93,48 @@ func Init(ctx context.Context, db *database.DB, steps ...func(context.Context, *
return nil
}
-func ReadStmts(typ string) (err error) {
- createUserStmt, err = readStmt(typ, "01_user")
+func ReadStmts() (err error) {
+ createUserStmt, err = readStmt("01_user")
if err != nil {
return err
}
- databaseStmt, err = readStmt(typ, "02_database")
+ databaseStmt, err = readStmt("02_database")
if err != nil {
return err
}
- grantStmt, err = readStmt(typ, "03_grant_user")
+ grantStmt, err = readStmt("03_grant_user")
if err != nil {
return err
}
- createEventstoreStmt, err = readStmt(typ, "04_eventstore")
+ createEventstoreStmt, err = readStmt("04_eventstore")
if err != nil {
return err
}
- createProjectionsStmt, err = readStmt(typ, "05_projections")
+ createProjectionsStmt, err = readStmt("05_projections")
if err != nil {
return err
}
- createSystemStmt, err = readStmt(typ, "06_system")
+ createSystemStmt, err = readStmt("06_system")
if err != nil {
return err
}
- createEncryptionKeysStmt, err = readStmt(typ, "07_encryption_keys_table")
+ createEncryptionKeysStmt, err = readStmt("07_encryption_keys_table")
if err != nil {
return err
}
- createEventsStmt, err = readStmt(typ, "08_events_table")
+ createEventsStmt, err = readStmt("08_events_table")
if err != nil {
return err
}
- createSystemSequenceStmt, err = readStmt(typ, "09_system_sequence")
- if err != nil {
- return err
- }
-
- createUniqueConstraints, err = readStmt(typ, "10_unique_constraints_table")
- if err != nil {
- return err
- }
-
- settingsStmt, err = readStmt(typ, "11_settings")
+ createUniqueConstraints, err = readStmt("10_unique_constraints_table")
if err != nil {
return err
}
@@ -156,7 +142,7 @@ func ReadStmts(typ string) (err error) {
return nil
}
-func readStmt(typ, step string) (string, error) {
- stmt, err := stmts.ReadFile("sql/" + typ + "/" + step + ".sql")
+func readStmt(step string) (string, error) {
+ stmt, err := stmts.ReadFile("sql/" + step + ".sql")
return string(stmt), err
}
diff --git a/cmd/initialise/sql/cockroach/01_user.sql b/cmd/initialise/sql/01_user.sql
similarity index 56%
rename from cmd/initialise/sql/cockroach/01_user.sql
rename to cmd/initialise/sql/01_user.sql
index 4e621216ce..7be2d4ae4d 100644
--- a/cmd/initialise/sql/cockroach/01_user.sql
+++ b/cmd/initialise/sql/01_user.sql
@@ -1,2 +1,2 @@
-- replace %[1]s with the name of the user
-CREATE USER IF NOT EXISTS "%[1]s"
\ No newline at end of file
+CREATE USER "%[1]s"
\ No newline at end of file
diff --git a/cmd/initialise/sql/cockroach/02_database.sql b/cmd/initialise/sql/02_database.sql
similarity index 54%
rename from cmd/initialise/sql/cockroach/02_database.sql
rename to cmd/initialise/sql/02_database.sql
index 6103b95b31..172913661b 100644
--- a/cmd/initialise/sql/cockroach/02_database.sql
+++ b/cmd/initialise/sql/02_database.sql
@@ -1,2 +1,2 @@
-- replace %[1]s with the name of the database
-CREATE DATABASE IF NOT EXISTS "%[1]s";
+CREATE DATABASE "%[1]s"
\ No newline at end of file
diff --git a/cmd/initialise/sql/postgres/03_grant_user.sql b/cmd/initialise/sql/03_grant_user.sql
similarity index 100%
rename from cmd/initialise/sql/postgres/03_grant_user.sql
rename to cmd/initialise/sql/03_grant_user.sql
diff --git a/cmd/initialise/sql/cockroach/04_eventstore.sql b/cmd/initialise/sql/04_eventstore.sql
similarity index 100%
rename from cmd/initialise/sql/cockroach/04_eventstore.sql
rename to cmd/initialise/sql/04_eventstore.sql
diff --git a/cmd/initialise/sql/cockroach/05_projections.sql b/cmd/initialise/sql/05_projections.sql
similarity index 100%
rename from cmd/initialise/sql/cockroach/05_projections.sql
rename to cmd/initialise/sql/05_projections.sql
diff --git a/cmd/initialise/sql/cockroach/06_system.sql b/cmd/initialise/sql/06_system.sql
similarity index 100%
rename from cmd/initialise/sql/cockroach/06_system.sql
rename to cmd/initialise/sql/06_system.sql
diff --git a/cmd/initialise/sql/cockroach/07_encryption_keys_table.sql b/cmd/initialise/sql/07_encryption_keys_table.sql
similarity index 100%
rename from cmd/initialise/sql/cockroach/07_encryption_keys_table.sql
rename to cmd/initialise/sql/07_encryption_keys_table.sql
diff --git a/cmd/initialise/sql/postgres/08_events_table.sql b/cmd/initialise/sql/08_events_table.sql
similarity index 100%
rename from cmd/initialise/sql/postgres/08_events_table.sql
rename to cmd/initialise/sql/08_events_table.sql
diff --git a/cmd/initialise/sql/postgres/10_unique_constraints_table.sql b/cmd/initialise/sql/10_unique_constraints_table.sql
similarity index 100%
rename from cmd/initialise/sql/postgres/10_unique_constraints_table.sql
rename to cmd/initialise/sql/10_unique_constraints_table.sql
diff --git a/cmd/initialise/sql/README.md b/cmd/initialise/sql/README.md
index b477c0fb73..b7a18f0f98 100644
--- a/cmd/initialise/sql/README.md
+++ b/cmd/initialise/sql/README.md
@@ -11,6 +11,5 @@ The sql-files in this folder initialize the ZITADEL database and user. These obj
- 05_projections.sql: creates the schema needed to read the data
- 06_system.sql: creates the schema needed for ZITADEL itself
- 07_encryption_keys_table.sql: creates the table for encryption keys (for event data)
-- files 08_enable_hash_sharded_indexes.sql and 09_events_table.sql must run in the same session
- - 08_enable_hash_sharded_indexes.sql enables the [hash sharded index](https://www.cockroachlabs.com/docs/stable/hash-sharded-indexes.html) feature for this session
- - 09_events_table.sql creates the table for eventsourcing
+- 08_events_table.sql creates the table for eventsourcing
+- 10_unique_constraints_table.sql creates the table to check unique constraints for events
diff --git a/cmd/initialise/sql/cockroach/03_grant_user.sql b/cmd/initialise/sql/cockroach/03_grant_user.sql
deleted file mode 100644
index de0d2743eb..0000000000
--- a/cmd/initialise/sql/cockroach/03_grant_user.sql
+++ /dev/null
@@ -1,4 +0,0 @@
--- replace the first %[1]s with the database
--- replace the second \%[2]s with the user
-GRANT ALL ON DATABASE "%[1]s" TO "%[2]s";
-GRANT SYSTEM VIEWACTIVITY TO "%[2]s";
\ No newline at end of file
diff --git a/cmd/initialise/sql/cockroach/08_events_table.sql b/cmd/initialise/sql/cockroach/08_events_table.sql
deleted file mode 100644
index ebaf18ce2a..0000000000
--- a/cmd/initialise/sql/cockroach/08_events_table.sql
+++ /dev/null
@@ -1,116 +0,0 @@
-CREATE TABLE IF NOT EXISTS eventstore.events2 (
- instance_id TEXT NOT NULL
- , aggregate_type TEXT NOT NULL
- , aggregate_id TEXT NOT NULL
-
- , event_type TEXT NOT NULL
- , "sequence" BIGINT NOT NULL
- , revision SMALLINT NOT NULL
- , created_at TIMESTAMPTZ NOT NULL
- , payload JSONB
- , creator TEXT NOT NULL
- , "owner" TEXT NOT NULL
-
- , "position" DECIMAL NOT NULL
- , in_tx_order INTEGER NOT NULL
-
- , PRIMARY KEY (instance_id, aggregate_type, aggregate_id, "sequence")
- , INDEX es_active_instances (created_at DESC) STORING ("position")
- , INDEX es_wm (aggregate_id, instance_id, aggregate_type, event_type)
- , INDEX es_projection (instance_id, aggregate_type, event_type, "position" DESC)
-);
-
--- represents an event to be created.
-CREATE TYPE IF NOT EXISTS eventstore.command AS (
- instance_id TEXT
- , aggregate_type TEXT
- , aggregate_id TEXT
- , command_type TEXT
- , revision INT2
- , payload JSONB
- , creator TEXT
- , owner TEXT
-);
-
-CREATE OR REPLACE FUNCTION eventstore.commands_to_events(commands eventstore.command[]) RETURNS SETOF eventstore.events2 VOLATILE AS $$
-SELECT
- ("c").instance_id
- , ("c").aggregate_type
- , ("c").aggregate_id
- , ("c").command_type AS event_type
- , cs.sequence + ROW_NUMBER() OVER (PARTITION BY ("c").instance_id, ("c").aggregate_type, ("c").aggregate_id ORDER BY ("c").in_tx_order) AS sequence
- , ("c").revision
- , hlc_to_timestamp(cluster_logical_timestamp()) AS created_at
- , ("c").payload
- , ("c").creator
- , cs.owner
- , cluster_logical_timestamp() AS position
- , ("c").in_tx_order
-FROM (
- SELECT
- ("c").instance_id
- , ("c").aggregate_type
- , ("c").aggregate_id
- , ("c").command_type
- , ("c").revision
- , ("c").payload
- , ("c").creator
- , ("c").owner
- , ROW_NUMBER() OVER () AS in_tx_order
- FROM
- UNNEST(commands) AS "c"
-) AS "c"
-JOIN (
- SELECT
- cmds.instance_id
- , cmds.aggregate_type
- , cmds.aggregate_id
- , CASE WHEN (e.owner IS NOT NULL OR e.owner <> '') THEN e.owner ELSE command_owners.owner END AS owner
- , COALESCE(MAX(e.sequence), 0) AS sequence
- FROM (
- SELECT DISTINCT
- ("cmds").instance_id
- , ("cmds").aggregate_type
- , ("cmds").aggregate_id
- , ("cmds").owner
- FROM UNNEST(commands) AS "cmds"
- ) AS cmds
- LEFT JOIN eventstore.events2 AS e
- ON cmds.instance_id = e.instance_id
- AND cmds.aggregate_type = e.aggregate_type
- AND cmds.aggregate_id = e.aggregate_id
- JOIN (
- SELECT
- DISTINCT ON (
- ("c").instance_id
- , ("c").aggregate_type
- , ("c").aggregate_id
- )
- ("c").instance_id
- , ("c").aggregate_type
- , ("c").aggregate_id
- , ("c").owner
- FROM
- UNNEST(commands) AS "c"
- ) AS command_owners ON
- cmds.instance_id = command_owners.instance_id
- AND cmds.aggregate_type = command_owners.aggregate_type
- AND cmds.aggregate_id = command_owners.aggregate_id
- GROUP BY
- cmds.instance_id
- , cmds.aggregate_type
- , cmds.aggregate_id
- , 4 -- owner
-) AS cs
- ON ("c").instance_id = cs.instance_id
- AND ("c").aggregate_type = cs.aggregate_type
- AND ("c").aggregate_id = cs.aggregate_id
-ORDER BY
- in_tx_order
-$$ LANGUAGE SQL;
-
-CREATE OR REPLACE FUNCTION eventstore.push(commands eventstore.command[]) RETURNS SETOF eventstore.events2 AS $$
- INSERT INTO eventstore.events2
- SELECT * FROM eventstore.commands_to_events(commands)
- RETURNING *
-$$ LANGUAGE SQL;
\ No newline at end of file
diff --git a/cmd/initialise/sql/cockroach/09_system_sequence.sql b/cmd/initialise/sql/cockroach/09_system_sequence.sql
deleted file mode 100644
index 596e887664..0000000000
--- a/cmd/initialise/sql/cockroach/09_system_sequence.sql
+++ /dev/null
@@ -1 +0,0 @@
-CREATE SEQUENCE IF NOT EXISTS eventstore.system_seq
diff --git a/cmd/initialise/sql/cockroach/10_unique_constraints_table.sql b/cmd/initialise/sql/cockroach/10_unique_constraints_table.sql
deleted file mode 100644
index 2594a248b7..0000000000
--- a/cmd/initialise/sql/cockroach/10_unique_constraints_table.sql
+++ /dev/null
@@ -1,6 +0,0 @@
-CREATE TABLE IF NOT EXISTS eventstore.unique_constraints (
- instance_id TEXT,
- unique_type TEXT,
- unique_field TEXT,
- PRIMARY KEY (instance_id, unique_type, unique_field)
-)
diff --git a/cmd/initialise/sql/cockroach/11_settings.sql b/cmd/initialise/sql/cockroach/11_settings.sql
deleted file mode 100644
index 5fa9dd72f6..0000000000
--- a/cmd/initialise/sql/cockroach/11_settings.sql
+++ /dev/null
@@ -1,4 +0,0 @@
--- replace the first %[1]q with the database in double quotes
--- replace the second \%[2]q with the user in double quotes$
--- For more information see technical advisory 10009 (https://zitadel.com/docs/support/advisory/a10009)
-ALTER ROLE %[2]q IN DATABASE %[1]q SET enable_durable_locking_for_serializable = on;
\ No newline at end of file
diff --git a/cmd/initialise/sql/postgres/01_user.sql b/cmd/initialise/sql/postgres/01_user.sql
deleted file mode 100644
index cd60b9a2cf..0000000000
--- a/cmd/initialise/sql/postgres/01_user.sql
+++ /dev/null
@@ -1 +0,0 @@
-CREATE USER "%[1]s"
\ No newline at end of file
diff --git a/cmd/initialise/sql/postgres/02_database.sql b/cmd/initialise/sql/postgres/02_database.sql
deleted file mode 100644
index 895a1f29d5..0000000000
--- a/cmd/initialise/sql/postgres/02_database.sql
+++ /dev/null
@@ -1 +0,0 @@
-CREATE DATABASE "%[1]s"
\ No newline at end of file
diff --git a/cmd/initialise/sql/postgres/04_eventstore.sql b/cmd/initialise/sql/postgres/04_eventstore.sql
deleted file mode 100644
index 3cb4fc0d3e..0000000000
--- a/cmd/initialise/sql/postgres/04_eventstore.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-CREATE SCHEMA IF NOT EXISTS eventstore;
-
-GRANT ALL ON ALL TABLES IN SCHEMA eventstore TO "%[1]s";
\ No newline at end of file
diff --git a/cmd/initialise/sql/postgres/05_projections.sql b/cmd/initialise/sql/postgres/05_projections.sql
deleted file mode 100644
index 91ca6662ee..0000000000
--- a/cmd/initialise/sql/postgres/05_projections.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-CREATE SCHEMA IF NOT EXISTS projections;
-
-GRANT ALL ON ALL TABLES IN SCHEMA projections TO "%[1]s";
\ No newline at end of file
diff --git a/cmd/initialise/sql/postgres/06_system.sql b/cmd/initialise/sql/postgres/06_system.sql
deleted file mode 100644
index 6c9138918b..0000000000
--- a/cmd/initialise/sql/postgres/06_system.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-CREATE SCHEMA IF NOT EXISTS system;
-
-GRANT ALL ON ALL TABLES IN SCHEMA system TO "%[1]s";
\ No newline at end of file
diff --git a/cmd/initialise/sql/postgres/07_encryption_keys_table.sql b/cmd/initialise/sql/postgres/07_encryption_keys_table.sql
deleted file mode 100644
index 61cb617fdf..0000000000
--- a/cmd/initialise/sql/postgres/07_encryption_keys_table.sql
+++ /dev/null
@@ -1,6 +0,0 @@
-CREATE TABLE IF NOT EXISTS system.encryption_keys (
- id TEXT NOT NULL
- , key TEXT NOT NULL
-
- , PRIMARY KEY (id)
-);
diff --git a/cmd/initialise/sql/postgres/09_system_sequence.sql b/cmd/initialise/sql/postgres/09_system_sequence.sql
deleted file mode 100644
index 15383b3878..0000000000
--- a/cmd/initialise/sql/postgres/09_system_sequence.sql
+++ /dev/null
@@ -1 +0,0 @@
-CREATE SEQUENCE IF NOT EXISTS eventstore.system_seq;
diff --git a/cmd/initialise/verify_database.go b/cmd/initialise/verify_database.go
index 6e04e489f5..3e3bea9efa 100644
--- a/cmd/initialise/verify_database.go
+++ b/cmd/initialise/verify_database.go
@@ -19,7 +19,7 @@ func newDatabase() *cobra.Command {
Long: `Sets up the ZITADEL database.
Prerequisites:
-- cockroachDB or postgreSQL
+- postgreSQL
The user provided by flags needs privileges to
- create the database if it does not exist
diff --git a/cmd/initialise/verify_database_test.go b/cmd/initialise/verify_database_test.go
index d7da97847f..1899605e4f 100644
--- a/cmd/initialise/verify_database_test.go
+++ b/cmd/initialise/verify_database_test.go
@@ -8,7 +8,7 @@ import (
)
func Test_verifyDB(t *testing.T) {
- err := ReadStmts("cockroach") //TODO: check all dialects
+ err := ReadStmts()
if err != nil {
t.Errorf("unable to read stmts: %v", err)
t.FailNow()
@@ -27,7 +27,7 @@ func Test_verifyDB(t *testing.T) {
name: "doesn't exists, create fails",
args: args{
db: prepareDB(t,
- expectExec("-- replace zitadel with the name of the database\nCREATE DATABASE IF NOT EXISTS \"zitadel\"", sql.ErrTxDone),
+ expectExec("-- replace zitadel with the name of the database\nCREATE DATABASE \"zitadel\"", sql.ErrTxDone),
),
database: "zitadel",
},
@@ -37,7 +37,7 @@ func Test_verifyDB(t *testing.T) {
name: "doesn't exists, create successful",
args: args{
db: prepareDB(t,
- expectExec("-- replace zitadel with the name of the database\nCREATE DATABASE IF NOT EXISTS \"zitadel\"", nil),
+ expectExec("-- replace zitadel with the name of the database\nCREATE DATABASE \"zitadel\"", nil),
),
database: "zitadel",
},
@@ -47,7 +47,7 @@ func Test_verifyDB(t *testing.T) {
name: "already exists",
args: args{
db: prepareDB(t,
- expectExec("-- replace zitadel with the name of the database\nCREATE DATABASE IF NOT EXISTS \"zitadel\"", nil),
+ expectExec("-- replace zitadel with the name of the database\nCREATE DATABASE \"zitadel\"", nil),
),
database: "zitadel",
},
diff --git a/cmd/initialise/verify_grant.go b/cmd/initialise/verify_grant.go
index a14a495bff..27f0bd4d08 100644
--- a/cmd/initialise/verify_grant.go
+++ b/cmd/initialise/verify_grant.go
@@ -19,7 +19,7 @@ func newGrant() *cobra.Command {
Long: `Sets ALL grant to the database user.
Prerequisites:
-- cockroachDB or postgreSQL
+- postgreSQL
`,
Run: func(cmd *cobra.Command, args []string) {
config := MustNewConfig(viper.GetViper())
diff --git a/cmd/initialise/verify_settings.go b/cmd/initialise/verify_settings.go
deleted file mode 100644
index 6f4ba7c074..0000000000
--- a/cmd/initialise/verify_settings.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package initialise
-
-import (
- "context"
- _ "embed"
- "fmt"
-
- "github.com/spf13/cobra"
- "github.com/spf13/viper"
- "github.com/zitadel/logging"
-
- "github.com/zitadel/zitadel/internal/database"
-)
-
-func newSettings() *cobra.Command {
- return &cobra.Command{
- Use: "settings",
- Short: "Ensures proper settings on the database",
- Long: `Ensures proper settings on the database.
-
-Prerequisites:
-- cockroachDB or postgreSQL
-
-Cockroach
-- Sets enable_durable_locking_for_serializable to on for the zitadel user and database
-`,
- Run: func(cmd *cobra.Command, args []string) {
- config := MustNewConfig(viper.GetViper())
-
- err := initialise(cmd.Context(), config.Database, VerifySettings(config.Database.DatabaseName(), config.Database.Username()))
- logging.OnError(err).Fatal("unable to set settings")
- },
- }
-}
-
-func VerifySettings(databaseName, username string) func(context.Context, *database.DB) error {
- return func(ctx context.Context, db *database.DB) error {
- if db.Type() == "postgres" {
- return nil
- }
- logging.WithFields("user", username, "database", databaseName).Info("verify settings")
-
- return exec(ctx, db, fmt.Sprintf(settingsStmt, databaseName, username), nil)
- }
-}
diff --git a/cmd/initialise/verify_user.go b/cmd/initialise/verify_user.go
index 43bdb91420..3adca93e53 100644
--- a/cmd/initialise/verify_user.go
+++ b/cmd/initialise/verify_user.go
@@ -19,7 +19,7 @@ func newUser() *cobra.Command {
Long: `Sets up the ZITADEL database user.
Prerequisites:
-- cockroachDB or postgreSQL
+- postgreSQL
The user provided by flags needs privileges to
- create the database if it does not exist
diff --git a/cmd/initialise/verify_user_test.go b/cmd/initialise/verify_user_test.go
index 53b35e67db..40cde5baa2 100644
--- a/cmd/initialise/verify_user_test.go
+++ b/cmd/initialise/verify_user_test.go
@@ -8,7 +8,7 @@ import (
)
func Test_verifyUser(t *testing.T) {
- err := ReadStmts("cockroach") //TODO: check all dialects
+ err := ReadStmts()
if err != nil {
t.Errorf("unable to read stmts: %v", err)
t.FailNow()
@@ -28,7 +28,7 @@ func Test_verifyUser(t *testing.T) {
name: "doesn't exists, create fails",
args: args{
db: prepareDB(t,
- expectExec("-- replace zitadel-user with the name of the user\nCREATE USER IF NOT EXISTS \"zitadel-user\"", sql.ErrTxDone),
+ expectExec("-- replace zitadel-user with the name of the user\nCREATE USER \"zitadel-user\"", sql.ErrTxDone),
),
username: "zitadel-user",
password: "",
@@ -39,7 +39,7 @@ func Test_verifyUser(t *testing.T) {
name: "correct without password",
args: args{
db: prepareDB(t,
- expectExec("-- replace zitadel-user with the name of the user\nCREATE USER IF NOT EXISTS \"zitadel-user\"", nil),
+ expectExec("-- replace zitadel-user with the name of the user\nCREATE USER \"zitadel-user\"", nil),
),
username: "zitadel-user",
password: "",
@@ -50,7 +50,7 @@ func Test_verifyUser(t *testing.T) {
name: "correct with password",
args: args{
db: prepareDB(t,
- expectExec("-- replace zitadel-user with the name of the user\nCREATE USER IF NOT EXISTS \"zitadel-user\" WITH PASSWORD 'password'", nil),
+ expectExec("-- replace zitadel-user with the name of the user\nCREATE USER \"zitadel-user\" WITH PASSWORD 'password'", nil),
),
username: "zitadel-user",
password: "password",
@@ -61,7 +61,7 @@ func Test_verifyUser(t *testing.T) {
name: "already exists",
args: args{
db: prepareDB(t,
- expectExec("-- replace zitadel-user with the name of the user\nCREATE USER IF NOT EXISTS \"zitadel-user\" WITH PASSWORD 'password'", nil),
+ expectExec("-- replace zitadel-user with the name of the user\nCREATE USER \"zitadel-user\" WITH PASSWORD 'password'", nil),
),
username: "zitadel-user",
password: "",
diff --git a/cmd/initialise/verify_zitadel.go b/cmd/initialise/verify_zitadel.go
index 1ae85a21fa..78f28809c2 100644
--- a/cmd/initialise/verify_zitadel.go
+++ b/cmd/initialise/verify_zitadel.go
@@ -21,7 +21,7 @@ func newZitadel() *cobra.Command {
Long: `initialize ZITADEL internals.
Prerequisites:
-- cockroachDB or postgreSQL with user and database
+- postgreSQL with user and database
`,
Run: func(cmd *cobra.Command, args []string) {
config := MustNewConfig(viper.GetViper())
@@ -32,7 +32,7 @@ Prerequisites:
}
func VerifyZitadel(ctx context.Context, db *database.DB, config database.Config) error {
- err := ReadStmts(config.Type())
+ err := ReadStmts()
if err != nil {
return err
}
@@ -68,11 +68,6 @@ func VerifyZitadel(ctx context.Context, db *database.DB, config database.Config)
return err
}
- logging.WithFields().Info("verify system sequence")
- if err := exec(ctx, conn, createSystemSequenceStmt, nil); err != nil {
- return err
- }
-
logging.WithFields().Info("verify unique constraints")
if err := exec(ctx, conn, createUniqueConstraints, nil); err != nil {
return err
diff --git a/cmd/initialise/verify_zitadel_test.go b/cmd/initialise/verify_zitadel_test.go
index 194911a179..7fccd4c0a2 100644
--- a/cmd/initialise/verify_zitadel_test.go
+++ b/cmd/initialise/verify_zitadel_test.go
@@ -9,7 +9,7 @@ import (
)
func Test_verifyEvents(t *testing.T) {
- err := ReadStmts("cockroach") //TODO: check all dialects
+ err := ReadStmts()
if err != nil {
t.Errorf("unable to read stmts: %v", err)
t.FailNow()
diff --git a/cmd/key/key.go b/cmd/key/key.go
index 1dba8fd969..a1cf15b34e 100644
--- a/cmd/key/key.go
+++ b/cmd/key/key.go
@@ -40,7 +40,7 @@ func newKey() *cobra.Command {
Long: `create new encryption key(s) (encrypted by the provided master key)
provide key(s) by YAML file and/or by argument
Requirements:
-- cockroachdb`,
+- postgreSQL`,
Example: `new -f keys.yaml
new key1=somekey key2=anotherkey
new -f keys.yaml key2=anotherkey`,
diff --git a/cmd/mirror/config.go b/cmd/mirror/config.go
index cc98000869..89b0876e5f 100644
--- a/cmd/mirror/config.go
+++ b/cmd/mirror/config.go
@@ -71,7 +71,7 @@ func mustNewConfig(v *viper.Viper, config any) {
mapstructure.StringToTimeDurationHookFunc(),
mapstructure.StringToTimeHookFunc(time.RFC3339),
mapstructure.StringToSliceHookFunc(","),
- database.DecodeHook,
+ database.DecodeHook(true),
actions.HTTPConfigDecodeHook,
hook.EnumHookFunc(internal_authz.MemberTypeString),
mapstructure.TextUnmarshallerHookFunc(),
diff --git a/cmd/mirror/defaults.yaml b/cmd/mirror/defaults.yaml
index 7db91ecc0b..4b42c06534 100644
--- a/cmd/mirror/defaults.yaml
+++ b/cmd/mirror/defaults.yaml
@@ -5,8 +5,6 @@ Source:
Database: zitadel # ZITADEL_DATABASE_COCKROACH_DATABASE
MaxOpenConns: 6 # ZITADEL_DATABASE_COCKROACH_MAXOPENCONNS
MaxIdleConns: 6 # ZITADEL_DATABASE_COCKROACH_MAXIDLECONNS
- EventPushConnRatio: 0.33 # ZITADEL_DATABASE_COCKROACH_EVENTPUSHCONNRATIO
- ProjectionSpoolerConnRatio: 0.33 # ZITADEL_DATABASE_COCKROACH_PROJECTIONSPOOLERCONNRATIO
MaxConnLifetime: 30m # ZITADEL_DATABASE_COCKROACH_MAXCONNLIFETIME
MaxConnIdleTime: 5m # ZITADEL_DATABASE_COCKROACH_MAXCONNIDLETIME
Options: "" # ZITADEL_DATABASE_COCKROACH_OPTIONS
@@ -39,44 +37,23 @@ Source:
Key: # ZITADEL_DATABASE_POSTGRES_USER_SSL_KEY
Destination:
- cockroach:
- Host: localhost # ZITADEL_DATABASE_COCKROACH_HOST
- Port: 26257 # ZITADEL_DATABASE_COCKROACH_PORT
- Database: zitadel # ZITADEL_DATABASE_COCKROACH_DATABASE
- MaxOpenConns: 0 # ZITADEL_DATABASE_COCKROACH_MAXOPENCONNS
- MaxIdleConns: 0 # ZITADEL_DATABASE_COCKROACH_MAXIDLECONNS
- MaxConnLifetime: 30m # ZITADEL_DATABASE_COCKROACH_MAXCONNLIFETIME
- MaxConnIdleTime: 5m # ZITADEL_DATABASE_COCKROACH_MAXCONNIDLETIME
- EventPushConnRatio: 0.01 # ZITADEL_DATABASE_COCKROACH_EVENTPUSHCONNRATIO
- ProjectionSpoolerConnRatio: 0.5 # ZITADEL_DATABASE_COCKROACH_PROJECTIONSPOOLERCONNRATIO
- Options: "" # ZITADEL_DATABASE_COCKROACH_OPTIONS
- User:
- Username: zitadel # ZITADEL_DATABASE_COCKROACH_USER_USERNAME
- Password: "" # ZITADEL_DATABASE_COCKROACH_USER_PASSWORD
- SSL:
- Mode: disable # ZITADEL_DATABASE_COCKROACH_USER_SSL_MODE
- RootCert: "" # ZITADEL_DATABASE_COCKROACH_USER_SSL_ROOTCERT
- Cert: "" # ZITADEL_DATABASE_COCKROACH_USER_SSL_CERT
- Key: "" # ZITADEL_DATABASE_COCKROACH_USER_SSL_KEY
- # Postgres is used as soon as a value is set
- # The values describe the possible fields to set values
postgres:
- Host: # ZITADEL_DATABASE_POSTGRES_HOST
- Port: # ZITADEL_DATABASE_POSTGRES_PORT
- Database: # ZITADEL_DATABASE_POSTGRES_DATABASE
- MaxOpenConns: # ZITADEL_DATABASE_POSTGRES_MAXOPENCONNS
- MaxIdleConns: # ZITADEL_DATABASE_POSTGRES_MAXIDLECONNS
- MaxConnLifetime: # ZITADEL_DATABASE_POSTGRES_MAXCONNLIFETIME
- MaxConnIdleTime: # ZITADEL_DATABASE_POSTGRES_MAXCONNIDLETIME
- Options: # ZITADEL_DATABASE_POSTGRES_OPTIONS
+ Host: localhost # ZITADEL_DATABASE_POSTGRES_HOST
+ Port: 5432 # ZITADEL_DATABASE_POSTGRES_PORT
+ Database: zitadel # ZITADEL_DATABASE_POSTGRES_DATABASE
+ MaxOpenConns: 5 # ZITADEL_DATABASE_POSTGRES_MAXOPENCONNS
+ MaxIdleConns: 2 # ZITADEL_DATABASE_POSTGRES_MAXIDLECONNS
+ MaxConnLifetime: 30m # ZITADEL_DATABASE_POSTGRES_MAXCONNLIFETIME
+ MaxConnIdleTime: 5m # ZITADEL_DATABASE_POSTGRES_MAXCONNIDLETIME
+ Options: "" # ZITADEL_DATABASE_POSTGRES_OPTIONS
User:
- Username: # ZITADEL_DATABASE_POSTGRES_USER_USERNAME
- Password: # ZITADEL_DATABASE_POSTGRES_USER_PASSWORD
+ Username: zitadel # ZITADEL_DATABASE_POSTGRES_USER_USERNAME
+ Password: "" # ZITADEL_DATABASE_POSTGRES_USER_PASSWORD
SSL:
- Mode: # ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE
- RootCert: # ZITADEL_DATABASE_POSTGRES_USER_SSL_ROOTCERT
- Cert: # ZITADEL_DATABASE_POSTGRES_USER_SSL_CERT
- Key: # ZITADEL_DATABASE_POSTGRES_USER_SSL_KEY
+ Mode: disable # ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE
+ RootCert: "" # ZITADEL_DATABASE_POSTGRES_USER_SSL_ROOTCERT
+ Cert: "" # ZITADEL_DATABASE_POSTGRES_USER_SSL_CERT
+ Key: "" # ZITADEL_DATABASE_POSTGRES_USER_SSL_KEY
EventBulkSize: 10000
diff --git a/cmd/mirror/event.go b/cmd/mirror/event.go
index 2bb0d52f45..d513990e10 100644
--- a/cmd/mirror/event.go
+++ b/cmd/mirror/event.go
@@ -4,7 +4,6 @@ import (
"context"
"github.com/zitadel/zitadel/internal/v2/eventstore"
- "github.com/zitadel/zitadel/internal/v2/projection"
"github.com/zitadel/zitadel/internal/v2/readmodel"
"github.com/zitadel/zitadel/internal/v2/system"
mirror_event "github.com/zitadel/zitadel/internal/v2/system/mirror"
@@ -30,39 +29,6 @@ func queryLastSuccessfulMigration(ctx context.Context, destinationES *eventstore
return lastSuccess, nil
}
-func writeMigrationStart(ctx context.Context, sourceES *eventstore.EventStore, id string, destination string) (_ float64, err error) {
- var cmd *eventstore.Command
- if len(instanceIDs) > 0 {
- cmd, err = mirror_event.NewStartedInstancesCommand(destination, instanceIDs)
- if err != nil {
- return 0, err
- }
- } else {
- cmd = mirror_event.NewStartedSystemCommand(destination)
- }
-
- var position projection.HighestPosition
-
- err = sourceES.Push(
- ctx,
- eventstore.NewPushIntent(
- system.AggregateInstance,
- eventstore.AppendAggregate(
- system.AggregateOwner,
- system.AggregateType,
- id,
- eventstore.CurrentSequenceMatches(0),
- eventstore.AppendCommands(cmd),
- ),
- eventstore.PushReducer(&position),
- ),
- )
- if err != nil {
- return 0, err
- }
- return position.Position, nil
-}
-
func writeMigrationSucceeded(ctx context.Context, destinationES *eventstore.EventStore, id, source string, position float64) error {
return destinationES.Push(
ctx,
diff --git a/cmd/mirror/event_store.go b/cmd/mirror/event_store.go
index 3825462126..8ce53b150a 100644
--- a/cmd/mirror/event_store.go
+++ b/cmd/mirror/event_store.go
@@ -14,6 +14,7 @@ import (
"github.com/zitadel/logging"
db "github.com/zitadel/zitadel/internal/database"
+ "github.com/zitadel/zitadel/internal/database/dialect"
"github.com/zitadel/zitadel/internal/id"
"github.com/zitadel/zitadel/internal/v2/database"
"github.com/zitadel/zitadel/internal/v2/eventstore"
@@ -57,9 +58,9 @@ func copyEventstore(ctx context.Context, config *Migration) {
func positionQuery(db *db.DB) string {
switch db.Type() {
- case "postgres":
+ case dialect.DatabaseTypePostgres:
return "SELECT EXTRACT(EPOCH FROM clock_timestamp())"
- case "cockroach":
+ case dialect.DatabaseTypeCockroach:
return "SELECT cluster_logical_timestamp()"
default:
logging.WithFields("db_type", db.Type()).Fatal("database type not recognized")
@@ -80,9 +81,6 @@ func copyEvents(ctx context.Context, source, dest *db.DB, bulkSize uint32) {
destConn, err := dest.Conn(ctx)
logging.OnError(err).Fatal("unable to acquire dest connection")
- sourceES := eventstore.NewEventstoreFromOne(postgres.New(source, &postgres.Config{
- MaxRetries: 3,
- }))
destinationES := eventstore.NewEventstoreFromOne(postgres.New(dest, &postgres.Config{
MaxRetries: 3,
}))
@@ -90,8 +88,14 @@ func copyEvents(ctx context.Context, source, dest *db.DB, bulkSize uint32) {
previousMigration, err := queryLastSuccessfulMigration(ctx, destinationES, source.DatabaseName())
logging.OnError(err).Fatal("unable to query latest successful migration")
- maxPosition, err := writeMigrationStart(ctx, sourceES, migrationID, dest.DatabaseName())
- logging.OnError(err).Fatal("unable to write migration started event")
+ var maxPosition float64
+ err = source.QueryRowContext(ctx,
+ func(row *sql.Row) error {
+ return row.Scan(&maxPosition)
+ },
+ "SELECT MAX(position) FROM eventstore.events2 "+instanceClause(),
+ )
+ logging.OnError(err).Fatal("unable to query max position from source")
logging.WithFields("from", previousMigration.Position, "to", maxPosition).Info("start event migration")
diff --git a/cmd/mirror/mirror.go b/cmd/mirror/mirror.go
index 3fbfe1ae94..866238e56e 100644
--- a/cmd/mirror/mirror.go
+++ b/cmd/mirror/mirror.go
@@ -56,7 +56,6 @@ Order of execution:
copyEventstore(cmd.Context(), config)
projections(cmd.Context(), projectionConfig, masterKey)
- verifyMigration(cmd.Context(), config)
},
}
diff --git a/cmd/mirror/projections.go b/cmd/mirror/projections.go
index c15747e74a..66b3fb1a26 100644
--- a/cmd/mirror/projections.go
+++ b/cmd/mirror/projections.go
@@ -84,6 +84,7 @@ type ProjectionsConfig struct {
ExternalDomain string
ExternalSecure bool
InternalAuthZ internal_authz.Config
+ SystemAuthZ internal_authz.Config
SystemDefaults systemdefaults.SystemDefaults
Telemetry *handlers.TelemetryPusherConfig
Login login.Config
@@ -117,8 +118,11 @@ func projections(
staticStorage, err := config.AssetStorage.NewStorage(client.DB)
logging.OnError(err).Fatal("unable create static storage")
- config.Eventstore.Querier = old_es.NewCRDB(client)
- config.Eventstore.Pusher = new_es.NewEventstore(client)
+ newEventstore := new_es.NewEventstore(client)
+ config.Eventstore.Querier = old_es.NewPostgres(client)
+ config.Eventstore.Pusher = newEventstore
+ config.Eventstore.Searcher = newEventstore
+
es := eventstore.NewEventstore(config.Eventstore)
esV4 := es_v4.NewEventstoreFromOne(es_v4_pg.New(client, &es_v4_pg.Config{
MaxRetries: config.Eventstore.MaxRetries,
@@ -147,7 +151,7 @@ func projections(
sessionTokenVerifier,
func(q *query.Queries) domain.PermissionCheck {
return func(ctx context.Context, permission, orgID, resourceID string) (err error) {
- return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
+ return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, config.SystemAuthZ.RolePermissionMappings, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
}
},
0,
@@ -184,7 +188,7 @@ func projections(
keys.Target,
&http.Client{},
func(ctx context.Context, permission, orgID, resourceID string) (err error) {
- return internal_authz.CheckPermission(ctx, authZRepo, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
+ return internal_authz.CheckPermission(ctx, authZRepo, config.SystemAuthZ.RolePermissionMappings, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
},
sessionTokenVerifier,
config.OIDC.DefaultAccessTokenLifetime,
@@ -220,7 +224,6 @@ func projections(
keys.SMS,
keys.OIDC,
config.OIDC.DefaultBackChannelLogoutLifetime,
- client,
nil,
)
@@ -248,7 +251,7 @@ func projections(
}
}()
- for i := 0; i < int(config.Projections.ConcurrentInstances); i++ {
+ for range int(config.Projections.ConcurrentInstances) {
go execProjections(ctx, instances, failedInstances, &wg)
}
@@ -270,31 +273,39 @@ func execProjections(ctx context.Context, instances <-chan string, failedInstanc
err := projection.ProjectInstance(ctx)
if err != nil {
- logging.WithFields("instance", instance).OnError(err).Info("trigger failed")
+ logging.WithFields("instance", instance).WithError(err).Info("trigger failed")
+ failedInstances <- instance
+ continue
+ }
+
+ err = projection.ProjectInstanceFields(ctx)
+ if err != nil {
+ logging.WithFields("instance", instance).WithError(err).Info("trigger fields failed")
failedInstances <- instance
continue
}
err = admin_handler.ProjectInstance(ctx)
if err != nil {
- logging.WithFields("instance", instance).OnError(err).Info("trigger admin handler failed")
+ logging.WithFields("instance", instance).WithError(err).Info("trigger admin handler failed")
failedInstances <- instance
continue
}
err = auth_handler.ProjectInstance(ctx)
if err != nil {
- logging.WithFields("instance", instance).OnError(err).Info("trigger auth handler failed")
+ logging.WithFields("instance", instance).WithError(err).Info("trigger auth handler failed")
failedInstances <- instance
continue
}
err = notification.ProjectInstance(ctx)
if err != nil {
- logging.WithFields("instance", instance).OnError(err).Info("trigger notification failed")
+ logging.WithFields("instance", instance).WithError(err).Info("trigger notification failed")
failedInstances <- instance
continue
}
+
logging.WithFields("instance", instance).Info("projections done")
}
wg.Done()
diff --git a/cmd/setup/07.go b/cmd/setup/07.go
index 73b9d3480b..590b220eb3 100644
--- a/cmd/setup/07.go
+++ b/cmd/setup/07.go
@@ -3,7 +3,7 @@ package setup
import (
"context"
"database/sql"
- "embed"
+ _ "embed"
"strings"
"github.com/zitadel/zitadel/internal/eventstore"
@@ -12,31 +12,20 @@ import (
var (
//go:embed 07/logstore.sql
createLogstoreSchema07 string
- //go:embed 07/cockroach/access.sql
- //go:embed 07/postgres/access.sql
- createAccessLogsTable07 embed.FS
- //go:embed 07/cockroach/execution.sql
- //go:embed 07/postgres/execution.sql
- createExecutionLogsTable07 embed.FS
+ //go:embed 07/access.sql
+ createAccessLogsTable07 string
+ //go:embed 07/execution.sql
+ createExecutionLogsTable07 string
)
type LogstoreTables struct {
dbClient *sql.DB
username string
- dbType string
}
func (mig *LogstoreTables) Execute(ctx context.Context, _ eventstore.Event) error {
- accessStmt, err := readStmt(createAccessLogsTable07, "07", mig.dbType, "access.sql")
- if err != nil {
- return err
- }
- executionStmt, err := readStmt(createExecutionLogsTable07, "07", mig.dbType, "execution.sql")
- if err != nil {
- return err
- }
- stmt := strings.ReplaceAll(createLogstoreSchema07, "%[1]s", mig.username) + accessStmt + executionStmt
- _, err = mig.dbClient.ExecContext(ctx, stmt)
+ stmt := strings.ReplaceAll(createLogstoreSchema07, "%[1]s", mig.username) + createAccessLogsTable07 + createExecutionLogsTable07
+ _, err := mig.dbClient.ExecContext(ctx, stmt)
return err
}
diff --git a/cmd/setup/07/postgres/access.sql b/cmd/setup/07/access.sql
similarity index 100%
rename from cmd/setup/07/postgres/access.sql
rename to cmd/setup/07/access.sql
diff --git a/cmd/setup/07/cockroach/access.sql b/cmd/setup/07/cockroach/access.sql
deleted file mode 100644
index fc5354cf32..0000000000
--- a/cmd/setup/07/cockroach/access.sql
+++ /dev/null
@@ -1,14 +0,0 @@
-CREATE TABLE IF NOT EXISTS logstore.access (
- log_date TIMESTAMPTZ NOT NULL
- , protocol INT NOT NULL
- , request_url TEXT NOT NULL
- , response_status INT NOT NULL
- , request_headers JSONB
- , response_headers JSONB
- , instance_id TEXT NOT NULL
- , project_id TEXT NOT NULL
- , requested_domain TEXT
- , requested_host TEXT
-
- , INDEX protocol_date_desc (instance_id, protocol, log_date DESC) STORING (request_url, response_status, request_headers)
-);
diff --git a/cmd/setup/07/cockroach/execution.sql b/cmd/setup/07/cockroach/execution.sql
deleted file mode 100644
index b8e18b525a..0000000000
--- a/cmd/setup/07/cockroach/execution.sql
+++ /dev/null
@@ -1,11 +0,0 @@
-CREATE TABLE IF NOT EXISTS logstore.execution (
- log_date TIMESTAMPTZ NOT NULL
- , took INTERVAL
- , message TEXT NOT NULL
- , loglevel INT NOT NULL
- , instance_id TEXT NOT NULL
- , action_id TEXT NOT NULL
- , metadata JSONB
-
- , INDEX log_date_desc (instance_id, log_date DESC) STORING (took)
-);
diff --git a/cmd/setup/07/postgres/execution.sql b/cmd/setup/07/execution.sql
similarity index 100%
rename from cmd/setup/07/postgres/execution.sql
rename to cmd/setup/07/execution.sql
diff --git a/cmd/setup/08.go b/cmd/setup/08.go
index bec6a65ebb..fa006bd3cf 100644
--- a/cmd/setup/08.go
+++ b/cmd/setup/08.go
@@ -2,16 +2,15 @@ package setup
import (
"context"
- "embed"
+ _ "embed"
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/eventstore"
)
var (
- //go:embed 08/cockroach/08.sql
- //go:embed 08/postgres/08.sql
- tokenIndexes08 embed.FS
+ //go:embed 08/08.sql
+ tokenIndexes08 string
)
type AuthTokenIndexes struct {
@@ -19,11 +18,7 @@ type AuthTokenIndexes struct {
}
func (mig *AuthTokenIndexes) Execute(ctx context.Context, _ eventstore.Event) error {
- stmt, err := readStmt(tokenIndexes08, "08", mig.dbClient.Type(), "08.sql")
- if err != nil {
- return err
- }
- _, err = mig.dbClient.ExecContext(ctx, stmt)
+ _, err := mig.dbClient.ExecContext(ctx, tokenIndexes08)
return err
}
diff --git a/cmd/setup/08/postgres/08.sql b/cmd/setup/08/08.sql
similarity index 100%
rename from cmd/setup/08/postgres/08.sql
rename to cmd/setup/08/08.sql
diff --git a/cmd/setup/08/cockroach/08.sql b/cmd/setup/08/cockroach/08.sql
deleted file mode 100644
index aec4d54303..0000000000
--- a/cmd/setup/08/cockroach/08.sql
+++ /dev/null
@@ -1,5 +0,0 @@
-CREATE INDEX IF NOT EXISTS inst_refresh_tkn_idx ON auth.tokens(instance_id, refresh_token_id);
-CREATE INDEX IF NOT EXISTS inst_app_tkn_idx ON auth.tokens(instance_id, application_id);
-CREATE INDEX IF NOT EXISTS inst_ro_tkn_idx ON auth.tokens(instance_id, resource_owner);
-DROP INDEX IF EXISTS auth.tokens@user_user_agent_idx;
-CREATE INDEX IF NOT EXISTS inst_usr_agnt_tkn_idx ON auth.tokens(instance_id, user_id, user_agent_id);
\ No newline at end of file
diff --git a/cmd/setup/10.go b/cmd/setup/10.go
index 93c017305c..b134fcab62 100644
--- a/cmd/setup/10.go
+++ b/cmd/setup/10.go
@@ -3,7 +3,7 @@ package setup
import (
"context"
"database/sql"
- "embed"
+ _ "embed"
"time"
"github.com/cockroachdb/cockroach-go/v2/crdb"
@@ -18,9 +18,8 @@ var (
correctCreationDate10CreateTable string
//go:embed 10/10_fill_table.sql
correctCreationDate10FillTable string
- //go:embed 10/cockroach/10_update.sql
- //go:embed 10/postgres/10_update.sql
- correctCreationDate10Update embed.FS
+ //go:embed 10/10_update.sql
+ correctCreationDate10Update string
//go:embed 10/10_count_wrong_events.sql
correctCreationDate10CountWrongEvents string
//go:embed 10/10_empty_table.sql
@@ -40,11 +39,6 @@ func (mig *CorrectCreationDate) Execute(ctx context.Context, _ eventstore.Event)
logging.WithFields("mig", mig.String(), "iteration", i).Debug("start iteration")
var affected int64
err = crdb.ExecuteTx(ctx, mig.dbClient.DB, nil, func(tx *sql.Tx) error {
- if mig.dbClient.Type() == "cockroach" {
- if _, err := tx.Exec("SET experimental_enable_temp_tables=on"); err != nil {
- return err
- }
- }
_, err := tx.ExecContext(ctx, correctCreationDate10CreateTable)
if err != nil {
return err
@@ -66,11 +60,7 @@ func (mig *CorrectCreationDate) Execute(ctx context.Context, _ eventstore.Event)
return err
}
- updateStmt, err := readStmt(correctCreationDate10Update, "10", mig.dbClient.Type(), "10_update.sql")
- if err != nil {
- return err
- }
- _, err = tx.ExecContext(ctx, updateStmt)
+ _, err = tx.ExecContext(ctx, correctCreationDate10Update)
if err != nil {
return err
}
diff --git a/cmd/setup/10/postgres/10_update.sql b/cmd/setup/10/10_update.sql
similarity index 100%
rename from cmd/setup/10/postgres/10_update.sql
rename to cmd/setup/10/10_update.sql
diff --git a/cmd/setup/10/cockroach/10_update.sql b/cmd/setup/10/cockroach/10_update.sql
deleted file mode 100644
index 9e7d7f993a..0000000000
--- a/cmd/setup/10/cockroach/10_update.sql
+++ /dev/null
@@ -1 +0,0 @@
-UPDATE eventstore.events e SET (creation_date, "position") = (we.next_cd, we.next_cd::DECIMAL) FROM wrong_events we WHERE e.event_sequence = we.event_sequence AND e.instance_id = we.instance_id;
diff --git a/cmd/setup/14.go b/cmd/setup/14.go
index f0ea1b819a..2cd5ac2c57 100644
--- a/cmd/setup/14.go
+++ b/cmd/setup/14.go
@@ -15,8 +15,7 @@ import (
)
var (
- //go:embed 14/cockroach/*.sql
- //go:embed 14/postgres/*.sql
+ //go:embed 14/*.sql
newEventsTable embed.FS
)
@@ -40,7 +39,7 @@ func (mig *NewEventsTable) Execute(ctx context.Context, _ eventstore.Event) erro
return err
}
- statements, err := readStatements(newEventsTable, "14", mig.dbClient.Type())
+ statements, err := readStatements(newEventsTable, "14")
if err != nil {
return err
}
diff --git a/cmd/setup/14/cockroach/01_disable_inserts.sql b/cmd/setup/14/01_disable_inserts.sql
similarity index 100%
rename from cmd/setup/14/cockroach/01_disable_inserts.sql
rename to cmd/setup/14/01_disable_inserts.sql
diff --git a/cmd/setup/14/postgres/02_create_and_fill_events2.sql b/cmd/setup/14/02_create_and_fill_events2.sql
similarity index 100%
rename from cmd/setup/14/postgres/02_create_and_fill_events2.sql
rename to cmd/setup/14/02_create_and_fill_events2.sql
diff --git a/cmd/setup/14/postgres/03_events2_pk.sql b/cmd/setup/14/03_events2_pk.sql
similarity index 100%
rename from cmd/setup/14/postgres/03_events2_pk.sql
rename to cmd/setup/14/03_events2_pk.sql
diff --git a/cmd/setup/14/postgres/04_constraints.sql b/cmd/setup/14/04_constraints.sql
similarity index 100%
rename from cmd/setup/14/postgres/04_constraints.sql
rename to cmd/setup/14/04_constraints.sql
diff --git a/cmd/setup/14/postgres/05_indexes.sql b/cmd/setup/14/05_indexes.sql
similarity index 100%
rename from cmd/setup/14/postgres/05_indexes.sql
rename to cmd/setup/14/05_indexes.sql
diff --git a/cmd/setup/14/cockroach/02_create_and_fill_events2.sql b/cmd/setup/14/cockroach/02_create_and_fill_events2.sql
deleted file mode 100644
index 300ac4b621..0000000000
--- a/cmd/setup/14/cockroach/02_create_and_fill_events2.sql
+++ /dev/null
@@ -1,33 +0,0 @@
-CREATE TABLE eventstore.events2 (
- instance_id,
- aggregate_type,
- aggregate_id,
-
- event_type,
- "sequence",
- revision,
- created_at,
- payload,
- creator,
- "owner",
-
- "position",
- in_tx_order,
-
- PRIMARY KEY (instance_id, aggregate_type, aggregate_id, "sequence")
-) AS SELECT
- instance_id,
- aggregate_type,
- aggregate_id,
-
- event_type,
- event_sequence,
- substr(aggregate_version, 2)::SMALLINT,
- creation_date,
- event_data,
- editor_user,
- resource_owner,
-
- creation_date::DECIMAL,
- event_sequence
-FROM eventstore.events_old;
\ No newline at end of file
diff --git a/cmd/setup/14/cockroach/03_constraints.sql b/cmd/setup/14/cockroach/03_constraints.sql
deleted file mode 100644
index 62f119cc43..0000000000
--- a/cmd/setup/14/cockroach/03_constraints.sql
+++ /dev/null
@@ -1,7 +0,0 @@
-ALTER TABLE eventstore.events2 ALTER COLUMN event_type SET NOT NULL;
-ALTER TABLE eventstore.events2 ALTER COLUMN revision SET NOT NULL;
-ALTER TABLE eventstore.events2 ALTER COLUMN created_at SET NOT NULL;
-ALTER TABLE eventstore.events2 ALTER COLUMN creator SET NOT NULL;
-ALTER TABLE eventstore.events2 ALTER COLUMN "owner" SET NOT NULL;
-ALTER TABLE eventstore.events2 ALTER COLUMN "position" SET NOT NULL;
-ALTER TABLE eventstore.events2 ALTER COLUMN in_tx_order SET NOT NULL;
\ No newline at end of file
diff --git a/cmd/setup/14/cockroach/04_indexes.sql b/cmd/setup/14/cockroach/04_indexes.sql
deleted file mode 100644
index a442653606..0000000000
--- a/cmd/setup/14/cockroach/04_indexes.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-CREATE INDEX IF NOT EXISTS es_active_instances ON eventstore.events2 (created_at DESC) STORING ("position");
-CREATE INDEX IF NOT EXISTS es_wm ON eventstore.events2 (aggregate_id, instance_id, aggregate_type, event_type);
-CREATE INDEX IF NOT EXISTS es_projection ON eventstore.events2 (instance_id, aggregate_type, event_type, "position");
\ No newline at end of file
diff --git a/cmd/setup/14/postgres/01_disable_inserts.sql b/cmd/setup/14/postgres/01_disable_inserts.sql
deleted file mode 100644
index 0f3c277eba..0000000000
--- a/cmd/setup/14/postgres/01_disable_inserts.sql
+++ /dev/null
@@ -1 +0,0 @@
-ALTER TABLE eventstore.events RENAME TO events_old;
\ No newline at end of file
diff --git a/cmd/setup/15.go b/cmd/setup/15.go
index 2e75ffb118..54161ddef9 100644
--- a/cmd/setup/15.go
+++ b/cmd/setup/15.go
@@ -11,8 +11,7 @@ import (
)
var (
- //go:embed 15/cockroach/*.sql
- //go:embed 15/postgres/*.sql
+ //go:embed 15/*.sql
currentProjectionState embed.FS
)
@@ -21,7 +20,7 @@ type CurrentProjectionState struct {
}
func (mig *CurrentProjectionState) Execute(ctx context.Context, _ eventstore.Event) error {
- statements, err := readStatements(currentProjectionState, "15", mig.dbClient.Type())
+ statements, err := readStatements(currentProjectionState, "15")
if err != nil {
return err
}
diff --git a/cmd/setup/15/cockroach/01_new_failed_events.sql b/cmd/setup/15/01_new_failed_events.sql
similarity index 100%
rename from cmd/setup/15/cockroach/01_new_failed_events.sql
rename to cmd/setup/15/01_new_failed_events.sql
diff --git a/cmd/setup/15/postgres/02_fe_from_projections.sql b/cmd/setup/15/02_fe_from_projections.sql
similarity index 100%
rename from cmd/setup/15/postgres/02_fe_from_projections.sql
rename to cmd/setup/15/02_fe_from_projections.sql
diff --git a/cmd/setup/15/cockroach/03_fe_from_adminapi.sql b/cmd/setup/15/03_fe_from_adminapi.sql
similarity index 100%
rename from cmd/setup/15/cockroach/03_fe_from_adminapi.sql
rename to cmd/setup/15/03_fe_from_adminapi.sql
diff --git a/cmd/setup/15/cockroach/04_fe_from_auth.sql b/cmd/setup/15/04_fe_from_auth.sql
similarity index 100%
rename from cmd/setup/15/cockroach/04_fe_from_auth.sql
rename to cmd/setup/15/04_fe_from_auth.sql
diff --git a/cmd/setup/15/cockroach/05_current_states.sql b/cmd/setup/15/05_current_states.sql
similarity index 100%
rename from cmd/setup/15/cockroach/05_current_states.sql
rename to cmd/setup/15/05_current_states.sql
diff --git a/cmd/setup/15/postgres/06_cs_from_projections.sql b/cmd/setup/15/06_cs_from_projections.sql
similarity index 100%
rename from cmd/setup/15/postgres/06_cs_from_projections.sql
rename to cmd/setup/15/06_cs_from_projections.sql
diff --git a/cmd/setup/15/postgres/07_cs_from_adminapi.sql b/cmd/setup/15/07_cs_from_adminapi.sql
similarity index 100%
rename from cmd/setup/15/postgres/07_cs_from_adminapi.sql
rename to cmd/setup/15/07_cs_from_adminapi.sql
diff --git a/cmd/setup/15/postgres/08_cs_from_auth.sql b/cmd/setup/15/08_cs_from_auth.sql
similarity index 100%
rename from cmd/setup/15/postgres/08_cs_from_auth.sql
rename to cmd/setup/15/08_cs_from_auth.sql
diff --git a/cmd/setup/15/cockroach/02_fe_from_projections.sql b/cmd/setup/15/cockroach/02_fe_from_projections.sql
deleted file mode 100644
index 8bf7a4b8d4..0000000000
--- a/cmd/setup/15/cockroach/02_fe_from_projections.sql
+++ /dev/null
@@ -1,26 +0,0 @@
-INSERT INTO projections.failed_events2 (
- projection_name
- , instance_id
- , aggregate_type
- , aggregate_id
- , event_creation_date
- , failed_sequence
- , failure_count
- , error
- , last_failed
-) SELECT
- fe.projection_name
- , fe.instance_id
- , e.aggregate_type
- , e.aggregate_id
- , e.created_at
- , e.sequence
- , fe.failure_count
- , fe.error
- , fe.last_failed
-FROM
- projections.failed_events fe
-JOIN eventstore.events2 e ON
- e.instance_id = fe.instance_id
- AND e.sequence = fe.failed_sequence
-ON CONFLICT DO NOTHING;
\ No newline at end of file
diff --git a/cmd/setup/15/cockroach/06_cs_from_projections.sql b/cmd/setup/15/cockroach/06_cs_from_projections.sql
deleted file mode 100644
index 579afb6d4c..0000000000
--- a/cmd/setup/15/cockroach/06_cs_from_projections.sql
+++ /dev/null
@@ -1,29 +0,0 @@
-INSERT INTO projections.current_states (
- projection_name
- , instance_id
- , event_date
- , "position"
- , last_updated
-) (SELECT
- cs.projection_name
- , cs.instance_id
- , e.created_at
- , e.position
- , cs.timestamp
-FROM
- projections.current_sequences cs
-JOIN eventstore.events2 e ON
- e.instance_id = cs.instance_id
- AND e.aggregate_type = cs.aggregate_type
- AND e.sequence = cs.current_sequence
- AND cs.current_sequence = (
- SELECT
- MAX(cs2.current_sequence)
- FROM
- projections.current_sequences cs2
- WHERE
- cs.projection_name = cs2.projection_name
- AND cs.instance_id = cs2.instance_id
- )
-)
-ON CONFLICT DO NOTHING;
\ No newline at end of file
diff --git a/cmd/setup/15/cockroach/07_cs_from_adminapi.sql b/cmd/setup/15/cockroach/07_cs_from_adminapi.sql
deleted file mode 100644
index c40d13a067..0000000000
--- a/cmd/setup/15/cockroach/07_cs_from_adminapi.sql
+++ /dev/null
@@ -1,28 +0,0 @@
-INSERT INTO projections.current_states (
- projection_name
- , instance_id
- , event_date
- , "position"
- , last_updated
-) (SELECT
- cs.view_name
- , cs.instance_id
- , e.created_at
- , e.position
- , cs.last_successful_spooler_run
-FROM
- adminapi.current_sequences cs
-JOIN eventstore.events2 e ON
- e.instance_id = cs.instance_id
- AND e.sequence = cs.current_sequence
- AND cs.current_sequence = (
- SELECT
- MAX(cs2.current_sequence)
- FROM
- adminapi.current_sequences cs2
- WHERE
- cs.view_name = cs2.view_name
- AND cs.instance_id = cs2.instance_id
- )
-)
-ON CONFLICT DO NOTHING;
\ No newline at end of file
diff --git a/cmd/setup/15/cockroach/08_cs_from_auth.sql b/cmd/setup/15/cockroach/08_cs_from_auth.sql
deleted file mode 100644
index c8e7236107..0000000000
--- a/cmd/setup/15/cockroach/08_cs_from_auth.sql
+++ /dev/null
@@ -1,28 +0,0 @@
-INSERT INTO projections.current_states (
- projection_name
- , instance_id
- , event_date
- , "position"
- , last_updated
-) (SELECT
- cs.view_name
- , cs.instance_id
- , e.created_at
- , e.position
- , cs.last_successful_spooler_run
-FROM
- auth.current_sequences cs
-JOIN eventstore.events2 e ON
- e.instance_id = cs.instance_id
- AND e.sequence = cs.current_sequence
- AND cs.current_sequence = (
- SELECT
- MAX(cs2.current_sequence)
- FROM
- auth.current_sequences cs2
- WHERE
- cs.view_name = cs2.view_name
- AND cs.instance_id = cs2.instance_id
- )
-)
-ON CONFLICT DO NOTHING;
\ No newline at end of file
diff --git a/cmd/setup/15/postgres/01_new_failed_events.sql b/cmd/setup/15/postgres/01_new_failed_events.sql
deleted file mode 100644
index 5fa39c08a5..0000000000
--- a/cmd/setup/15/postgres/01_new_failed_events.sql
+++ /dev/null
@@ -1,16 +0,0 @@
-CREATE TABLE IF NOT EXISTS projections.failed_events2 (
- projection_name TEXT NOT NULL
- , instance_id TEXT NOT NULL
-
- , aggregate_type TEXT NOT NULL
- , aggregate_id TEXT NOT NULL
- , event_creation_date TIMESTAMPTZ NOT NULL
- , failed_sequence INT8 NOT NULL
-
- , failure_count INT2 NULL DEFAULT 0
- , error TEXT
- , last_failed TIMESTAMPTZ
-
- , PRIMARY KEY (projection_name, instance_id, aggregate_type, aggregate_id, failed_sequence)
-);
-CREATE INDEX IF NOT EXISTS fe2_instance_id_idx on projections.failed_events2 (instance_id);
\ No newline at end of file
diff --git a/cmd/setup/15/postgres/03_fe_from_adminapi.sql b/cmd/setup/15/postgres/03_fe_from_adminapi.sql
deleted file mode 100644
index 1616662fed..0000000000
--- a/cmd/setup/15/postgres/03_fe_from_adminapi.sql
+++ /dev/null
@@ -1,26 +0,0 @@
-INSERT INTO projections.failed_events2 (
- projection_name
- , instance_id
- , aggregate_type
- , aggregate_id
- , event_creation_date
- , failed_sequence
- , failure_count
- , error
- , last_failed
-) SELECT
- fe.view_name
- , fe.instance_id
- , e.aggregate_type
- , e.aggregate_id
- , e.created_at
- , e.sequence
- , fe.failure_count
- , fe.err_msg
- , fe.last_failed
-FROM
- adminapi.failed_events fe
-JOIN eventstore.events2 e ON
- e.instance_id = fe.instance_id
- AND e.sequence = fe.failed_sequence
-ON CONFLICT DO NOTHING;
\ No newline at end of file
diff --git a/cmd/setup/15/postgres/04_fe_from_auth.sql b/cmd/setup/15/postgres/04_fe_from_auth.sql
deleted file mode 100644
index a249293e24..0000000000
--- a/cmd/setup/15/postgres/04_fe_from_auth.sql
+++ /dev/null
@@ -1,26 +0,0 @@
-INSERT INTO projections.failed_events2 (
- projection_name
- , instance_id
- , aggregate_type
- , aggregate_id
- , event_creation_date
- , failed_sequence
- , failure_count
- , error
- , last_failed
-) SELECT
- fe.view_name
- , fe.instance_id
- , e.aggregate_type
- , e.aggregate_id
- , e.created_at
- , e.sequence
- , fe.failure_count
- , fe.err_msg
- , fe.last_failed
-FROM
- auth.failed_events fe
-JOIN eventstore.events2 e ON
- e.instance_id = fe.instance_id
- AND e.sequence = fe.failed_sequence
-ON CONFLICT DO NOTHING;
\ No newline at end of file
diff --git a/cmd/setup/15/postgres/05_current_states.sql b/cmd/setup/15/postgres/05_current_states.sql
deleted file mode 100644
index bc2f5ed771..0000000000
--- a/cmd/setup/15/postgres/05_current_states.sql
+++ /dev/null
@@ -1,15 +0,0 @@
-CREATE TABLE IF NOT EXISTS projections.current_states (
- projection_name TEXT NOT NULL
- , instance_id TEXT NOT NULL
-
- , last_updated TIMESTAMPTZ
-
- , aggregate_id TEXT
- , aggregate_type TEXT
- , "sequence" INT8
- , event_date TIMESTAMPTZ
- , "position" DECIMAL
-
- , PRIMARY KEY (projection_name, instance_id)
-);
-CREATE INDEX IF NOT EXISTS cs_instance_id_idx ON projections.current_states (instance_id);
\ No newline at end of file
diff --git a/cmd/setup/34.go b/cmd/setup/34.go
index 59854e9e97..75e4076803 100644
--- a/cmd/setup/34.go
+++ b/cmd/setup/34.go
@@ -3,17 +3,14 @@ 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
+ //go:embed 34/34_cache_schema.sql
+ addCacheSchema string
)
type AddCacheSchema struct {
@@ -21,14 +18,7 @@ type AddCacheSchema struct {
}
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())
- }
+ _, err = mig.dbClient.ExecContext(ctx, addCacheSchema)
return err
}
diff --git a/cmd/setup/34/postgres/34_cache_schema.sql b/cmd/setup/34/34_cache_schema.sql
similarity index 100%
rename from cmd/setup/34/postgres/34_cache_schema.sql
rename to cmd/setup/34/34_cache_schema.sql
diff --git a/cmd/setup/34/cockroach/34_cache_schema.sql b/cmd/setup/34/cockroach/34_cache_schema.sql
deleted file mode 100644
index 0f866b0ccd..0000000000
--- a/cmd/setup/34/cockroach/34_cache_schema.sql
+++ /dev/null
@@ -1,27 +0,0 @@
-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
diff --git a/cmd/setup/35.go b/cmd/setup/35.go
index f8473cfbfd..68e08bdfdb 100644
--- a/cmd/setup/35.go
+++ b/cmd/setup/35.go
@@ -21,7 +21,7 @@ type AddPositionToIndexEsWm struct {
}
func (mig *AddPositionToIndexEsWm) Execute(ctx context.Context, _ eventstore.Event) error {
- statements, err := readStatements(addPositionToEsWmIndex, "35", "")
+ statements, err := readStatements(addPositionToEsWmIndex, "35")
if err != nil {
return err
}
diff --git a/cmd/setup/40.go b/cmd/setup/40.go
index b16b9226f7..86cdab0d11 100644
--- a/cmd/setup/40.go
+++ b/cmd/setup/40.go
@@ -24,8 +24,7 @@ const (
)
var (
- //go:embed 40/cockroach/*.sql
- //go:embed 40/postgres/*.sql
+ //go:embed 40/*.sql
initPushFunc embed.FS
)
@@ -112,5 +111,5 @@ func (mig *InitPushFunc) inTxOrderType(ctx context.Context) (typeName string, er
}
func (mig *InitPushFunc) filePath(fileName string) string {
- return path.Join("40", mig.dbClient.Type(), fileName)
+ return path.Join("40", fileName)
}
diff --git a/cmd/setup/40/cockroach/00_in_tx_order_type.sql b/cmd/setup/40/00_in_tx_order_type.sql
similarity index 100%
rename from cmd/setup/40/cockroach/00_in_tx_order_type.sql
rename to cmd/setup/40/00_in_tx_order_type.sql
diff --git a/cmd/setup/40/postgres/01_type.sql b/cmd/setup/40/01_type.sql
similarity index 100%
rename from cmd/setup/40/postgres/01_type.sql
rename to cmd/setup/40/01_type.sql
diff --git a/cmd/setup/40/postgres/02_func.sql b/cmd/setup/40/02_func.sql
similarity index 100%
rename from cmd/setup/40/postgres/02_func.sql
rename to cmd/setup/40/02_func.sql
diff --git a/cmd/setup/40/cockroach/01_type.sql b/cmd/setup/40/cockroach/01_type.sql
deleted file mode 100644
index e26af2f828..0000000000
--- a/cmd/setup/40/cockroach/01_type.sql
+++ /dev/null
@@ -1,10 +0,0 @@
-CREATE TYPE IF NOT EXISTS eventstore.command AS (
- instance_id TEXT
- , aggregate_type TEXT
- , aggregate_id TEXT
- , command_type TEXT
- , revision INT2
- , payload JSONB
- , creator TEXT
- , owner TEXT
-);
diff --git a/cmd/setup/40/cockroach/02_func.sql b/cmd/setup/40/cockroach/02_func.sql
deleted file mode 100644
index 9cb45529ad..0000000000
--- a/cmd/setup/40/cockroach/02_func.sql
+++ /dev/null
@@ -1,137 +0,0 @@
-CREATE OR REPLACE FUNCTION eventstore.latest_aggregate_state(
- instance_id TEXT
- , aggregate_type TEXT
- , aggregate_id TEXT
-
- , sequence OUT BIGINT
- , owner OUT TEXT
-)
- LANGUAGE 'plpgsql'
-AS $$
- BEGIN
- SELECT
- COALESCE(e.sequence, 0) AS sequence
- , e.owner
- INTO
- sequence
- , owner
- FROM
- eventstore.events2 e
- WHERE
- e.instance_id = $1
- AND e.aggregate_type = $2
- AND e.aggregate_id = $3
- ORDER BY
- e.sequence DESC
- LIMIT 1;
-
- RETURN;
- END;
-$$;
-
-CREATE OR REPLACE FUNCTION eventstore.commands_to_events2(commands eventstore.command[])
- RETURNS eventstore.events2[]
- LANGUAGE 'plpgsql'
-AS $$
-DECLARE
- current_sequence BIGINT;
- current_owner TEXT;
-
- instance_id TEXT;
- aggregate_type TEXT;
- aggregate_id TEXT;
-
- _events eventstore.events2[];
-
- _aggregates CURSOR FOR
- select
- DISTINCT ("c").instance_id
- , ("c").aggregate_type
- , ("c").aggregate_id
- FROM
- UNNEST(commands) AS c;
-BEGIN
- OPEN _aggregates;
- LOOP
- FETCH NEXT IN _aggregates INTO instance_id, aggregate_type, aggregate_id;
- -- crdb does not support EXIT WHEN NOT FOUND
- EXIT WHEN instance_id IS NULL;
-
- SELECT
- *
- INTO
- current_sequence
- , current_owner
- FROM eventstore.latest_aggregate_state(
- instance_id
- , aggregate_type
- , aggregate_id
- );
-
- -- RETURN QUERY is not supported by crdb: https://github.com/cockroachdb/cockroach/issues/105240
- SELECT
- ARRAY_CAT(_events, ARRAY_AGG(e))
- INTO
- _events
- FROM (
- SELECT
- ("c").instance_id
- , ("c").aggregate_type
- , ("c").aggregate_id
- , ("c").command_type -- AS event_type
- , COALESCE(current_sequence, 0) + ROW_NUMBER() OVER () -- AS sequence
- , ("c").revision
- , NOW() -- AS created_at
- , ("c").payload
- , ("c").creator
- , COALESCE(current_owner, ("c").owner) -- AS owner
- , cluster_logical_timestamp() -- AS position
- , ordinality::{{ .InTxOrderType }} -- AS in_tx_order
- FROM
- UNNEST(commands) WITH ORDINALITY AS c
- WHERE
- ("c").instance_id = instance_id
- AND ("c").aggregate_type = aggregate_type
- AND ("c").aggregate_id = aggregate_id
- ) AS e;
- END LOOP;
- CLOSE _aggregates;
- RETURN _events;
-END;
-$$;
-
-CREATE OR REPLACE FUNCTION eventstore.push(commands eventstore.command[]) RETURNS SETOF eventstore.events2 AS $$
- INSERT INTO eventstore.events2
- SELECT
- ("e").instance_id
- , ("e").aggregate_type
- , ("e").aggregate_id
- , ("e").event_type
- , ("e").sequence
- , ("e").revision
- , ("e").created_at
- , ("e").payload
- , ("e").creator
- , ("e").owner
- , ("e")."position"
- , ("e").in_tx_order
- FROM
- UNNEST(eventstore.commands_to_events2(commands)) e
- ORDER BY
- in_tx_order
- RETURNING *
-$$ LANGUAGE SQL;
-
-/*
-select (c).* from UNNEST(eventstore.commands_to_events2(
-ARRAY[
- ROW('', 'system', 'SYSTEM', 'ct1', 1, '{"key": "value"}', 'c1', 'SYSTEM')
- , ROW('', 'system', 'SYSTEM', 'ct2', 1, '{"key": "value"}', 'c1', 'SYSTEM')
- , ROW('289525561255060732', 'org', '289575074711790844', 'ct3', 1, '{"key": "value"}', 'c1', '289575074711790844')
- , ROW('289525561255060732', 'user', '289575075164906748', 'ct3', 1, '{"key": "value"}', 'c1', '289575074711790844')
- , ROW('289525561255060732', 'oidc_session', 'V2_289575178579535100', 'ct3', 1, '{"key": "value"}', 'c1', '289575074711790844')
- , ROW('', 'system', 'SYSTEM', 'ct3', 1, '{"key": "value"}', 'c1', 'SYSTEM')
-]::eventstore.command[]
-) )c;
-*/
-
diff --git a/cmd/setup/40/postgres/00_in_tx_order_type.sql b/cmd/setup/40/postgres/00_in_tx_order_type.sql
deleted file mode 100644
index 68b7daf984..0000000000
--- a/cmd/setup/40/postgres/00_in_tx_order_type.sql
+++ /dev/null
@@ -1,5 +0,0 @@
-SELECT data_type
-FROM information_schema.columns
-WHERE table_schema = 'eventstore'
-AND table_name = 'events2'
-AND column_name = 'in_tx_order';
diff --git a/cmd/setup/43.go b/cmd/setup/43.go
index 844c25cf24..1fa09773bc 100644
--- a/cmd/setup/43.go
+++ b/cmd/setup/43.go
@@ -12,8 +12,7 @@ import (
)
var (
- //go:embed 43/cockroach/*.sql
- //go:embed 43/postgres/*.sql
+ //go:embed 43/*.sql
createFieldsDomainIndex embed.FS
)
@@ -22,7 +21,7 @@ type CreateFieldsDomainIndex struct {
}
func (mig *CreateFieldsDomainIndex) Execute(ctx context.Context, _ eventstore.Event) error {
- statements, err := readStatements(createFieldsDomainIndex, "43", mig.dbClient.Type())
+ statements, err := readStatements(createFieldsDomainIndex, "43")
if err != nil {
return err
}
diff --git a/cmd/setup/43/postgres/43.sql b/cmd/setup/43/43.sql
similarity index 100%
rename from cmd/setup/43/postgres/43.sql
rename to cmd/setup/43/43.sql
diff --git a/cmd/setup/43/cockroach/43.sql b/cmd/setup/43/cockroach/43.sql
deleted file mode 100644
index 9152130970..0000000000
--- a/cmd/setup/43/cockroach/43.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-CREATE INDEX CONCURRENTLY IF NOT EXISTS fields_instance_domains_idx
-ON eventstore.fields (object_id)
-WHERE object_type = 'instance_domain' AND field_name = 'domain';
\ No newline at end of file
diff --git a/cmd/setup/44.go b/cmd/setup/44.go
index 11c355a053..5eb2f8d5c1 100644
--- a/cmd/setup/44.go
+++ b/cmd/setup/44.go
@@ -21,7 +21,7 @@ type ReplaceCurrentSequencesIndex struct {
}
func (mig *ReplaceCurrentSequencesIndex) Execute(ctx context.Context, _ eventstore.Event) error {
- statements, err := readStatements(replaceCurrentSequencesIndex, "44", "")
+ statements, err := readStatements(replaceCurrentSequencesIndex, "44")
if err != nil {
return err
}
diff --git a/cmd/setup/46.go b/cmd/setup/46.go
index e48b16e4b0..3593a1b668 100644
--- a/cmd/setup/46.go
+++ b/cmd/setup/46.go
@@ -21,7 +21,7 @@ var (
)
func (mig *InitPermissionFunctions) Execute(ctx context.Context, _ eventstore.Event) error {
- statements, err := readStatements(permissionFunctions, "46", "")
+ statements, err := readStatements(permissionFunctions, "46")
if err != nil {
return err
}
diff --git a/cmd/setup/49.go b/cmd/setup/49.go
index 28bf797110..8465589140 100644
--- a/cmd/setup/49.go
+++ b/cmd/setup/49.go
@@ -21,7 +21,7 @@ var (
)
func (mig *InitPermittedOrgsFunction) Execute(ctx context.Context, _ eventstore.Event) error {
- statements, err := readStatements(permittedOrgsFunction, "49", "")
+ statements, err := readStatements(permittedOrgsFunction, "49")
if err != nil {
return err
}
diff --git a/cmd/setup/53.go b/cmd/setup/53.go
new file mode 100644
index 0000000000..83a7b1c0e2
--- /dev/null
+++ b/cmd/setup/53.go
@@ -0,0 +1,37 @@
+package setup
+
+import (
+ "context"
+ "embed"
+ "fmt"
+
+ "github.com/zitadel/logging"
+
+ "github.com/zitadel/zitadel/internal/database"
+ "github.com/zitadel/zitadel/internal/eventstore"
+)
+
+type InitPermittedOrgsFunction53 struct {
+ dbClient *database.DB
+}
+
+//go:embed 53/*.sql
+var permittedOrgsFunction53 embed.FS
+
+func (mig *InitPermittedOrgsFunction53) Execute(ctx context.Context, _ eventstore.Event) error {
+ statements, err := readStatements(permittedOrgsFunction53, "53")
+ 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 (*InitPermittedOrgsFunction53) String() string {
+ return "53_init_permitted_orgs_function"
+}
diff --git a/cmd/setup/53/01-get-permissions-from-JSON.sql b/cmd/setup/53/01-get-permissions-from-JSON.sql
new file mode 100644
index 0000000000..b6415fa180
--- /dev/null
+++ b/cmd/setup/53/01-get-permissions-from-JSON.sql
@@ -0,0 +1,43 @@
+DROP FUNCTION IF EXISTS eventstore.get_system_permissions;
+
+CREATE OR REPLACE FUNCTION eventstore.get_system_permissions(
+ permissions_json JSONB
+ /*
+ [
+ {
+ "member_type": "System",
+ "aggregate_id": "",
+ "object_id": "",
+ "permissions": ["iam.read", "iam.write", "iam.polic.read"]
+ },
+ {
+ "member_type": "IAM",
+ "aggregate_id": "310716990375453665",
+ "object_id": "",
+ "permissions": ["iam.read", "iam.write", "iam.polic.read"]
+ }
+ ]
+ */
+ , permm TEXT
+)
+RETURNS TABLE (
+ member_type TEXT,
+ aggregate_id TEXT,
+ object_id TEXT
+)
+ LANGUAGE 'plpgsql'
+AS $$
+BEGIN
+ RETURN QUERY
+ SELECT res.member_type, res.aggregate_id, res.object_id FROM (
+ SELECT
+ (perm)->>'member_type' AS member_type,
+ (perm)->>'aggregate_id' AS aggregate_id,
+ (perm)->>'object_id' AS object_id,
+ permission
+ FROM jsonb_array_elements(permissions_json) AS perm
+ CROSS JOIN jsonb_array_elements_text(perm->'permissions') AS permission) AS res
+ WHERE res. permission= permm;
+END;
+$$;
+
diff --git a/cmd/setup/53/02-permitted_orgs_function.sql b/cmd/setup/53/02-permitted_orgs_function.sql
new file mode 100644
index 0000000000..b6f61c6225
--- /dev/null
+++ b/cmd/setup/53/02-permitted_orgs_function.sql
@@ -0,0 +1,144 @@
+DROP FUNCTION IF EXISTS eventstore.check_system_user_perms;
+
+CREATE OR REPLACE FUNCTION eventstore.check_system_user_perms(
+ system_user_perms JSONB
+ , perm TEXT
+ , filter_orgs TEXT
+
+ , org_ids OUT TEXT[]
+)
+ LANGUAGE 'plpgsql'
+AS $$
+BEGIN
+
+ WITH found_permissions(member_type, aggregate_id, object_id ) AS (
+ SELECT * FROM eventstore.get_system_permissions(
+ system_user_perms,
+ perm)
+ )
+
+ SELECT array_agg(DISTINCT o.org_id) INTO org_ids
+ FROM eventstore.instance_orgs o, found_permissions
+ WHERE
+ CASE WHEN (SELECT TRUE WHERE found_permissions.member_type = 'System' LIMIT 1) THEN
+ TRUE
+ WHEN (SELECT TRUE WHERE found_permissions.member_type = 'IAM' LIMIT 1) THEN
+ -- aggregate_id not present
+ CASE WHEN (SELECT TRUE WHERE '' = ANY (
+ (
+ SELECT array_agg(found_permissions.aggregate_id)
+ FROM found_permissions
+ WHERE member_type = 'IAM'
+ GROUP BY member_type
+ LIMIT 1
+ )::TEXT[])) THEN
+ TRUE
+ -- aggregate_id is present
+ ELSE
+ o.instance_id = ANY (
+ (
+ SELECT array_agg(found_permissions.aggregate_id)
+ FROM found_permissions
+ WHERE member_type = 'IAM'
+ GROUP BY member_type
+ LIMIT 1
+ )::TEXT[])
+ END
+ WHEN (SELECT TRUE WHERE found_permissions.member_type = 'Organization' LIMIT 1) THEN
+ -- aggregate_id not present
+ CASE WHEN (SELECT TRUE WHERE '' = ANY (
+ (
+ SELECT array_agg(found_permissions.aggregate_id)
+ FROM found_permissions
+ WHERE member_type = 'Organization'
+ GROUP BY member_type
+ LIMIT 1
+ )::TEXT[])) THEN
+ TRUE
+ -- aggregate_id is present
+ ELSE
+ o.org_id = ANY (
+ (
+ SELECT array_agg(found_permissions.aggregate_id)
+ FROM found_permissions
+ WHERE member_type = 'Organization'
+ GROUP BY member_type
+ LIMIT 1
+ )::TEXT[])
+ END
+ END
+ AND
+ CASE WHEN filter_orgs != ''
+ THEN o.org_id IN (filter_orgs)
+ ELSE TRUE END
+ LIMIT 1;
+END;
+$$;
+
+
+DROP FUNCTION IF EXISTS eventstore.permitted_orgs;
+
+CREATE OR REPLACE FUNCTION eventstore.permitted_orgs(
+ instanceId TEXT
+ , userId TEXT
+ , system_user_perms JSONB
+ , perm TEXT
+ , filter_orgs TEXT
+
+ , org_ids OUT TEXT[]
+)
+ LANGUAGE 'plpgsql'
+AS $$
+BEGIN
+
+ -- if system user
+ IF system_user_perms IS NOT NULL THEN
+ org_ids := eventstore.check_system_user_perms(system_user_perms, perm, filter_orgs);
+ -- if human/machine user
+ ELSE
+ DECLARE
+ matched_roles TEXT[]; -- roles containing permission
+ BEGIN
+
+ SELECT array_agg(rp.role) INTO matched_roles
+ FROM eventstore.role_permissions rp
+ WHERE rp.instance_id = instanceId
+ AND rp.permission = perm;
+
+ -- First try if the permission was granted thru an instance-level role
+ DECLARE
+ has_instance_permission bool;
+ BEGIN
+ SELECT true INTO has_instance_permission
+ FROM eventstore.instance_members im
+ WHERE im.role = ANY(matched_roles)
+ AND im.instance_id = instanceId
+ AND im.user_id = userId
+ LIMIT 1;
+
+ IF has_instance_permission THEN
+ -- Return all organizations or only those in filter_orgs
+ SELECT array_agg(o.org_id) INTO org_ids
+ FROM eventstore.instance_orgs o
+ WHERE o.instance_id = instanceId
+ AND CASE WHEN filter_orgs != ''
+ THEN o.org_id IN (filter_orgs)
+ ELSE TRUE END;
+ RETURN;
+ END IF;
+ END;
+
+ -- Return the organizations where permission were granted thru org-level roles
+ SELECT array_agg(sub.org_id) INTO org_ids
+ FROM (
+ SELECT DISTINCT om.org_id
+ FROM eventstore.org_members om
+ WHERE om.role = ANY(matched_roles)
+ AND om.instance_id = instanceID
+ AND om.user_id = userId
+ ) AS sub;
+ END;
+ END IF;
+END;
+$$;
+
diff --git a/cmd/setup/cleanup.go b/cmd/setup/cleanup.go
index 943ac164ea..e0a07c0a9d 100644
--- a/cmd/setup/cleanup.go
+++ b/cmd/setup/cleanup.go
@@ -35,7 +35,7 @@ func Cleanup(config *Config) {
logging.OnError(err).Fatal("unable to connect to database")
config.Eventstore.Pusher = new_es.NewEventstore(dbClient)
- config.Eventstore.Querier = old_es.NewCRDB(dbClient)
+ config.Eventstore.Querier = old_es.NewPostgres(dbClient)
es := eventstore.NewEventstore(config.Eventstore)
step, err := migration.LastStuckStep(ctx, es)
diff --git a/cmd/setup/config.go b/cmd/setup/config.go
index 2a94b7919e..4742b94c7b 100644
--- a/cmd/setup/config.go
+++ b/cmd/setup/config.go
@@ -12,7 +12,7 @@ import (
"github.com/zitadel/zitadel/cmd/encryption"
"github.com/zitadel/zitadel/cmd/hooks"
"github.com/zitadel/zitadel/internal/actions"
- internal_authz "github.com/zitadel/zitadel/internal/api/authz"
+ "github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/oidc"
"github.com/zitadel/zitadel/internal/api/ui/login"
"github.com/zitadel/zitadel/internal/cache/connector"
@@ -22,6 +22,7 @@ import (
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore"
+ "github.com/zitadel/zitadel/internal/execution"
"github.com/zitadel/zitadel/internal/id"
"github.com/zitadel/zitadel/internal/notification/handlers"
"github.com/zitadel/zitadel/internal/query/projection"
@@ -34,7 +35,8 @@ type Config struct {
Database database.Config
Caches *connector.CachesConfig
SystemDefaults systemdefaults.SystemDefaults
- InternalAuthZ internal_authz.Config
+ InternalAuthZ authz.Config
+ SystemAuthZ authz.Config
ExternalDomain string
ExternalPort uint16
ExternalSecure bool
@@ -45,6 +47,7 @@ type Config struct {
Machine *id.Config
Projections projection.Config
Notifications handlers.WorkerConfig
+ Executions execution.WorkerConfig
Eventstore *eventstore.Config
InitProjections InitProjections
@@ -53,7 +56,7 @@ type Config struct {
Login login.Config
WebAuthNName string
Telemetry *handlers.TelemetryPusherConfig
- SystemAPIUsers map[string]*internal_authz.SystemAPIUser
+ SystemAPIUsers map[string]*authz.SystemAPIUser
}
type InitProjections struct {
@@ -68,12 +71,12 @@ func MustNewConfig(v *viper.Viper) *Config {
err := v.Unmarshal(config,
viper.DecodeHook(mapstructure.ComposeDecodeHookFunc(
hooks.SliceTypeStringDecode[*domain.CustomMessageText],
- hooks.SliceTypeStringDecode[internal_authz.RoleMapping],
- hooks.MapTypeStringDecode[string, *internal_authz.SystemAPIUser],
+ hooks.SliceTypeStringDecode[authz.RoleMapping],
+ hooks.MapTypeStringDecode[string, *authz.SystemAPIUser],
hooks.MapHTTPHeaderStringDecode,
- database.DecodeHook,
+ database.DecodeHook(false),
actions.HTTPConfigDecodeHook,
- hook.EnumHookFunc(internal_authz.MemberTypeString),
+ hook.EnumHookFunc(authz.MemberTypeString),
hook.Base64ToBytesHookFunc(),
hook.TagToLanguageHookFunc(),
mapstructure.StringToTimeDurationHookFunc(),
@@ -146,6 +149,7 @@ type Steps struct {
s50IDPTemplate6UsePKCE *IDPTemplate6UsePKCE
s51IDPTemplate6RootCA *IDPTemplate6RootCA
s52IDPTemplate6LDAP2 *IDPTemplate6LDAP2
+ s53InitPermittedOrgsFunction *InitPermittedOrgsFunction53
}
func MustNewSteps(v *viper.Viper) *Steps {
diff --git a/cmd/setup/river_queue_repeatable.go b/cmd/setup/river_queue_repeatable.go
index 5248894a8f..bfbd3ee581 100644
--- a/cmd/setup/river_queue_repeatable.go
+++ b/cmd/setup/river_queue_repeatable.go
@@ -13,9 +13,6 @@ type RiverMigrateRepeatable struct {
}
func (mig *RiverMigrateRepeatable) Execute(ctx context.Context, _ eventstore.Event) error {
- if mig.client.Type() != "postgres" {
- return nil
- }
return queue.NewMigrator(mig.client).Execute(ctx)
}
diff --git a/cmd/setup/setup.go b/cmd/setup/setup.go
index f13802ffa0..fe628c8df2 100644
--- a/cmd/setup/setup.go
+++ b/cmd/setup/setup.go
@@ -55,7 +55,7 @@ func New() *cobra.Command {
Short: "setup ZITADEL instance",
Long: `sets up data to start ZITADEL.
Requirements:
-- cockroachdb`,
+- postgreSQL`,
Run: func(cmd *cobra.Command, args []string) {
err := tls.ModeFromFlag(cmd)
logging.OnError(err).Fatal("invalid tlsMode")
@@ -107,7 +107,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
dbClient, err := database.Connect(config.Database, false)
logging.OnError(err).Fatal("unable to connect to database")
- config.Eventstore.Querier = old_es.NewCRDB(dbClient)
+ config.Eventstore.Querier = old_es.NewPostgres(dbClient)
esV3 := new_es.NewEventstore(dbClient)
config.Eventstore.Pusher = esV3
config.Eventstore.Searcher = esV3
@@ -137,7 +137,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
steps.s5LastFailed = &LastFailed{dbClient: dbClient.DB}
steps.s6OwnerRemoveColumns = &OwnerRemoveColumns{dbClient: dbClient.DB}
- steps.s7LogstoreTables = &LogstoreTables{dbClient: dbClient.DB, username: config.Database.Username(), dbType: config.Database.Type()}
+ steps.s7LogstoreTables = &LogstoreTables{dbClient: dbClient.DB, username: config.Database.Username()}
steps.s8AuthTokens = &AuthTokenIndexes{dbClient: dbClient}
steps.CorrectCreationDate.dbClient = dbClient
steps.s12AddOTPColumns = &AddOTPColumns{dbClient: dbClient}
@@ -179,6 +179,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
steps.s50IDPTemplate6UsePKCE = &IDPTemplate6UsePKCE{dbClient: dbClient}
steps.s51IDPTemplate6RootCA = &IDPTemplate6RootCA{dbClient: dbClient}
steps.s52IDPTemplate6LDAP2 = &IDPTemplate6LDAP2{dbClient: dbClient}
+ steps.s53InitPermittedOrgsFunction = &InitPermittedOrgsFunction53{dbClient: dbClient}
err = projection.Create(ctx, dbClient, eventstoreClient, config.Projections, nil, nil, nil)
logging.OnError(err).Fatal("unable to start projections")
@@ -220,6 +221,7 @@ func Setup(ctx context.Context, config *Config, steps *Steps, masterKey string)
steps.s50IDPTemplate6UsePKCE,
steps.s51IDPTemplate6RootCA,
steps.s52IDPTemplate6LDAP2,
+ steps.s53InitPermittedOrgsFunction,
} {
mustExecuteMigration(ctx, eventstoreClient, step, "migration failed")
}
@@ -308,8 +310,8 @@ func mustExecuteMigration(ctx context.Context, eventstoreClient *eventstore.Even
// 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) {
- stmt, err := fs.ReadFile(path.Join(folder, typ, filename))
+func readStmt(fs embed.FS, folder, filename string) (string, error) {
+ stmt, err := fs.ReadFile(path.Join(folder, filename))
return string(stmt), err
}
@@ -322,16 +324,15 @@ type statement struct {
// 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 := path.Join(folder, typ)
- dir, err := fs.ReadDir(basePath)
+func readStatements(fs embed.FS, folder string) ([]statement, error) {
+ dir, err := fs.ReadDir(folder)
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())
+ statements[i].query, err = readStmt(fs, folder, file.Name())
if err != nil {
return nil, err
}
@@ -412,7 +413,7 @@ func startCommandsQueries(
sessionTokenVerifier,
func(q *query.Queries) domain.PermissionCheck {
return func(ctx context.Context, permission, orgID, resourceID string) (err error) {
- return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
+ return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, config.SystemAuthZ.RolePermissionMappings, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
}
},
0, // not needed for projections
@@ -437,7 +438,7 @@ func startCommandsQueries(
authZRepo, err := authz.Start(queries, eventstoreClient, dbClient, keys.OIDC, config.ExternalSecure)
logging.OnError(err).Fatal("unable to start authz repo")
permissionCheck := func(ctx context.Context, permission, orgID, resourceID string) (err error) {
- return internal_authz.CheckPermission(ctx, authZRepo, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
+ return internal_authz.CheckPermission(ctx, authZRepo, config.SystemAuthZ.RolePermissionMappings, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
}
commands, err := command.StartCommands(ctx,
@@ -472,9 +473,6 @@ func startCommandsQueries(
)
logging.OnError(err).Fatal("unable to start commands")
- if !config.Notifications.LegacyEnabled && dbClient.Type() == "cockroach" {
- logging.Fatal("notifications must be set to LegacyEnabled=true when using CockroachDB")
- }
q, err := queue.NewQueue(&queue.Config{
Client: dbClient,
})
@@ -501,7 +499,6 @@ func startCommandsQueries(
keys.SMS,
keys.OIDC,
config.OIDC.DefaultBackChannelLogoutLifetime,
- dbClient,
q,
)
diff --git a/cmd/start/config.go b/cmd/start/config.go
index 910759b653..e973c40479 100644
--- a/cmd/start/config.go
+++ b/cmd/start/config.go
@@ -11,7 +11,7 @@ import (
"github.com/zitadel/zitadel/cmd/hooks"
"github.com/zitadel/zitadel/internal/actions"
admin_es "github.com/zitadel/zitadel/internal/admin/repository/eventsourcing"
- internal_authz "github.com/zitadel/zitadel/internal/api/authz"
+ "github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/http/middleware"
"github.com/zitadel/zitadel/internal/api/oidc"
"github.com/zitadel/zitadel/internal/api/saml"
@@ -27,6 +27,7 @@ import (
"github.com/zitadel/zitadel/internal/database"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore"
+ "github.com/zitadel/zitadel/internal/execution"
"github.com/zitadel/zitadel/internal/id"
"github.com/zitadel/zitadel/internal/logstore"
"github.com/zitadel/zitadel/internal/notification/handlers"
@@ -56,6 +57,7 @@ type Config struct {
Profiler profiler.Config
Projections projection.Config
Notifications handlers.WorkerConfig
+ Executions execution.WorkerConfig
Auth auth_es.Config
Admin admin_es.Config
UserAgentCookie *middleware.UserAgentCookieConfig
@@ -65,12 +67,13 @@ type Config struct {
Login login.Config
Console console.Config
AssetStorage static_config.AssetStorageConfig
- InternalAuthZ internal_authz.Config
+ InternalAuthZ authz.Config
+ SystemAuthZ authz.Config
SystemDefaults systemdefaults.SystemDefaults
EncryptionKeys *encryption.EncryptionKeyConfig
DefaultInstance command.InstanceSetup
AuditLogRetention time.Duration
- SystemAPIUsers map[string]*internal_authz.SystemAPIUser
+ SystemAPIUsers map[string]*authz.SystemAPIUser
CustomerPortal string
Machine *id.Config
Actions *actions.Config
@@ -94,12 +97,12 @@ func MustNewConfig(v *viper.Viper) *Config {
err := v.Unmarshal(config,
viper.DecodeHook(mapstructure.ComposeDecodeHookFunc(
hooks.SliceTypeStringDecode[*domain.CustomMessageText],
- hooks.SliceTypeStringDecode[internal_authz.RoleMapping],
- hooks.MapTypeStringDecode[string, *internal_authz.SystemAPIUser],
+ hooks.SliceTypeStringDecode[authz.RoleMapping],
+ hooks.MapTypeStringDecode[string, *authz.SystemAPIUser],
hooks.MapHTTPHeaderStringDecode,
- database.DecodeHook,
+ database.DecodeHook(false),
actions.HTTPConfigDecodeHook,
- hook.EnumHookFunc(internal_authz.MemberTypeString),
+ hook.EnumHookFunc(authz.MemberTypeString),
hooks.MapTypeStringDecode[domain.Feature, any],
hooks.SliceTypeStringDecode[*command.SetQuota],
hook.Base64ToBytesHookFunc(),
diff --git a/cmd/start/start.go b/cmd/start/start.go
index 76ffdb8921..e3d84625b4 100644
--- a/cmd/start/start.go
+++ b/cmd/start/start.go
@@ -4,7 +4,6 @@ import (
"context"
"crypto/tls"
_ "embed"
- "errors"
"fmt"
"math"
"net/http"
@@ -35,6 +34,7 @@ import (
"github.com/zitadel/zitadel/internal/api"
"github.com/zitadel/zitadel/internal/api/assets"
internal_authz "github.com/zitadel/zitadel/internal/api/authz"
+ action_v2_beta "github.com/zitadel/zitadel/internal/api/grpc/action/v2beta"
"github.com/zitadel/zitadel/internal/api/grpc/admin"
"github.com/zitadel/zitadel/internal/api/grpc/auth"
feature_v2 "github.com/zitadel/zitadel/internal/api/grpc/feature/v2"
@@ -45,11 +45,9 @@ import (
oidc_v2beta "github.com/zitadel/zitadel/internal/api/grpc/oidc/v2beta"
org_v2 "github.com/zitadel/zitadel/internal/api/grpc/org/v2"
org_v2beta "github.com/zitadel/zitadel/internal/api/grpc/org/v2beta"
- action_v3_alpha "github.com/zitadel/zitadel/internal/api/grpc/resources/action/v3alpha"
"github.com/zitadel/zitadel/internal/api/grpc/resources/debug_events/debug_events"
user_v3_alpha "github.com/zitadel/zitadel/internal/api/grpc/resources/user/v3alpha"
userschema_v3_alpha "github.com/zitadel/zitadel/internal/api/grpc/resources/userschema/v3alpha"
- "github.com/zitadel/zitadel/internal/api/grpc/resources/webkey/v3"
saml_v2 "github.com/zitadel/zitadel/internal/api/grpc/saml/v2"
session_v2 "github.com/zitadel/zitadel/internal/api/grpc/session/v2"
session_v2beta "github.com/zitadel/zitadel/internal/api/grpc/session/v2beta"
@@ -58,6 +56,7 @@ import (
"github.com/zitadel/zitadel/internal/api/grpc/system"
user_v2 "github.com/zitadel/zitadel/internal/api/grpc/user/v2"
user_v2beta "github.com/zitadel/zitadel/internal/api/grpc/user/v2beta"
+ webkey "github.com/zitadel/zitadel/internal/api/grpc/webkey/v2beta"
http_util "github.com/zitadel/zitadel/internal/api/http"
"github.com/zitadel/zitadel/internal/api/http/middleware"
"github.com/zitadel/zitadel/internal/api/idp"
@@ -82,13 +81,14 @@ import (
"github.com/zitadel/zitadel/internal/eventstore"
old_es "github.com/zitadel/zitadel/internal/eventstore/repository/sql"
new_es "github.com/zitadel/zitadel/internal/eventstore/v3"
+ "github.com/zitadel/zitadel/internal/execution"
"github.com/zitadel/zitadel/internal/i18n"
"github.com/zitadel/zitadel/internal/id"
"github.com/zitadel/zitadel/internal/integration/sink"
"github.com/zitadel/zitadel/internal/logstore"
"github.com/zitadel/zitadel/internal/logstore/emitters/access"
- "github.com/zitadel/zitadel/internal/logstore/emitters/execution"
- "github.com/zitadel/zitadel/internal/logstore/emitters/stdout"
+ emit_execution "github.com/zitadel/zitadel/internal/logstore/emitters/execution"
+ emit_stdout "github.com/zitadel/zitadel/internal/logstore/emitters/stdout"
"github.com/zitadel/zitadel/internal/logstore/record"
"github.com/zitadel/zitadel/internal/net"
"github.com/zitadel/zitadel/internal/notification"
@@ -107,7 +107,7 @@ func New(server chan<- *Server) *cobra.Command {
Short: "starts ZITADEL instance",
Long: `starts ZITADEL.
Requirements:
-- cockroachdb`,
+- postgreSQL`,
RunE: func(cmd *cobra.Command, args []string) error {
err := cmd_tls.ModeFromFlag(cmd)
if err != nil {
@@ -163,7 +163,7 @@ func startZitadel(ctx context.Context, config *Config, masterKey string, server
config.Eventstore.Pusher = new_es.NewEventstore(dbClient)
config.Eventstore.Searcher = new_es.NewEventstore(dbClient)
- config.Eventstore.Querier = old_es.NewCRDB(dbClient)
+ config.Eventstore.Querier = old_es.NewPostgres(dbClient)
eventstoreClient := eventstore.NewEventstore(config.Eventstore)
eventstoreV4 := es_v4.NewEventstoreFromOne(es_v4_pg.New(dbClient, &es_v4_pg.Config{
MaxRetries: config.Eventstore.MaxRetries,
@@ -193,7 +193,7 @@ func startZitadel(ctx context.Context, config *Config, masterKey string, server
sessionTokenVerifier,
func(q *query.Queries) domain.PermissionCheck {
return func(ctx context.Context, permission, orgID, resourceID string) (err error) {
- return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
+ return internal_authz.CheckPermission(ctx, &authz_es.UserMembershipRepo{Queries: q}, config.SystemAuthZ.RolePermissionMappings, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
}
},
config.AuditLogRetention,
@@ -209,7 +209,7 @@ func startZitadel(ctx context.Context, config *Config, masterKey string, server
return fmt.Errorf("error starting authz repo: %w", err)
}
permissionCheck := func(ctx context.Context, permission, orgID, resourceID string) (err error) {
- return internal_authz.CheckPermission(ctx, authZRepo, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
+ return internal_authz.CheckPermission(ctx, authZRepo, config.SystemAuthZ.RolePermissionMappings, config.InternalAuthZ.RolePermissionMappings, permission, orgID, resourceID)
}
storage, err := config.AssetStorage.NewStorage(dbClient.DB)
@@ -257,11 +257,12 @@ func startZitadel(ctx context.Context, config *Config, masterKey string, server
defer closeSink()
clock := clockpkg.New()
- actionsExecutionStdoutEmitter, err := logstore.NewEmitter[*record.ExecutionLog](ctx, clock, &logstore.EmitterConfig{Enabled: config.LogStore.Execution.Stdout.Enabled}, stdout.NewStdoutEmitter[*record.ExecutionLog]())
+ actionsExecutionStdoutEmitter, err := logstore.NewEmitter(ctx, clock, &logstore.EmitterConfig{Enabled: config.LogStore.Execution.Stdout.Enabled}, emit_stdout.NewStdoutEmitter[*record.ExecutionLog]())
if err != nil {
return err
}
- actionsExecutionDBEmitter, err := logstore.NewEmitter[*record.ExecutionLog](ctx, clock, config.Quotas.Execution, execution.NewDatabaseLogStorage(dbClient, commands, queries))
+
+ actionsExecutionDBEmitter, err := logstore.NewEmitter(ctx, clock, config.Quotas.Execution, emit_execution.NewDatabaseLogStorage(dbClient, commands, queries))
if err != nil {
return err
}
@@ -269,9 +270,6 @@ func startZitadel(ctx context.Context, config *Config, masterKey string, server
actionsLogstoreSvc := logstore.New(queries, actionsExecutionDBEmitter, actionsExecutionStdoutEmitter)
actions.SetLogstoreService(actionsLogstoreSvc)
- if !config.Notifications.LegacyEnabled && dbClient.Type() == "cockroach" {
- return errors.New("notifications must be set to LegacyEnabled=true when using CockroachDB")
- }
q, err := queue.NewQueue(&queue.Config{
Client: dbClient,
})
@@ -300,11 +298,20 @@ func startZitadel(ctx context.Context, config *Config, masterKey string, server
keys.SMS,
keys.OIDC,
config.OIDC.DefaultBackChannelLogoutLifetime,
- dbClient,
q,
)
notification.Start(ctx)
+ execution.Register(
+ ctx,
+ config.Projections.Customizations["executions"],
+ config.Executions,
+ queries,
+ eventstoreClient.EventTypes(),
+ q,
+ )
+ execution.Start(ctx)
+
if err = q.Start(ctx); err != nil {
return err
}
@@ -395,23 +402,23 @@ func startAPIs(
return nil, err
}
- accessStdoutEmitter, err := logstore.NewEmitter[*record.AccessLog](ctx, clock, &logstore.EmitterConfig{Enabled: config.LogStore.Access.Stdout.Enabled}, stdout.NewStdoutEmitter[*record.AccessLog]())
+ accessStdoutEmitter, err := logstore.NewEmitter(ctx, clock, &logstore.EmitterConfig{Enabled: config.LogStore.Access.Stdout.Enabled}, emit_stdout.NewStdoutEmitter[*record.AccessLog]())
if err != nil {
return nil, err
}
- accessDBEmitter, err := logstore.NewEmitter[*record.AccessLog](ctx, clock, &config.Quotas.Access.EmitterConfig, access.NewDatabaseLogStorage(dbClient, commands, queries))
+ accessDBEmitter, err := logstore.NewEmitter(ctx, clock, &config.Quotas.Access.EmitterConfig, access.NewDatabaseLogStorage(dbClient, commands, queries))
if err != nil {
return nil, err
}
- accessSvc := logstore.New[*record.AccessLog](queries, accessDBEmitter, accessStdoutEmitter)
+ accessSvc := logstore.New(queries, accessDBEmitter, accessStdoutEmitter)
exhaustedCookieHandler := http_util.NewCookieHandler(
http_util.WithUnsecure(),
http_util.WithNonHttpOnly(),
http_util.WithMaxAge(int(math.Floor(config.Quotas.Access.ExhaustedCookieMaxAge.Seconds()))),
)
limitingAccessInterceptor := middleware.NewAccessInterceptor(accessSvc, exhaustedCookieHandler, &config.Quotas.Access.AccessConfig)
- apis, err := api.New(ctx, config.Port, router, queries, verifier, config.InternalAuthZ, tlsConfig, config.ExternalDomain, append(config.InstanceHostHeaders, config.PublicHostHeaders...), limitingAccessInterceptor)
+ apis, err := api.New(ctx, config.Port, router, queries, verifier, config.SystemAuthZ, config.InternalAuthZ, tlsConfig, config.ExternalDomain, append(config.InstanceHostHeaders, config.PublicHostHeaders...), limitingAccessInterceptor)
if err != nil {
return nil, fmt.Errorf("error creating api %w", err)
}
@@ -477,7 +484,7 @@ func startAPIs(
if err := apis.RegisterService(ctx, idp_v2.CreateServer(commands, queries, permissionCheck)); err != nil {
return nil, err
}
- if err := apis.RegisterService(ctx, action_v3_alpha.CreateServer(config.SystemDefaults, commands, queries, domain.AllActionFunctions, apis.ListGrpcMethods, apis.ListGrpcServices)); err != nil {
+ if err := apis.RegisterService(ctx, action_v2_beta.CreateServer(config.SystemDefaults, commands, queries, domain.AllActionFunctions, apis.ListGrpcMethods, apis.ListGrpcServices)); err != nil {
return nil, err
}
if err := apis.RegisterService(ctx, userschema_v3_alpha.CreateServer(config.SystemDefaults, commands, queries)); err != nil {
@@ -494,7 +501,7 @@ func startAPIs(
}
instanceInterceptor := middleware.InstanceInterceptor(queries, config.ExternalDomain, login.IgnoreInstanceEndpoints...)
assetsCache := middleware.AssetsCacheInterceptor(config.AssetStorage.Cache.MaxAge, config.AssetStorage.Cache.SharedMaxAge)
- apis.RegisterHandlerOnPrefix(assets.HandlerPrefix, assets.NewHandler(commands, verifier, config.InternalAuthZ, id.SonyFlakeGenerator(), store, queries, middleware.CallDurationHandler, instanceInterceptor.Handler, assetsCache.Handler, limitingAccessInterceptor.Handle))
+ apis.RegisterHandlerOnPrefix(assets.HandlerPrefix, assets.NewHandler(commands, verifier, config.SystemAuthZ, config.InternalAuthZ, id.SonyFlakeGenerator(), store, queries, middleware.CallDurationHandler, instanceInterceptor.Handler, assetsCache.Handler, limitingAccessInterceptor.Handle))
apis.RegisterHandlerOnPrefix(idp.HandlerPrefix, idp.NewHandler(commands, queries, keys.IDPConfig, instanceInterceptor.Handler))
@@ -538,7 +545,7 @@ func startAPIs(
keys.User,
&config.SCIM,
instanceInterceptor.HandlerFuncWithError,
- middleware.AuthorizationInterceptor(verifier, config.InternalAuthZ).HandlerFuncWithError))
+ middleware.AuthorizationInterceptor(verifier, config.SystemAuthZ, config.InternalAuthZ).HandlerFuncWithError))
c, err := console.Start(config.Console, config.ExternalSecure, oidcServer.IssuerFromRequest, middleware.CallDurationHandler, instanceInterceptor.Handler, limitingAccessInterceptor, config.CustomerPortal)
if err != nil {
@@ -604,7 +611,7 @@ func listen(ctx context.Context, router *mux.Router, port uint16, tlsConfig *tls
go func() {
logging.Infof("server is listening on %s", lis.Addr().String())
if tlsConfig != nil {
- //we don't need to pass the files here, because we already initialized the TLS config on the server
+ // we don't need to pass the files here, because we already initialized the TLS config on the server
errCh <- http1Server.ServeTLS(lis, "", "")
} else {
errCh <- http1Server.Serve(lis)
diff --git a/cmd/start/start_from_init.go b/cmd/start/start_from_init.go
index 38a6a6c4d1..62d705b33c 100644
--- a/cmd/start/start_from_init.go
+++ b/cmd/start/start_from_init.go
@@ -21,7 +21,7 @@ Second the initial events are created.
Last ZITADEL starts.
Requirements:
-- cockroachdb`,
+- postgreSQL`,
Run: func(cmd *cobra.Command, args []string) {
err := tls.ModeFromFlag(cmd)
logging.OnError(err).Fatal("invalid tlsMode")
diff --git a/console/package.json b/console/package.json
index 8f15250747..2d986730c2 100644
--- a/console/package.json
+++ b/console/package.json
@@ -32,7 +32,7 @@
"@fortawesome/free-brands-svg-icons": "^6.7.2",
"@ngx-translate/core": "^15.0.0",
"@zitadel/client": "^1.0.7",
- "@zitadel/proto": "^1.0.4",
+ "@zitadel/proto": "1.0.5-sha-4118a9d",
"angular-oauth2-oidc": "^15.0.1",
"angularx-qrcode": "^16.0.2",
"buffer": "^6.0.3",
@@ -65,6 +65,7 @@
"@angular/compiler-cli": "^16.2.5",
"@angular/language-service": "^18.2.4",
"@bufbuild/buf": "^1.41.0",
+ "@netlify/framework-info": "^9.8.13",
"@types/file-saver": "^2.0.7",
"@types/google-protobuf": "^3.15.3",
"@types/jasmine": "~5.1.4",
@@ -86,7 +87,6 @@
"karma-jasmine-html-reporter": "^2.1.0",
"prettier": "^3.5.3",
"prettier-plugin-organize-imports": "^4.1.0",
- "typescript": "5.1",
- "@netlify/framework-info": "^9.8.13"
+ "typescript": "5.1"
}
}
diff --git a/console/src/app/components/feature-toggle/feature-toggle.component.html b/console/src/app/components/feature-toggle/feature-toggle.component.html
index eb09552445..cb97f1b746 100644
--- a/console/src/app/components/feature-toggle/feature-toggle.component.html
+++ b/console/src/app/components/feature-toggle/feature-toggle.component.html
@@ -1,29 +1,29 @@
-
diff --git a/console/src/app/pages/users/user-list/user-table/user-table.component.html b/console/src/app/pages/users/user-list/user-table/user-table.component.html
index 07583b5626..af293c01a4 100644
--- a/console/src/app/pages/users/user-list/user-table/user-table.component.html
+++ b/console/src/app/pages/users/user-list/user-table/user-table.component.html
@@ -2,7 +2,6 @@
*ngIf="type$ | async as type"
[loading]="loading()"
(refreshed)="this.refresh$.next(true)"
- [dataSize]="dataSize()"
[hideRefresh]="true"
[timestamp]="(users$ | async)?.details?.timestamp"
[selection]="selection"
diff --git a/console/src/app/pipes/action-condition-pipe/action-condition-pipe.module.ts b/console/src/app/pipes/action-condition-pipe/action-condition-pipe.module.ts
new file mode 100644
index 0000000000..2af211d5bc
--- /dev/null
+++ b/console/src/app/pipes/action-condition-pipe/action-condition-pipe.module.ts
@@ -0,0 +1,11 @@
+import { CommonModule } from '@angular/common';
+import { NgModule } from '@angular/core';
+
+import { ActionConditionPipe } from './action-condition-pipe.pipe';
+
+@NgModule({
+ declarations: [ActionConditionPipe],
+ imports: [CommonModule],
+ exports: [ActionConditionPipe],
+})
+export class ActionConditionPipeModule {}
diff --git a/console/src/app/pipes/action-condition-pipe/action-condition-pipe.pipe.ts b/console/src/app/pipes/action-condition-pipe/action-condition-pipe.pipe.ts
new file mode 100644
index 0000000000..7c45f9da5f
--- /dev/null
+++ b/console/src/app/pipes/action-condition-pipe/action-condition-pipe.pipe.ts
@@ -0,0 +1,29 @@
+import { Pipe, PipeTransform } from '@angular/core';
+import { Condition } from '@zitadel/proto/zitadel/action/v2beta/execution_pb';
+
+@Pipe({
+ name: 'condition',
+})
+export class ActionConditionPipe implements PipeTransform {
+ transform(condition?: Condition): string {
+ if (!condition?.conditionType?.case) {
+ return '';
+ }
+
+ const conditionType = condition.conditionType.value;
+
+ if ('name' in conditionType) {
+ // Applies for function condition
+ return `function: ${conditionType.name}`;
+ }
+
+ const { condition: innerCondition } = conditionType;
+
+ if (typeof innerCondition.value === 'string') {
+ // Applies for service, method condition of Request/ResponseCondition, event, and group of EventCondition
+ return `${innerCondition.case}: ${innerCondition.value}`;
+ }
+
+ return `all`;
+ }
+}
diff --git a/console/src/app/pipes/timestamp-to-date-pipe/timestamp-to-date.pipe.ts b/console/src/app/pipes/timestamp-to-date-pipe/timestamp-to-date.pipe.ts
index 8ec703230d..8fadbd30ed 100644
--- a/console/src/app/pipes/timestamp-to-date-pipe/timestamp-to-date.pipe.ts
+++ b/console/src/app/pipes/timestamp-to-date-pipe/timestamp-to-date.pipe.ts
@@ -1,18 +1,15 @@
import { Pipe, PipeTransform } from '@angular/core';
-import { Timestamp as ConnectTimestamp } from '@bufbuild/protobuf/wkt';
+import { Timestamp as BufTimestamp } from '@bufbuild/protobuf/wkt';
import { Timestamp } from 'src/app/proto/generated/google/protobuf/timestamp_pb';
@Pipe({
name: 'timestampToDate',
})
export class TimestampToDatePipe implements PipeTransform {
- transform(value: ConnectTimestamp | Timestamp.AsObject, ...args: unknown[]): unknown {
- return this.dateFromTimestamp(value);
- }
-
- private dateFromTimestamp(date: ConnectTimestamp | Timestamp.AsObject): any {
- if (date?.seconds !== undefined && date?.nanos !== undefined) {
+ transform(date: BufTimestamp | Timestamp.AsObject | undefined): Date | undefined {
+ if (date?.seconds && date.nanos) {
return new Date(Number(date.seconds) * 1000 + date.nanos / 1000 / 1000);
}
+ return undefined;
}
}
diff --git a/console/src/app/services/action.service.ts b/console/src/app/services/action.service.ts
new file mode 100644
index 0000000000..dabe2faf01
--- /dev/null
+++ b/console/src/app/services/action.service.ts
@@ -0,0 +1,77 @@
+import { Injectable } from '@angular/core';
+import { GrpcService } from './grpc.service';
+import { MessageInitShape } from '@bufbuild/protobuf';
+import {
+ CreateTargetRequestSchema,
+ CreateTargetResponse,
+ DeleteTargetRequestSchema,
+ GetTargetRequestSchema,
+ GetTargetResponse,
+ ListExecutionFunctionsRequestSchema,
+ ListExecutionFunctionsResponse,
+ ListExecutionMethodsRequestSchema,
+ ListExecutionMethodsResponse,
+ ListExecutionServicesRequestSchema,
+ ListExecutionServicesResponse,
+ ListExecutionsRequestSchema,
+ ListExecutionsResponse,
+ ListTargetsRequestSchema,
+ ListTargetsResponse,
+ SetExecutionRequestSchema,
+ SetExecutionResponse,
+ UpdateTargetRequestSchema,
+ UpdateTargetResponse,
+} from '@zitadel/proto/zitadel/action/v2beta/action_service_pb';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class ActionService {
+ constructor(private readonly grpcService: GrpcService) {}
+
+ public listTargets(req: MessageInitShape): Promise {
+ return this.grpcService.actionNew.listTargets(req);
+ }
+
+ public createTarget(req: MessageInitShape): Promise {
+ return this.grpcService.actionNew.createTarget(req);
+ }
+
+ public deleteTarget(req: MessageInitShape): Promise {
+ return this.grpcService.actionNew.deleteTarget(req);
+ }
+
+ public getTarget(req: MessageInitShape): Promise {
+ return this.grpcService.actionNew.getTarget(req);
+ }
+
+ public updateTarget(req: MessageInitShape): Promise {
+ return this.grpcService.actionNew.updateTarget(req);
+ }
+
+ public listExecutionFunctions(
+ req: MessageInitShape,
+ ): Promise {
+ return this.grpcService.actionNew.listExecutionFunctions(req);
+ }
+
+ public listExecutionMethods(
+ req: MessageInitShape,
+ ): Promise {
+ return this.grpcService.actionNew.listExecutionMethods(req);
+ }
+
+ public listExecutionServices(
+ req: MessageInitShape,
+ ): Promise {
+ return this.grpcService.actionNew.listExecutionServices(req);
+ }
+
+ public listExecutions(req: MessageInitShape): Promise {
+ return this.grpcService.actionNew.listExecutions(req);
+ }
+
+ public setExecution(req: MessageInitShape): Promise {
+ return this.grpcService.actionNew.setExecution(req);
+ }
+}
diff --git a/console/src/app/services/grpc.service.ts b/console/src/app/services/grpc.service.ts
index 81e7893671..b2f89ca648 100644
--- a/console/src/app/services/grpc.service.ts
+++ b/console/src/app/services/grpc.service.ts
@@ -18,10 +18,22 @@ import { NewConnectWebOrgInterceptor, OrgInterceptor, OrgInterceptorProvider } f
import { StorageService } from './storage.service';
import { UserServiceClient } from '../proto/generated/zitadel/user/v2/User_serviceServiceClientPb';
//@ts-ignore
-import { createFeatureServiceClient, createUserServiceClient } from '@zitadel/client/v2';
+import { createFeatureServiceClient, createUserServiceClient, createSessionServiceClient } from '@zitadel/client/v2';
//@ts-ignore
import { createAuthServiceClient, createManagementServiceClient } from '@zitadel/client/v1';
import { createGrpcWebTransport } from '@connectrpc/connect-web';
+// @ts-ignore
+import { createClientFor } from '@zitadel/client';
+import { Client, Transport } from '@connectrpc/connect';
+
+import { WebKeyService } from '@zitadel/proto/zitadel/webkey/v2beta/webkey_service_pb';
+import { ActionService } from '@zitadel/proto/zitadel/action/v2beta/action_service_pb';
+
+// @ts-ignore
+import { createClientFor } from '@zitadel/client';
+
+const createWebKeyServiceClient = createClientFor(WebKeyService);
+const createActionServiceClient = createClientFor(ActionService);
@Injectable({
providedIn: 'root',
@@ -32,15 +44,17 @@ export class GrpcService {
public admin!: AdminServiceClient;
public user!: UserServiceClient;
public userNew!: ReturnType;
+ public session!: ReturnType;
public mgmtNew!: ReturnType;
public authNew!: ReturnType;
public featureNew!: ReturnType;
+ public actionNew!: ReturnType;
+ public webKey!: ReturnType;
constructor(
private readonly envService: EnvironmentService,
private readonly platformLocation: PlatformLocation,
private readonly authenticationService: AuthenticationService,
- private readonly storageService: StorageService,
private readonly translate: TranslateService,
private readonly exhaustedService: ExhaustedService,
private readonly authInterceptor: AuthInterceptor,
@@ -105,9 +119,12 @@ export class GrpcService {
],
});
this.userNew = createUserServiceClient(transport);
+ this.session = createSessionServiceClient(transport);
this.mgmtNew = createManagementServiceClient(transportOldAPIs);
this.authNew = createAuthServiceClient(transport);
this.featureNew = createFeatureServiceClient(transport);
+ this.actionNew = createActionServiceClient(transport);
+ this.webKey = createWebKeyServiceClient(transport);
const authConfig: AuthConfig = {
scope: 'openid profile email',
diff --git a/console/src/app/services/new-feature.service.ts b/console/src/app/services/new-feature.service.ts
index 6cc631755e..5bb4fe8dd7 100644
--- a/console/src/app/services/new-feature.service.ts
+++ b/console/src/app/services/new-feature.service.ts
@@ -3,7 +3,6 @@ import { GrpcService } from './grpc.service';
import {
GetInstanceFeaturesResponse,
ResetInstanceFeaturesResponse,
- SetInstanceFeaturesRequest,
SetInstanceFeaturesRequestSchema,
SetInstanceFeaturesResponse,
} from '@zitadel/proto/zitadel/feature/v2/instance_pb';
diff --git a/console/src/app/services/session.service.ts b/console/src/app/services/session.service.ts
new file mode 100644
index 0000000000..12e07049b4
--- /dev/null
+++ b/console/src/app/services/session.service.ts
@@ -0,0 +1,15 @@
+import { Injectable } from '@angular/core';
+import { GrpcService } from './grpc.service';
+import type { MessageInitShape } from '@bufbuild/protobuf';
+import { ListSessionsRequestSchema, ListSessionsResponse } from '@zitadel/proto/zitadel/session/v2/session_service_pb';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class SessionService {
+ constructor(private readonly grpcService: GrpcService) {}
+
+ public listSessions(req: MessageInitShape): Promise {
+ return this.grpcService.session.listSessions(req);
+ }
+}
diff --git a/console/src/app/services/webkeys.service.ts b/console/src/app/services/webkeys.service.ts
new file mode 100644
index 0000000000..9a26be4712
--- /dev/null
+++ b/console/src/app/services/webkeys.service.ts
@@ -0,0 +1,33 @@
+import { Injectable } from '@angular/core';
+import { GrpcService } from './grpc.service';
+import type { MessageInitShape } from '@bufbuild/protobuf';
+import {
+ DeleteWebKeyResponse,
+ ListWebKeysResponse,
+ CreateWebKeyRequestSchema,
+ CreateWebKeyResponse,
+ ActivateWebKeyResponse,
+} from '@zitadel/proto/zitadel/webkey/v2beta/webkey_service_pb';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class WebKeysService {
+ constructor(private readonly grpcService: GrpcService) {}
+
+ public ListWebKeys(): Promise {
+ return this.grpcService.webKey.listWebKeys({});
+ }
+
+ public DeleteWebKey(id: string): Promise {
+ return this.grpcService.webKey.deleteWebKey({ id });
+ }
+
+ public CreateWebKey(req: MessageInitShape): Promise {
+ return this.grpcService.webKey.createWebKey(req);
+ }
+
+ public ActivateWebKey(id: string): Promise {
+ return this.grpcService.webKey.activateWebKey({ id });
+ }
+}
diff --git a/console/src/assets/i18n/bg.json b/console/src/assets/i18n/bg.json
index c37a88917b..f1929cef14 100644
--- a/console/src/assets/i18n/bg.json
+++ b/console/src/assets/i18n/bg.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "Животът на неактивния refresh токен е максималното време, през което refresh токен може да не се използва."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Управлявайте вашите OIDC уеб ключове, за да подписвате и валидирате токени сигурно за вашата ZITADEL инстанция.",
+ "TABLE": {
+ "TITLE": "Активни и бъдещи уеб ключове",
+ "DESCRIPTION": "Вашите активни и предстоящи уеб ключове. Активирането на нов ключ ще деактивира текущия.",
+ "NOTE": "Забележка: Крайна точка JWKs OIDC връща кешируем отговор (по подразбиране 5 минути). Избягвайте активирането на ключ твърде рано, тъй като той може да не е наличен в кеша и клиентите.",
+ "ACTIVATE": "Активирайте следващия уеб ключ",
+ "ACTIVE": "В момента активен",
+ "NEXT": "Следващ в опашката",
+ "FUTURE": "Бъдещ",
+ "WARNING": "Уеб ключът е на по-малко от 5 минути"
+ },
+ "CREATE": {
+ "TITLE": "Създаване на нов уеб ключ",
+ "DESCRIPTION": "Създаването на нов уеб ключ го добавя към вашия списък. ZITADEL използва ключове RSA2048 с хеш SHA256 по подразбиране.",
+ "KEY_TYPE": "Тип ключ",
+ "BITS": "Битове",
+ "HASHER": "Хешер",
+ "CURVE": "Крива"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Предишни уеб ключове",
+ "DESCRIPTION": "Това са вашите предишни уеб ключове, които вече не са активни.",
+ "DEACTIVATED_ON": "Деактивиран на"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "Текстове на съобщенията",
"DESCRIPTION": "Персонализирайте текстовете на вашите имейл или SMS уведомления. Ако искате да деактивирате някои от езиците, ограничете ги в настройките за език на вашите инстанции.",
@@ -501,6 +527,114 @@
"DOWNLOAD": "Изтегляне",
"APPLY": "Прилагам"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Действия",
+ "DESCRIPTION": "Действията ви позволяват да изпълнявате персонализиран код в отговор на API заявки, събития или специфични функции. Използвайте ги, за да разширите Zitadel, да автоматизирате работни процеси и да се интегрирате с други системи.",
+ "TYPES": {
+ "request": "Заявка",
+ "response": "Отговор",
+ "events": "Събития",
+ "function": "Функция"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Създаване на действие",
+ "UPDATE_TITLE": "Актуализиране на действие",
+ "TYPE": {
+ "DESCRIPTION": "Изберете кога искате да се изпълни това действие",
+ "REQUEST": {
+ "TITLE": "Заявка",
+ "DESCRIPTION": "Заявки, които се появяват в Zitadel. Това може да бъде нещо като заявка за вход."
+ },
+ "RESPONSE": {
+ "TITLE": "Отговор",
+ "DESCRIPTION": "Отговор от заявка в Zitadel. Помислете за отговора, който получавате при извличане на потребител."
+ },
+ "EVENTS": {
+ "TITLE": "Събития",
+ "DESCRIPTION": "Събития, които се случват в Zitadel. Това може да бъде нещо като създаване на потребителски акаунт, успешно влизане и т.н."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Функции",
+ "DESCRIPTION": "Функции, които можете да извикате в Zitadel. Това може да бъде всичко от изпращане на имейл до създаване на потребител."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Изберете дали това действие се прилага към всички заявки, конкретна услуга (напр. управление на потребители) или единична заявка (напр. създаване на потребител).",
+ "ALL": {
+ "TITLE": "Всички",
+ "DESCRIPTION": "Изберете това, ако искате да изпълните действието си при всяка заявка"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Избор на услуга",
+ "DESCRIPTION": "Изберете услуга на Zitadel за вашето действие."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Избор на метод",
+ "DESCRIPTION": "Ако искате да изпълните само при конкретна заявка, изберете я тук",
+ "NOTE": "Ако не изберете метод, действието ви ще се изпълни при всяка заявка във вашата избрана услуга."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Име на функция",
+ "DESCRIPTION": "Изберете функцията, която искате да изпълните"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Задаване на група",
+ "DESCRIPTION": "Ако искате да изпълните само върху група събития, задайте групата тук"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Избор на събитие",
+ "DESCRIPTION": "Ако искате да изпълните само при конкретно събитие, посочете го тук"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "Можете да изберете да изпълните цел или да я изпълните при същите условия като други цели.",
+ "TARGET": {
+ "DESCRIPTION": "Целта, която искате да изпълните за това действие"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Условия за изпълнение"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Условие",
+ "TYPE": "Тип",
+ "TARGET": "Цел",
+ "CREATIONDATE": "Дата на създаване"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Цели",
+ "DESCRIPTION": "Целта е дестинацията на кода, който искате да изпълните от действие. Създайте цел тук и я добавете към вашите действия.",
+ "CREATE": {
+ "TITLE": "Създаване на вашата цел",
+ "DESCRIPTION": "Създайте своя собствена цел извън Zitadel",
+ "NAME": "Име",
+ "NAME_DESCRIPTION": "Дайте на целта си ясно, описателно име, за да я идентифицирате лесно по-късно",
+ "TYPE": "Тип",
+ "TYPES": {
+ "restWebhook": "REST уеб кука",
+ "restCall": "REST извикване",
+ "restAsync": "REST асинхронно"
+ },
+ "ENDPOINT": "Крайна точка",
+ "ENDPOINT_DESCRIPTION": "Въведете крайната точка, където се хоства вашият код. Уверете се, че е достъпна за нас!",
+ "TIMEOUT": "Време за изчакване",
+ "TIMEOUT_DESCRIPTION": "Задайте максималното време, за което вашата цел трябва да отговори. Ако отнеме повече време, ще спрем заявката.",
+ "INTERRUPT_ON_ERROR": "Прекъсване при грешка",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Спрете всички изпълнения, когато целите върнат грешка",
+ "INTERRUPT_ON_ERROR_WARNING": "Внимание: „Прекъсване при грешка“ спира операциите при неуспех, което може да доведе до блокиране. Тествайте с изключена опция, за да предотвратите блокиране на входа/създаването.",
+ "AWAIT_RESPONSE": "Изчакване на отговор",
+ "AWAIT_RESPONSE_DESCRIPTION": "Ще изчакаме отговор, преди да направим нещо друго. Полезно, ако възнамерявате да използвате множество цели за едно действие"
+ },
+ "TABLE": {
+ "NAME": "Име",
+ "ENDPOINT": "Крайна точка",
+ "CREATIONDATE": "Дата на създаване"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "Има контрол върху цялата инстанция, включително всички организации",
"IAM_OWNER_VIEWER": "Има разрешение да прегледа целия екземпляр, включително всички организации",
@@ -1355,6 +1489,7 @@
"BRANDING": "Брандиране",
"PRIVACYPOLICY": "Политика за бедност",
"OIDC": "Живот и изтичане на OIDC Token",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Тайна поява",
"SECURITY": "Настройки на сигурността",
"EVENTS": "Събития",
@@ -1514,7 +1649,10 @@
},
"RESET": "Задай всички на наследено",
"CONSOLEUSEV2USERAPI": "Използвайте V2 API в конзолата за създаване на потребител",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "Когато този флаг е активиран, конзолата използва V2 User API за създаване на нови потребители. С V2 API новосъздадените потребители започват без начален статус."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "Когато този флаг е активиран, конзолата използва V2 User API за създаване на нови потребители. С V2 API новосъздадените потребители започват без начален статус.",
+ "LOGINV2": "Вход V2",
+ "LOGINV2_DESCRIPTION": "Активирането на това включва новия потребителски интерфейс за вход, базиран на TypeScript, с подобрена сигурност, производителност и възможности за персонализиране.",
+ "LOGINV2_BASEURI": "Базов URI"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/cs.json b/console/src/assets/i18n/cs.json
index 914fb290bb..ba7f4b1ada 100644
--- a/console/src/assets/i18n/cs.json
+++ b/console/src/assets/i18n/cs.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "Životnost nečinného refresh tokenu je maximální doba, po kterou může být refresh token nepoužitý."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Spravujte své OIDC webové klíče pro bezpečné podepisování a ověřování tokenů ve vaší instanci ZITADEL.",
+ "TABLE": {
+ "TITLE": "Aktivní a budoucí webové klíče",
+ "DESCRIPTION": "Vaše aktivní a nadcházející webové klíče. Aktivací nového klíče dojde k deaktivaci aktuálního.",
+ "NOTE": "Poznámka: Koncový bod JWKs OIDC vrací odpověď uložitelnou do mezipaměti (výchozí 5 minut). Vyhněte se příliš brzké aktivaci klíče, protože nemusí být dostupný v mezipaměti a klientům.",
+ "ACTIVATE": "Aktivovat další webový klíč",
+ "ACTIVE": "Aktuálně aktivní",
+ "NEXT": "Další v řadě",
+ "FUTURE": "Budoucí",
+ "WARNING": "Webový klíč je starý méně než 5 minut"
+ },
+ "CREATE": {
+ "TITLE": "Vytvořit nový webový klíč",
+ "DESCRIPTION": "Vytvořením nového webového klíče jej přidáte do svého seznamu. ZITADEL používá klíče RSA2048 s hashováním SHA256 jako výchozí.",
+ "KEY_TYPE": "Typ klíče",
+ "BITS": "Bity",
+ "HASHER": "Hasher",
+ "CURVE": "Křivka"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Předchozí webové klíče",
+ "DESCRIPTION": "Toto jsou vaše předchozí webové klíče, které již nejsou aktivní.",
+ "DEACTIVATED_ON": "Deaktivováno dne"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "Texty zpráv",
"DESCRIPTION": "Přizpůsob si texty svých e-mailových nebo SMS notifikací. Pokud chceš některé z jazyků zakázat, omez je ve svém nastavení jazyků instance.",
@@ -502,6 +528,114 @@
"DOWNLOAD": "Stáhnout",
"APPLY": "Platit"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Akce",
+ "DESCRIPTION": "Akce vám umožňují spouštět vlastní kód v reakci na požadavky API, události nebo specifické funkce. Použijte je k rozšíření Zitadel, automatizaci pracovních postupů a integraci s dalšími systémy.",
+ "TYPES": {
+ "request": "Požadavek",
+ "response": "Odpověď",
+ "events": "Události",
+ "function": "Funkce"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Vytvořit akci",
+ "UPDATE_TITLE": "Aktualizovat akci",
+ "TYPE": {
+ "DESCRIPTION": "Vyberte, kdy chcete tuto akci spustit",
+ "REQUEST": {
+ "TITLE": "Požadavek",
+ "DESCRIPTION": "Požadavky, které se vyskytují v rámci Zitadel. Může to být něco jako volání požadavku na přihlášení."
+ },
+ "RESPONSE": {
+ "TITLE": "Odpověď",
+ "DESCRIPTION": "Odpověď na požadavek v rámci Zitadel. Představte si odpověď, kterou získáte při načítání uživatele."
+ },
+ "EVENTS": {
+ "TITLE": "Události",
+ "DESCRIPTION": "Události, které se dějí v rámci Zitadel. Může to být cokoli, jako je vytvoření uživatelského účtu, úspěšné přihlášení atd."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Funkce",
+ "DESCRIPTION": "Funkce, které můžete volat v rámci Zitadel. Může to být cokoli od odeslání e-mailu po vytvoření uživatele."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Vyberte, zda se tato akce vztahuje na všechny požadavky, konkrétní službu (např. správa uživatelů) nebo jeden požadavek (např. vytvoření uživatele).",
+ "ALL": {
+ "TITLE": "Všechny",
+ "DESCRIPTION": "Vyberte tuto možnost, pokud chcete spustit akci pro každý požadavek"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Vybrat službu",
+ "DESCRIPTION": "Vyberte službu Zitadel pro svou akci."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Vybrat metodu",
+ "DESCRIPTION": "Pokud chcete spustit pouze pro konkrétní požadavek, vyberte jej zde",
+ "NOTE": "Pokud nevyberete metodu, vaše akce se spustí pro každý požadavek ve vaší vybrané službě."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Název funkce",
+ "DESCRIPTION": "Vyberte funkci, kterou chcete spustit"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Nastavit skupinu",
+ "DESCRIPTION": "Pokud chcete spustit pouze pro skupinu událostí, nastavte zde skupinu"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Vybrat událost",
+ "DESCRIPTION": "Pokud chcete spustit pouze pro konkrétní událost, zadejte ji zde"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "Můžete se rozhodnout spustit cíl nebo jej spustit za stejných podmínek jako jiné cíle.",
+ "TARGET": {
+ "DESCRIPTION": "Cíl, který chcete spustit pro tuto akci"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Podmínky spuštění"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Podmínka",
+ "TYPE": "Typ",
+ "TARGET": "Cíl",
+ "CREATIONDATE": "Datum vytvoření"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Cíle",
+ "DESCRIPTION": "Cíl je cíl kódu, který chcete spustit z akce. Vytvořte zde cíl a přidejte jej do svých akcí.",
+ "CREATE": {
+ "TITLE": "Vytvořit cíl",
+ "DESCRIPTION": "Vytvořte si vlastní cíl mimo Zitadel",
+ "NAME": "Název",
+ "NAME_DESCRIPTION": "Dejte svému cíli jasný, popisný název, aby bylo snadné jej později identifikovat",
+ "TYPE": "Typ",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "REST Volání",
+ "restAsync": "REST Asynchronní"
+ },
+ "ENDPOINT": "Koncový bod",
+ "ENDPOINT_DESCRIPTION": "Zadejte koncový bod, kde je hostován váš kód. Ujistěte se, že je pro nás přístupný!",
+ "TIMEOUT": "Časový limit",
+ "TIMEOUT_DESCRIPTION": "Nastavte maximální dobu, po kterou musí váš cíl odpovědět. Pokud to trvá déle, požadavek zastavíme.",
+ "INTERRUPT_ON_ERROR": "Přerušit při chybě",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Zastavte všechna spuštění, když cíle vrátí chybu",
+ "INTERRUPT_ON_ERROR_WARNING": "Pozor: „Přerušit při chybě“ zastaví operace při selhání, což může vést k zablokování. Otestujte s vypnutou možností, abyste předešli zablokování přihlášení/vytváření.",
+ "AWAIT_RESPONSE": "Čekat na odpověď",
+ "AWAIT_RESPONSE_DESCRIPTION": "Před provedením čehokoli jiného počkáme na odpověď. Užitečné, pokud hodláte použít více cílů pro jednu akci"
+ },
+ "TABLE": {
+ "NAME": "Název",
+ "ENDPOINT": "Koncový bod",
+ "CREATIONDATE": "Datum vytvoření"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "Má kontrolu nad celou instancí, včetně všech organizací",
"IAM_OWNER_VIEWER": "Má oprávnění prohlížet celou instanci, včetně všech organizací",
@@ -1356,6 +1490,7 @@
"BRANDING": "Branding",
"PRIVACYPOLICY": "Zásady ochrany osobních údajů",
"OIDC": "Životnost a expirace OIDC tokenu",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Generátor tajemství",
"SECURITY": "Bezpečnostní nastavení",
"EVENTS": "Události",
@@ -1515,7 +1650,10 @@
},
"RESET": "Nastavit vše na děděné",
"CONSOLEUSEV2USERAPI": "Použijte V2 API v konzoli pro vytvoření uživatele",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "Když je tato příznak povolen, konzole používá V2 User API k vytvoření nových uživatelů. S V2 API nově vytvoření uživatelé začínají bez počátečního stavu."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "Když je tato příznak povolen, konzole používá V2 User API k vytvoření nových uživatelů. S V2 API nově vytvoření uživatelé začínají bez počátečního stavu.",
+ "LOGINV2": "Přihlášení V2",
+ "LOGINV2_DESCRIPTION": "Povolením této možnosti se aktivuje nové přihlašovací rozhraní založené na TypeScriptu s vylepšeným zabezpečením, výkonem a přizpůsobitelností.",
+ "LOGINV2_BASEURI": "Základní URI"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/de.json b/console/src/assets/i18n/de.json
index 5735d383d6..79b9596678 100644
--- a/console/src/assets/i18n/de.json
+++ b/console/src/assets/i18n/de.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "Die maximale Inaktivitätsdauer eines Aktualisierungstokens ist die maximale Zeit, in der ein Aktualisierungstoken unbenutzt sein kann."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Verwalte deine OIDC Web Keys, um Tokens für deine ZITADEL-Instanz sicher zu signieren und zu validieren.",
+ "TABLE": {
+ "TITLE": "Aktive und zukünftige Web Keys",
+ "DESCRIPTION": "Deine aktiven und kommenden Web Keys. Das Aktivieren eines neuen Schlüssels deaktiviert den aktuellen.",
+ "NOTE": "Hinweis: Der JWKs OIDC-Endpunkt gibt eine zwischenspeicherbare Antwort zurück (Standard: 5 Min.). Vermeide es, einen Schlüssel zu früh zu aktivieren, da er möglicherweise noch nicht in Caches und Clients verfügbar ist.",
+ "ACTIVATE": "Nächsten Web Key aktivieren",
+ "ACTIVE": "Derzeit aktiv",
+ "NEXT": "Als Nächstes in der Warteschlange",
+ "FUTURE": "Zukünftig",
+ "WARNING": "Der Web Key ist weniger als 5 Minuten alt"
+ },
+ "CREATE": {
+ "TITLE": "Neuen Web Key erstellen",
+ "DESCRIPTION": "Das Erstellen eines neuen Web Keys fügt ihn zu deiner Liste hinzu. ZITADEL verwendet standardmäßig RSA2048-Schlüssel mit einem SHA256-Hasher.",
+ "KEY_TYPE": "Schlüsseltyp",
+ "BITS": "Bits",
+ "HASHER": "Hasher",
+ "CURVE": "Kurve"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Frühere Web Keys",
+ "DESCRIPTION": "Dies sind deine früheren Web Keys, die nicht mehr aktiv sind.",
+ "DEACTIVATED_ON": "Deaktiviert am"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "Nachrichtentexte",
"DESCRIPTION": "Passe die Texte deiner Benachrichtigungs-E-Mails oder SMS-Nachrichten an. Wenn du einige der Sprachen deaktivieren möchtest, beschränke sie in den Spracheinstellungen deiner Instanz.",
@@ -502,6 +528,114 @@
"DOWNLOAD": "Herunterladen",
"APPLY": "Anwenden"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Aktionen",
+ "DESCRIPTION": "Aktionen ermöglichen es Ihnen, benutzerdefinierten Code als Reaktion auf API-Anfragen, Ereignisse oder bestimmte Funktionen auszuführen. Verwenden Sie sie, um Zitadel zu erweitern, Arbeitsabläufe zu automatisieren und sich in andere Systeme zu integrieren.",
+ "TYPES": {
+ "request": "Anfrage",
+ "response": "Antwort",
+ "events": "Ereignisse",
+ "function": "Funktion"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Eine Aktion erstellen",
+ "UPDATE_TITLE": "Eine Aktion aktualisieren",
+ "TYPE": {
+ "DESCRIPTION": "Wählen Sie aus, wann diese Aktion ausgeführt werden soll",
+ "REQUEST": {
+ "TITLE": "Anfrage",
+ "DESCRIPTION": "Anfragen, die innerhalb von Zitadel auftreten. Dies könnte so etwas wie ein Login-Anfrageaufruf sein."
+ },
+ "RESPONSE": {
+ "TITLE": "Antwort",
+ "DESCRIPTION": "Eine Antwort auf eine Anfrage innerhalb von Zitadel. Denken Sie an die Antwort, die Sie beim Abrufen eines Benutzers erhalten."
+ },
+ "EVENTS": {
+ "TITLE": "Ereignisse",
+ "DESCRIPTION": "Ereignisse, die innerhalb von Zitadel stattfinden. Dies könnte alles sein, wie z.B. das Erstellen eines Benutzerkontos, ein erfolgreicher Login usw."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Funktionen",
+ "DESCRIPTION": "Funktionen, die Sie innerhalb von Zitadel aufrufen können. Dies könnte alles sein, vom Senden einer E-Mail bis zum Erstellen eines Benutzers."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Wählen Sie aus, ob diese Aktion für alle Anfragen, einen bestimmten Dienst (z.B. Benutzerverwaltung) oder eine einzelne Anfrage (z.B. Benutzer erstellen) gelten soll.",
+ "ALL": {
+ "TITLE": "Alle",
+ "DESCRIPTION": "Wählen Sie dies aus, wenn Sie Ihre Aktion bei jeder Anfrage ausführen möchten"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Dienst auswählen",
+ "DESCRIPTION": "Wählen Sie einen Zitadel-Dienst für Ihre Aktion aus."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Methode auswählen",
+ "DESCRIPTION": "Wenn Sie nur bei einer bestimmten Anfrage ausführen möchten, wählen Sie sie hier aus",
+ "NOTE": "Wenn Sie keine Methode auswählen, wird Ihre Aktion bei jeder Anfrage in Ihrem ausgewählten Dienst ausgeführt."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Funktionsname",
+ "DESCRIPTION": "Wählen Sie die Funktion aus, die Sie ausführen möchten"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Gruppe festlegen",
+ "DESCRIPTION": "Wenn Sie nur bei einer Gruppe von Ereignissen ausführen möchten, legen Sie die Gruppe hier fest"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Ereignis auswählen",
+ "DESCRIPTION": "Wenn Sie nur bei einem bestimmten Ereignis ausführen möchten, geben Sie es hier an"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "Sie können wählen, ob Sie ein Ziel ausführen oder es unter den gleichen Bedingungen wie andere Ziele ausführen möchten.",
+ "TARGET": {
+ "DESCRIPTION": "Das Ziel, das Sie für diese Aktion ausführen möchten"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Ausführungsbedingungen"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Bedingung",
+ "TYPE": "Typ",
+ "TARGET": "Ziel",
+ "CREATIONDATE": "Erstellungsdatum"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Ziele",
+ "DESCRIPTION": "Ein Ziel ist das Ziel des Codes, den Sie von einer Aktion ausführen möchten. Erstellen Sie hier ein Ziel und fügen Sie es Ihren Aktionen hinzu.",
+ "CREATE": {
+ "TITLE": "Ihr Ziel erstellen",
+ "DESCRIPTION": "Erstellen Sie Ihr eigenes Ziel außerhalb von Zitadel",
+ "NAME": "Name",
+ "NAME_DESCRIPTION": "Geben Sie Ihrem Ziel einen klaren, beschreibenden Namen, um es später leicht identifizieren zu können",
+ "TYPE": "Typ",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "REST Aufruf",
+ "restAsync": "REST Asynchron"
+ },
+ "ENDPOINT": "Endpunkt",
+ "ENDPOINT_DESCRIPTION": "Geben Sie den Endpunkt ein, an dem Ihr Code gehostet wird. Stellen Sie sicher, dass er für uns zugänglich ist!",
+ "TIMEOUT": "Timeout",
+ "TIMEOUT_DESCRIPTION": "Legen Sie die maximale Zeit fest, die Ihr Ziel zum Antworten hat. Wenn es länger dauert, stoppen wir die Anfrage.",
+ "INTERRUPT_ON_ERROR": "Bei Fehler unterbrechen",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Stoppen Sie alle Ausführungen, wenn die Ziele einen Fehler zurückgeben",
+ "INTERRUPT_ON_ERROR_WARNING": "Achtung: „Bei Fehler unterbrechen“ stoppt Vorgänge bei einem Fehler und kann zur Sperrung führen. Testen Sie mit deaktivierter Option, um Login/Erstellung nicht zu blockieren.",
+ "AWAIT_RESPONSE": "Auf Antwort warten",
+ "AWAIT_RESPONSE_DESCRIPTION": "Wir warten auf eine Antwort, bevor wir etwas anderes tun. Nützlich, wenn Sie mehrere Ziele für eine einzelne Aktion verwenden möchten"
+ },
+ "TABLE": {
+ "NAME": "Name",
+ "ENDPOINT": "Endpunkt",
+ "CREATIONDATE": "Erstellungsdatum"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "Hat die Kontrolle über die gesamte Instanz, einschließlich aller Organisationen",
"IAM_OWNER_VIEWER": "Hat die Leseberechtigung, die gesamte Instanz einschließlich aller Organisationen zu überprüfen",
@@ -1356,6 +1490,7 @@
"BRANDING": "Branding",
"PRIVACYPOLICY": "Datenschutzrichtlinie",
"OIDC": "OIDC Token Lifetime und Expiration",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Secret Generator",
"SECURITY": "Sicherheitseinstellungen",
"EVENTS": "Events",
@@ -1515,7 +1650,10 @@
},
"RESET": "Alle auf Erben setzen",
"CONSOLEUSEV2USERAPI": "Verwende die V2-API in der Konsole zur Erstellung von Benutzern",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "Wenn diese Option aktiviert ist, verwendet die Konsole die V2 User API, um neue Benutzer zu erstellen. Mit der V2 API starten neu erstellte Benutzer nicht im Initial Zustand."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "Wenn diese Option aktiviert ist, verwendet die Konsole die V2 User API, um neue Benutzer zu erstellen. Mit der V2 API starten neu erstellte Benutzer nicht im Initial Zustand.",
+ "LOGINV2": "Login V2",
+ "LOGINV2_DESCRIPTION": "Durch das Aktivieren wird das neue TypeScript-basierte Login-UI mit verbesserter Sicherheit, Leistung und Anpassbarkeit aktiviert.",
+ "LOGINV2_BASEURI": "Basis-URI"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/en.json b/console/src/assets/i18n/en.json
index e09b138708..19759d0041 100644
--- a/console/src/assets/i18n/en.json
+++ b/console/src/assets/i18n/en.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "The idle refresh token lifetime is the maximum time a refresh token can be unused."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Manage your OIDC Web Keys to securely sign and validate tokens for your ZITADEL instance.",
+ "TABLE": {
+ "TITLE": "Active and Future Web Keys",
+ "DESCRIPTION": "Your active and upcoming web keys. Activating a new key will deactivate the current one.",
+ "NOTE": "Note: The JWKs OIDC endpoint returns a cacheable response (default 5 min). Avoid activating a key too soon, as it may not be available to caches and clients yet.",
+ "ACTIVATE": "Activate next Web Key",
+ "ACTIVE": "Currently active",
+ "NEXT": "Next in queue",
+ "FUTURE": "Future",
+ "WARNING": "Web Key is less than 5 min old"
+ },
+ "CREATE": {
+ "TITLE": "Create new Web Key",
+ "DESCRIPTION": "Creating a new web key adds it to your list. ZITADEL uses RSA2048 keys with a SHA256 hasher by default.",
+ "KEY_TYPE": "Key Type",
+ "BITS": "Bits",
+ "HASHER": "Hasher",
+ "CURVE": "Curve"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Previous Web Keys",
+ "DESCRIPTION": "These are your previous web keys that are no longer active.",
+ "DEACTIVATED_ON": "Deactivated on"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "Message Texts",
"DESCRIPTION": "Customize the texts of your notification email or SMS messages. If you want to disable some of the languages, restrict them in your instances language settings.",
@@ -502,6 +528,114 @@
"DOWNLOAD": "Download",
"APPLY": "Apply"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Actions",
+ "DESCRIPTION": "Actions let you run custom code in response to API requests, events or specific functions. Use them to extend Zitadel, automate workflows, and itegrate with other systems.",
+ "TYPES": {
+ "request": "Request",
+ "response": "Response",
+ "events": "Events",
+ "function": "Function"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Create an Action",
+ "UPDATE_TITLE": "Update an Action",
+ "TYPE": {
+ "DESCRIPTION": "Select when you want this Action to run",
+ "REQUEST": {
+ "TITLE": "Request",
+ "DESCRIPTION": "Requests that occur within Zitadel. This could be something as a login request call."
+ },
+ "RESPONSE": {
+ "TITLE": "Response",
+ "DESCRIPTION": "A response from a request within Zitadel. Think of the response you get back from fetching a user."
+ },
+ "EVENTS": {
+ "TITLE": "Events",
+ "DESCRIPTION": "Events that happen within Zitadel. This could be anything like a user creating an account, a successful login etc."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Functions",
+ "DESCRIPTION": "Functions that you can call within Zitadel. This could be anything from sending an email to creating a user."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Choose whether this action applies to all request, a specific service (ec. user management), or a single request (e.g. create user).",
+ "ALL": {
+ "TITLE": "All",
+ "DESCRIPTION": "Select this if you want to run your action on every request"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Select Service",
+ "DESCRIPTION": "Choose a Zitadel Service for you action."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Select Method",
+ "DESCRIPTION": "If you want to only execute on a specific request, select it here",
+ "NOTE": "If you don't select a method, your action will run on every request in your selected service."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Function Name",
+ "DESCRIPTION": "Choose the function you want to execute"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Set Group",
+ "DESCRIPTION": "If you want to only execute on a group of events, set the group here"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Select Event",
+ "DESCRIPTION": "If you want to only execute on a specific event, specify it here"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "You can choose to execute a target, or to run it on the same conditions as other targets.",
+ "TARGET": {
+ "DESCRIPTION": "The target you want to execute for this action"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Execution Conditions"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Condition",
+ "TYPE": "Type",
+ "TARGET": "Target",
+ "CREATIONDATE": "Creation Date"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Targets",
+ "DESCRIPTION": "A target is the destination of the code you want to execute from an action. Create a target here and at it to your actions.",
+ "CREATE": {
+ "TITLE": "Create your Target",
+ "DESCRIPTION": "Create your own target outside of Zitadel",
+ "NAME": "Name",
+ "NAME_DESCRIPTION": "Give your target a clear, descriptive name to make it easy to identify later",
+ "TYPE": "Type",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "REST Call",
+ "restAsync": "REST Async"
+ },
+ "ENDPOINT": "Endpoint",
+ "ENDPOINT_DESCRIPTION": "Enter the endpoint where your code is hosted. Make sure it is accessible to us!",
+ "TIMEOUT": "Timeout",
+ "TIMEOUT_DESCRIPTION": "Set the maximum time your target has to respond. If it takes longer, we will stop the request.",
+ "INTERRUPT_ON_ERROR": "Interrupt on Error",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Stop all executions when the targets returns with an error",
+ "INTERRUPT_ON_ERROR_WARNING": "Caution: “Interrupt on Error” halts operations on failure, risking lockout. Test with it disabled to prevent blocking login/creation.",
+ "AWAIT_RESPONSE": "Await Response",
+ "AWAIT_RESPONSE_DESCRIPTION": "We'll Wait for a response before we do anything else. Useful if you intend to use multiple targets for a single action"
+ },
+ "TABLE": {
+ "NAME": "Name",
+ "ENDPOINT": "Endpoint",
+ "CREATIONDATE": "Creation Date"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "Has control over the whole instance, including all organizations",
"IAM_OWNER_VIEWER": "Has permission to review the whole instance, including all organizations",
@@ -1356,11 +1490,14 @@
"BRANDING": "Branding",
"PRIVACYPOLICY": "External links",
"OIDC": "OIDC Token lifetime and expiration",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Secret Generator",
"SECURITY": "Security settings",
"EVENTS": "Events",
"FAILEDEVENTS": "Failed Events",
- "VIEWS": "Views"
+ "VIEWS": "Views",
+ "ACTIONS": "Actions",
+ "TARGETS": "Targets"
},
"GROUPS": {
"GENERAL": "General Information",
@@ -1370,7 +1507,8 @@
"TEXTS": "Texts and Languages",
"APPEARANCE": "Appearance",
"OTHER": "Other",
- "STORAGE": "Storage"
+ "STORAGE": "Storage",
+ "ACTIONS": "Actions"
}
},
"SETTING": {
@@ -1515,7 +1653,10 @@
},
"RESET": "Set all to inherit",
"CONSOLEUSEV2USERAPI": "Use V2 Api in Console for User creation",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "When this flag is enabled, the console uses the V2 User API to create new users. With the V2 API, newly created users start without an initial state."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "When this flag is enabled, the console uses the V2 User API to create new users. With the V2 API, newly created users start without an initial state.",
+ "LOGINV2": "Login V2",
+ "LOGINV2_DESCRIPTION": "Enabling this activates the new TypeScript-based login UI with improved security, performance, and customization.",
+ "LOGINV2_BASEURI": "Base URI"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/es.json b/console/src/assets/i18n/es.json
index a03b298ec4..6855d0dcbf 100644
--- a/console/src/assets/i18n/es.json
+++ b/console/src/assets/i18n/es.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "La duración de vida del token de actualización en espera es el tiempo máximo que un token de actualización puede estar sin usar."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Administra tus claves web OIDC para firmar y validar tokens de manera segura en tu instancia de ZITADEL.",
+ "TABLE": {
+ "TITLE": "Claves Web Activas y Futuras",
+ "DESCRIPTION": "Tus claves web activas y próximas. Activar una nueva clave desactivará la actual.",
+ "NOTE": "Nota: El endpoint JWKs OIDC devuelve una respuesta almacenable en caché (por defecto 5 min). Evita activar una clave demasiado pronto, ya que puede que aún no esté disponible en cachés y clientes.",
+ "ACTIVATE": "Activar la siguiente Clave Web",
+ "ACTIVE": "Actualmente activa",
+ "NEXT": "Siguiente en la cola",
+ "FUTURE": "Futuro",
+ "WARNING": "La clave web tiene menos de 5 minutos"
+ },
+ "CREATE": {
+ "TITLE": "Crear nueva Clave Web",
+ "DESCRIPTION": "Crear una nueva clave web la añadirá a tu lista. ZITADEL usa por defecto claves RSA2048 con un algoritmo de hash SHA256.",
+ "KEY_TYPE": "Tipo de Clave",
+ "BITS": "Bits",
+ "HASHER": "Algoritmo de Hash",
+ "CURVE": "Curva"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Claves Web Anteriores",
+ "DESCRIPTION": "Estas son tus claves web anteriores que ya no están activas.",
+ "DEACTIVATED_ON": "Desactivada el"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "Textos de Mensajes",
"DESCRIPTION": "Personaliza los textos de tus mensajes de correo electrónico de notificación o mensajes SMS. Si deseas desactivar algunos de los idiomas, restríngelos en la configuración de idiomas de tus instancias.",
@@ -502,6 +528,114 @@
"DOWNLOAD": "Descargar",
"APPLY": "Aplicar"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Acciones",
+ "DESCRIPTION": "Las acciones te permiten ejecutar código personalizado en respuesta a solicitudes de API, eventos o funciones específicas. Úsalas para extender Zitadel, automatizar flujos de trabajo e integrarte con otros sistemas.",
+ "TYPES": {
+ "request": "Solicitud",
+ "response": "Respuesta",
+ "events": "Eventos",
+ "function": "Función"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Crear una acción",
+ "UPDATE_TITLE": "Actualizar una acción",
+ "TYPE": {
+ "DESCRIPTION": "Selecciona cuándo quieres que se ejecute esta acción",
+ "REQUEST": {
+ "TITLE": "Solicitud",
+ "DESCRIPTION": "Solicitudes que ocurren dentro de Zitadel. Esto podría ser algo como una llamada de solicitud de inicio de sesión."
+ },
+ "RESPONSE": {
+ "TITLE": "Respuesta",
+ "DESCRIPTION": "Una respuesta de una solicitud dentro de Zitadel. Piensa en la respuesta que recibes al obtener un usuario."
+ },
+ "EVENTS": {
+ "TITLE": "Eventos",
+ "DESCRIPTION": "Eventos que ocurren dentro de Zitadel. Esto podría ser cualquier cosa como un usuario creando una cuenta, un inicio de sesión exitoso, etc."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Funciones",
+ "DESCRIPTION": "Funciones que puedes llamar dentro de Zitadel. Esto podría ser cualquier cosa, desde enviar un correo electrónico hasta crear un usuario."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Elige si esta acción se aplica a todas las solicitudes, a un servicio específico (p. ej., administración de usuarios) o a una sola solicitud (p. ej., crear usuario).",
+ "ALL": {
+ "TITLE": "Todas",
+ "DESCRIPTION": "Selecciona esto si quieres ejecutar tu acción en cada solicitud"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Seleccionar servicio",
+ "DESCRIPTION": "Elige un servicio de Zitadel para tu acción."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Seleccionar método",
+ "DESCRIPTION": "Si quieres ejecutar solo en una solicitud específica, selecciónala aquí",
+ "NOTE": "Si no seleccionas un método, tu acción se ejecutará en cada solicitud de tu servicio seleccionado."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Nombre de la función",
+ "DESCRIPTION": "Elige la función que quieres ejecutar"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Establecer grupo",
+ "DESCRIPTION": "Si quieres ejecutar solo en un grupo de eventos, establece el grupo aquí"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Seleccionar evento",
+ "DESCRIPTION": "Si quieres ejecutar solo en un evento específico, especifícalo aquí"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "Puedes elegir ejecutar un objetivo o ejecutarlo en las mismas condiciones que otros objetivos.",
+ "TARGET": {
+ "DESCRIPTION": "El objetivo que quieres ejecutar para esta acción"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Condiciones de ejecución"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Condición",
+ "TYPE": "Tipo",
+ "TARGET": "Objetivo",
+ "CREATIONDATE": "Fecha de creación"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Objetivos",
+ "DESCRIPTION": "Un objetivo es el destino del código que quieres ejecutar desde una acción. Crea un objetivo aquí y agrégalo a tus acciones.",
+ "CREATE": {
+ "TITLE": "Crear tu objetivo",
+ "DESCRIPTION": "Crea tu propio objetivo fuera de Zitadel",
+ "NAME": "Nombre",
+ "NAME_DESCRIPTION": "Dale a tu objetivo un nombre claro y descriptivo para que sea fácil de identificar más tarde",
+ "TYPE": "Tipo",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "Llamada REST",
+ "restAsync": "REST Asíncrono"
+ },
+ "ENDPOINT": "Punto de conexión",
+ "ENDPOINT_DESCRIPTION": "Introduce el punto de conexión donde se aloja tu código. ¡Asegúrate de que sea accesible para nosotros!",
+ "TIMEOUT": "Tiempo de espera",
+ "TIMEOUT_DESCRIPTION": "Establece el tiempo máximo que tiene tu objetivo para responder. Si tarda más, detendremos la solicitud.",
+ "INTERRUPT_ON_ERROR": "Interrumpir en error",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Detén todas las ejecuciones cuando los objetivos devuelvan un error",
+ "INTERRUPT_ON_ERROR_WARNING": "Precaución: “Interrumpir en error” detiene las operaciones si fallan, lo que puede provocar un bloqueo. Pruebe con esta opción desactivada para evitar bloquear el inicio de sesión o la creación.",
+ "AWAIT_RESPONSE": "Esperar respuesta",
+ "AWAIT_RESPONSE_DESCRIPTION": "Esperaremos una respuesta antes de hacer cualquier otra cosa. Útil si tienes la intención de usar múltiples objetivos para una sola acción"
+ },
+ "TABLE": {
+ "NAME": "Nombre",
+ "ENDPOINT": "Punto de conexión",
+ "CREATIONDATE": "Fecha de creación"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "Tiene control sobre toda la instancia, incluyendo todas las organizaciones",
"IAM_OWNER_VIEWER": "Tiene permiso para revisar toda la instancia, incluyendo todas las organizaciones",
@@ -1357,6 +1491,7 @@
"BRANDING": "Imagen de marca",
"PRIVACYPOLICY": "Política de privacidad",
"OIDC": "OIDC Token lifetime and expiration",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Apariencia del secreto",
"SECURITY": "Ajustes de seguridad",
"EVENTS": "Eventos",
@@ -1516,7 +1651,10 @@
},
"RESET": "Establecer todo a heredado",
"CONSOLEUSEV2USERAPI": "Utilice la API V2 en la consola para la creación de usuarios",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "Cuando esta opción está habilitada, la consola utiliza la API V2 de usuario para crear nuevos usuarios. Con la API V2, los usuarios recién creados comienzan sin un estado inicial."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "Cuando esta opción está habilitada, la consola utiliza la API V2 de usuario para crear nuevos usuarios. Con la API V2, los usuarios recién creados comienzan sin un estado inicial.",
+ "LOGINV2": "Inicio de sesión V2",
+ "LOGINV2_DESCRIPTION": "Al habilitar esto, se activa la nueva interfaz de inicio de sesión basada en TypeScript con mejoras en seguridad, rendimiento y personalización.",
+ "LOGINV2_BASEURI": "URI base"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/fr.json b/console/src/assets/i18n/fr.json
index c63fb42cab..47acd0ac9f 100644
--- a/console/src/assets/i18n/fr.json
+++ b/console/src/assets/i18n/fr.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "La durée de vie du token de rafraîchissement inactif est le temps maximum qu'un token de rafraîchissement peut être inutilisé."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Gérez vos clés Web OIDC pour signer et valider en toute sécurité les jetons de votre instance ZITADEL.",
+ "TABLE": {
+ "TITLE": "Clés Web Actives et Futures",
+ "DESCRIPTION": "Vos clés Web actives et à venir. L'activation d'une nouvelle clé désactivera l'actuelle.",
+ "NOTE": "Remarque : Le point de terminaison JWKs OIDC renvoie une réponse mise en cache (par défaut 5 min). Évitez d'activer une clé trop tôt, car elle pourrait ne pas encore être disponible pour les caches et les clients.",
+ "ACTIVATE": "Activer la prochaine Clé Web",
+ "ACTIVE": "Actuellement active",
+ "NEXT": "Prochaine dans la file d'attente",
+ "FUTURE": "Futur",
+ "WARNING": "La clé Web a moins de 5 minutes"
+ },
+ "CREATE": {
+ "TITLE": "Créer une nouvelle Clé Web",
+ "DESCRIPTION": "Créer une nouvelle clé Web l'ajoutera à votre liste. ZITADEL utilise par défaut des clés RSA2048 avec un hacheur SHA256.",
+ "KEY_TYPE": "Type de Clé",
+ "BITS": "Bits",
+ "HASHER": "Hacheur",
+ "CURVE": "Courbe"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Clés Web Précédentes",
+ "DESCRIPTION": "Voici vos anciennes clés Web qui ne sont plus actives.",
+ "DEACTIVATED_ON": "Désactivée le"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "Textes des Messages",
"DESCRIPTION": "Personnalisez les textes de vos e-mails de notification ou messages SMS. Si vous souhaitez désactiver certaines langues, restreignez-les dans les paramètres de langue de vos instances.",
@@ -502,6 +528,114 @@
"DOWNLOAD": "Télécharger",
"APPLY": "Appliquer"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Actions",
+ "DESCRIPTION": "Les actions vous permettent d'exécuter du code personnalisé en réponse à des requêtes API, des événements ou des fonctions spécifiques. Utilisez-les pour étendre Zitadel, automatiser les flux de travail et vous intégrer à d'autres systèmes.",
+ "TYPES": {
+ "request": "Requête",
+ "response": "Réponse",
+ "events": "Événements",
+ "function": "Fonction"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Créer une action",
+ "UPDATE_TITLE": "Mettre à jour une action",
+ "TYPE": {
+ "DESCRIPTION": "Sélectionnez quand vous souhaitez que cette action s'exécute",
+ "REQUEST": {
+ "TITLE": "Requête",
+ "DESCRIPTION": "Requêtes qui se produisent dans Zitadel. Cela pourrait être quelque chose comme un appel de requête de connexion."
+ },
+ "RESPONSE": {
+ "TITLE": "Réponse",
+ "DESCRIPTION": "Une réponse à une requête dans Zitadel. Pensez à la réponse que vous obtenez lorsque vous récupérez un utilisateur."
+ },
+ "EVENTS": {
+ "TITLE": "Événements",
+ "DESCRIPTION": "Événements qui se produisent dans Zitadel. Cela pourrait être n'importe quoi, comme un utilisateur créant un compte, une connexion réussie, etc."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Fonctions",
+ "DESCRIPTION": "Fonctions que vous pouvez appeler dans Zitadel. Cela pourrait être n'importe quoi, de l'envoi d'un e-mail à la création d'un utilisateur."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Choisissez si cette action s'applique à toutes les requêtes, à un service spécifique (par exemple, la gestion des utilisateurs) ou à une seule requête (par exemple, créer un utilisateur).",
+ "ALL": {
+ "TITLE": "Tous",
+ "DESCRIPTION": "Sélectionnez ceci si vous souhaitez exécuter votre action sur chaque requête"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Sélectionner un service",
+ "DESCRIPTION": "Choisissez un service Zitadel pour votre action."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Sélectionner une méthode",
+ "DESCRIPTION": "Si vous souhaitez exécuter uniquement sur une requête spécifique, sélectionnez-la ici",
+ "NOTE": "Si vous ne sélectionnez pas de méthode, votre action s'exécutera sur chaque requête de votre service sélectionné."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Nom de la fonction",
+ "DESCRIPTION": "Choisissez la fonction que vous souhaitez exécuter"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Définir un groupe",
+ "DESCRIPTION": "Si vous souhaitez exécuter uniquement sur un groupe d'événements, définissez le groupe ici"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Sélectionner un événement",
+ "DESCRIPTION": "Si vous souhaitez exécuter uniquement sur un événement spécifique, spécifiez-le ici"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "Vous pouvez choisir d'exécuter une cible ou de l'exécuter dans les mêmes conditions que d'autres cibles.",
+ "TARGET": {
+ "DESCRIPTION": "La cible que vous souhaitez exécuter pour cette action"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Conditions d'exécution"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Condition",
+ "TYPE": "Type",
+ "TARGET": "Cible",
+ "CREATIONDATE": "Date de création"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Cibles",
+ "DESCRIPTION": "Une cible est la destination du code que vous souhaitez exécuter à partir d'une action. Créez une cible ici et ajoutez-la à vos actions.",
+ "CREATE": {
+ "TITLE": "Créer votre cible",
+ "DESCRIPTION": "Créez votre propre cible en dehors de Zitadel",
+ "NAME": "Nom",
+ "NAME_DESCRIPTION": "Donnez à votre cible un nom clair et descriptif pour la rendre facile à identifier plus tard",
+ "TYPE": "Type",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "Appel REST",
+ "restAsync": "REST Asynchrone"
+ },
+ "ENDPOINT": "Point de terminaison",
+ "ENDPOINT_DESCRIPTION": "Entrez le point de terminaison où votre code est hébergé. Assurez-vous qu'il nous est accessible !",
+ "TIMEOUT": "Délai d'attente",
+ "TIMEOUT_DESCRIPTION": "Définissez le temps maximal dont votre cible dispose pour répondre. Si cela prend plus de temps, nous arrêterons la requête.",
+ "INTERRUPT_ON_ERROR": "Interrompre en cas d'erreur",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Arrêtez toutes les exécutions lorsque les cibles renvoient une erreur",
+ "INTERRUPT_ON_ERROR_WARNING": "Attention : “Interrompre en cas d'erreur” arrête les opérations en cas d’échec, ce qui peut entraîner un verrouillage. Testez avec cette option désactivée pour éviter de bloquer la connexion ou la création.",
+ "AWAIT_RESPONSE": "Attendre une réponse",
+ "AWAIT_RESPONSE_DESCRIPTION": "Nous attendrons une réponse avant de faire autre chose. Utile si vous avez l'intention d'utiliser plusieurs cibles pour une seule action"
+ },
+ "TABLE": {
+ "NAME": "Nom",
+ "ENDPOINT": "Point de terminaison",
+ "CREATIONDATE": "Date de création"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "A le contrôle de toute l'instance, y compris toutes les organisations",
"IAM_OWNER_VIEWER": "A le droit de passer en revue l'ensemble de l'instance, y compris toutes les organisations.",
@@ -1356,6 +1490,7 @@
"BRANDING": "Image de marque",
"PRIVACYPOLICY": "Politique de confidentialité",
"OIDC": "Durée de vie et expiration des jetons OIDC",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Générateur de secrets",
"SECURITY": "Paramètres de sécurité",
"EVENTS": "Événements",
@@ -1515,7 +1650,10 @@
},
"RESET": "Réinitialiser tout sur hérité",
"CONSOLEUSEV2USERAPI": "Utilisez l'API V2 dans la console pour la création d'utilisateurs",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "Lorsque ce drapeau est activé, la console utilise l'API V2 User pour créer de nouveaux utilisateurs. Avec l'API V2, les nouveaux utilisateurs commencent sans état initial."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "Lorsque ce drapeau est activé, la console utilise l'API V2 User pour créer de nouveaux utilisateurs. Avec l'API V2, les nouveaux utilisateurs commencent sans état initial.",
+ "LOGINV2": "Connexion V2",
+ "LOGINV2_DESCRIPTION": "L’activation de cette option lance la nouvelle interface de connexion basée sur TypeScript, avec une sécurité, des performances et une personnalisation améliorées.",
+ "LOGINV2_BASEURI": "URI de base"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/hu.json b/console/src/assets/i18n/hu.json
index 8f7a5632f6..8e1f8ad7d2 100644
--- a/console/src/assets/i18n/hu.json
+++ b/console/src/assets/i18n/hu.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "A tétlen frissítő token élettartama az a maximális idő, ameddig a frissítő token használaton kívül maradhat."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Kezelje az OIDC Webkulcsokat, hogy biztonságosan aláírja és érvényesítse a tokeneket a ZITADEL példányában.",
+ "TABLE": {
+ "TITLE": "Aktív és Jövőbeli Webkulcsok",
+ "DESCRIPTION": "Az aktív és közelgő webkulcsai. Egy új kulcs aktiválása deaktiválja az aktuálisat.",
+ "NOTE": "Megjegyzés: A JWKs OIDC végpont egy gyorsítótárazható választ ad vissza (alapértelmezett: 5 perc). Kerülje a kulcs túl korai aktiválását, mivel lehet, hogy még nem érhető el a gyorsítótárakban és a klienseknél.",
+ "ACTIVATE": "Következő Webkulcs aktiválása",
+ "ACTIVE": "Jelenleg aktív",
+ "NEXT": "Következő a sorban",
+ "FUTURE": "Jövőbeli",
+ "WARNING": "A webkulcs kevesebb mint 5 perces"
+ },
+ "CREATE": {
+ "TITLE": "Új Webkulcs létrehozása",
+ "DESCRIPTION": "Egy új webkulcs létrehozása hozzáadja azt a listájához. A ZITADEL alapértelmezés szerint RSA2048 kulcsokat használ SHA256 hasheléssel.",
+ "KEY_TYPE": "Kulcstípus",
+ "BITS": "Bitek",
+ "HASHER": "Hasher",
+ "CURVE": "Görbe"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Korábbi Webkulcsok",
+ "DESCRIPTION": "Ezek a korábbi webkulcsai, amelyek már nem aktívak.",
+ "DEACTIVATED_ON": "Deaktiválva ekkor"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "Üzenet Szövegek",
"DESCRIPTION": "Testreszabhatod az értesítési e-mailjeid vagy SMS üzeneteid szövegeit. Ha le szeretnél tiltani néhány nyelvet, korlátozd azokat az instance nyelvi beállításaiban.",
@@ -502,6 +528,114 @@
"DOWNLOAD": "Letöltés",
"APPLY": "Alkalmaz"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Műveletek",
+ "DESCRIPTION": "A műveletek lehetővé teszik egyedi kód futtatását API-kérésekre, eseményekre vagy konkrét függvényekre válaszul. Használja őket a Zitadel kiterjesztéséhez, a munkafolyamatok automatizálásához és más rendszerekkel való integrációhoz.",
+ "TYPES": {
+ "request": "Kérés",
+ "response": "Válasz",
+ "events": "Események",
+ "function": "Függvény"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Művelet létrehozása",
+ "UPDATE_TITLE": "Művelet frissítése",
+ "TYPE": {
+ "DESCRIPTION": "Válassza ki, mikor szeretné futtatni ezt a műveletet",
+ "REQUEST": {
+ "TITLE": "Kérés",
+ "DESCRIPTION": "A Zitadelen belül előforduló kérések. Ez lehet például egy bejelentkezési kérés hívása."
+ },
+ "RESPONSE": {
+ "TITLE": "Válasz",
+ "DESCRIPTION": "Válasz egy Zitadelen belüli kérésre. Gondoljon arra a válaszra, amelyet egy felhasználó lekérésekor kap."
+ },
+ "EVENTS": {
+ "TITLE": "Események",
+ "DESCRIPTION": "A Zitadelen belül zajló események. Ez bármi lehet, például egy felhasználó fiók létrehozása, sikeres bejelentkezés stb."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Függvények",
+ "DESCRIPTION": "Függvények, amelyeket a Zitadelen belül hívhat. Ez bármi lehet, az e-mail küldésétől a felhasználó létrehozásáig."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Válassza ki, hogy ez a művelet vonatkozik-e minden kérésre, egy adott szolgáltatásra (pl. felhasználókezelés) vagy egyetlen kérésre (pl. felhasználó létrehozása).",
+ "ALL": {
+ "TITLE": "Összes",
+ "DESCRIPTION": "Válassza ezt, ha minden kérésnél futtatni szeretné a műveletet"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Szolgáltatás kiválasztása",
+ "DESCRIPTION": "Válasszon egy Zitadel szolgáltatást a művelethez."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Módszer kiválasztása",
+ "DESCRIPTION": "Ha csak egy adott kérésnél szeretne futtatni, válassza ki itt",
+ "NOTE": "Ha nem választ módszert, a művelet minden kérésnél futni fog a kiválasztott szolgáltatásban."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Függvénynév",
+ "DESCRIPTION": "Válassza ki a futtatni kívánt függvényt"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Csoport beállítása",
+ "DESCRIPTION": "Ha csak események egy csoportján szeretne futtatni, állítsa be itt a csoportot"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Esemény kiválasztása",
+ "DESCRIPTION": "Ha csak egy adott eseményen szeretne futtatni, adja meg itt"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "Választhat, hogy futtat egy célt, vagy ugyanazokkal a feltételekkel futtatja, mint más célokat.",
+ "TARGET": {
+ "DESCRIPTION": "A cél, amelyet futtatni szeretne ehhez a művelethez"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Végrehajtási feltételek"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Feltétel",
+ "TYPE": "Típus",
+ "TARGET": "Cél",
+ "CREATIONDATE": "Létrehozás dátuma"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Célok",
+ "DESCRIPTION": "A cél annak a kódnak a célja, amelyet egy műveletből szeretne futtatni. Hozzon létre itt egy célt, és adja hozzá a műveleteihez.",
+ "CREATE": {
+ "TITLE": "Cél létrehozása",
+ "DESCRIPTION": "Hozza létre saját célját a Zitadelen kívül",
+ "NAME": "Név",
+ "NAME_DESCRIPTION": "Adjon a céljának egy világos, leíró nevet, hogy később könnyen azonosítható legyen",
+ "TYPE": "Típus",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "REST Hívás",
+ "restAsync": "REST Aszinkron"
+ },
+ "ENDPOINT": "Végpont",
+ "ENDPOINT_DESCRIPTION": "Adja meg azt a végpontot, ahol a kódja található. Győződjön meg arról, hogy elérhető számunkra!",
+ "TIMEOUT": "Időtúllépés",
+ "TIMEOUT_DESCRIPTION": "Állítsa be a maximális időt, amíg a céljának válaszolnia kell. Ha tovább tart, leállítjuk a kérést.",
+ "INTERRUPT_ON_ERROR": "Hiba esetén megszakítás",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Állítsa le az összes végrehajtást, ha a célok hibát adnak vissza",
+ "INTERRUPT_ON_ERROR_WARNING": "Figyelem: Az „Hiba esetén megszakítás” funkció leállítja a műveleteket hiba esetén, ami kizáráshoz vezethet. Tesztelje kikapcsolt állapotban a bejelentkezés/létrehozás blokkolásának elkerülése érdekében.",
+ "AWAIT_RESPONSE": "Válaszra várás",
+ "AWAIT_RESPONSE_DESCRIPTION": "Megvárjuk a választ, mielőtt bármi mást tennénk. Hasznos, ha több célt szeretne használni egyetlen művelethez"
+ },
+ "TABLE": {
+ "NAME": "Név",
+ "ENDPOINT": "Végpont",
+ "CREATIONDATE": "Létrehozás dátuma"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "Teljes irányítása van az egész példány felett, beleértve minden szervezetet",
"IAM_OWNER_VIEWER": "Jogosultsága van az egész példány átnézésére, beleértve minden szervezetet",
@@ -1356,6 +1490,7 @@
"BRANDING": "Márkaépítés",
"PRIVACYPOLICY": "Külső hivatkozások",
"OIDC": "OIDC token élettartam és lejárat",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Titokgenerátor",
"SECURITY": "Biztonsági beállítások",
"EVENTS": "Események",
@@ -1513,7 +1648,10 @@
},
"RESET": "Mindent állíts öröklésre",
"CONSOLEUSEV2USERAPI": "Használja a V2 API-t a konzolban felhasználók létrehozásához",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "Ha ez a jelző engedélyezve van, a konzol a V2 User API-t használja új felhasználók létrehozásához. A V2 API-val az újonnan létrehozott felhasználók kezdeti állapot nélkül indulnak."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "Ha ez a jelző engedélyezve van, a konzol a V2 User API-t használja új felhasználók létrehozásához. A V2 API-val az újonnan létrehozott felhasználók kezdeti állapot nélkül indulnak.",
+ "LOGINV2": "Bejelentkezés V2",
+ "LOGINV2_DESCRIPTION": "Ennek engedélyezésével aktiválódik az új, TypeScript-alapú bejelentkezési felület, amely jobb biztonságot, teljesítményt és testreszabhatóságot nyújt.",
+ "LOGINV2_BASEURI": "Alap URI"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/id.json b/console/src/assets/i18n/id.json
index aff1e59854..d5cef2c054 100644
--- a/console/src/assets/i18n/id.json
+++ b/console/src/assets/i18n/id.json
@@ -173,6 +173,32 @@
"DESCRIPTION": "Masa pakai token penyegaran yang menganggur adalah waktu maksimum token penyegaran tidak dapat digunakan."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Kelola Kunci Web OIDC Anda untuk menandatangani dan memvalidasi token dengan aman untuk instance ZITADEL Anda.",
+ "TABLE": {
+ "TITLE": "Kunci Web Aktif dan Mendatang",
+ "DESCRIPTION": "Kunci web Anda yang aktif dan akan datang. Mengaktifkan kunci baru akan menonaktifkan kunci yang sedang digunakan.",
+ "NOTE": "Catatan: Endpoint JWKs OIDC mengembalikan respons yang dapat di-cache (default 5 menit). Hindari mengaktifkan kunci terlalu cepat, karena mungkin belum tersedia di cache dan klien.",
+ "ACTIVATE": "Aktifkan Kunci Web Berikutnya",
+ "ACTIVE": "Saat ini aktif",
+ "NEXT": "Berikutnya dalam antrean",
+ "FUTURE": "Mendatang",
+ "WARNING": "Kunci Web berusia kurang dari 5 menit"
+ },
+ "CREATE": {
+ "TITLE": "Buat Kunci Web Baru",
+ "DESCRIPTION": "Membuat kunci web baru akan menambahkannya ke daftar Anda. ZITADEL secara default menggunakan kunci RSA2048 dengan fungsi hash SHA256.",
+ "KEY_TYPE": "Jenis Kunci",
+ "BITS": "Bit",
+ "HASHER": "Hasher",
+ "CURVE": "Kurva"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Kunci Web Sebelumnya",
+ "DESCRIPTION": "Ini adalah kunci web sebelumnya yang tidak lagi aktif.",
+ "DEACTIVATED_ON": "Dinonaktifkan pada"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "Teks Pesan",
"DESCRIPTION": "Sesuaikan teks email notifikasi atau pesan SMS Anda. Jika Anda ingin menonaktifkan beberapa bahasa, batasi bahasa tersebut di pengaturan bahasa instance Anda.",
@@ -469,6 +495,114 @@
"DOWNLOAD": "Unduh",
"APPLY": "Menerapkan"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Tindakan",
+ "DESCRIPTION": "Tindakan memungkinkan Anda menjalankan kode khusus sebagai respons terhadap permintaan API, peristiwa, atau fungsi tertentu. Gunakan ini untuk memperluas Zitadel, mengotomatiskan alur kerja, dan berintegrasi dengan sistem lain.",
+ "TYPES": {
+ "request": "Permintaan",
+ "response": "Respons",
+ "events": "Peristiwa",
+ "function": "Fungsi"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Buat Tindakan",
+ "UPDATE_TITLE": "Perbarui Tindakan",
+ "TYPE": {
+ "DESCRIPTION": "Pilih kapan Anda ingin Tindakan ini dijalankan",
+ "REQUEST": {
+ "TITLE": "Permintaan",
+ "DESCRIPTION": "Permintaan yang terjadi di dalam Zitadel. Ini bisa berupa sesuatu seperti panggilan permintaan login."
+ },
+ "RESPONSE": {
+ "TITLE": "Respons",
+ "DESCRIPTION": "Respons dari permintaan di dalam Zitadel. Pikirkan respons yang Anda dapatkan kembali dari pengambilan pengguna."
+ },
+ "EVENTS": {
+ "TITLE": "Peristiwa",
+ "DESCRIPTION": "Peristiwa yang terjadi di dalam Zitadel. Ini bisa berupa apa saja seperti pengguna membuat akun, login berhasil, dll."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Fungsi",
+ "DESCRIPTION": "Fungsi yang dapat Anda panggil di dalam Zitadel. Ini bisa berupa apa saja mulai dari mengirim email hingga membuat pengguna."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Pilih apakah tindakan ini berlaku untuk semua permintaan, layanan tertentu (mis. manajemen pengguna), atau permintaan tunggal (mis. buat pengguna).",
+ "ALL": {
+ "TITLE": "Semua",
+ "DESCRIPTION": "Pilih ini jika Anda ingin menjalankan tindakan Anda pada setiap permintaan"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Pilih Layanan",
+ "DESCRIPTION": "Pilih Layanan Zitadel untuk tindakan Anda."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Pilih Metode",
+ "DESCRIPTION": "Jika Anda hanya ingin menjalankan pada permintaan tertentu, pilih di sini",
+ "NOTE": "Jika Anda tidak memilih metode, tindakan Anda akan berjalan pada setiap permintaan di layanan yang Anda pilih."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Nama Fungsi",
+ "DESCRIPTION": "Pilih fungsi yang ingin Anda jalankan"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Tetapkan Grup",
+ "DESCRIPTION": "Jika Anda hanya ingin menjalankan pada grup peristiwa, tetapkan grup di sini"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Pilih Peristiwa",
+ "DESCRIPTION": "Jika Anda hanya ingin menjalankan pada peristiwa tertentu, tentukan di sini"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "Anda dapat memilih untuk menjalankan target, atau menjalankannya dengan kondisi yang sama dengan target lain.",
+ "TARGET": {
+ "DESCRIPTION": "Target yang ingin Anda jalankan untuk tindakan ini"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Kondisi Eksekusi"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Kondisi",
+ "TYPE": "Jenis",
+ "TARGET": "Target",
+ "CREATIONDATE": "Tanggal Pembuatan"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Target",
+ "DESCRIPTION": "Target adalah tujuan kode yang ingin Anda jalankan dari tindakan. Buat target di sini dan tambahkan ke tindakan Anda.",
+ "CREATE": {
+ "TITLE": "Buat Target Anda",
+ "DESCRIPTION": "Buat target Anda sendiri di luar Zitadel",
+ "NAME": "Nama",
+ "NAME_DESCRIPTION": "Beri target Anda nama yang jelas dan deskriptif agar mudah diidentifikasi nanti",
+ "TYPE": "Jenis",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "Panggilan REST",
+ "restAsync": "REST Asinkron"
+ },
+ "ENDPOINT": "Titik Akhir",
+ "ENDPOINT_DESCRIPTION": "Masukkan titik akhir tempat kode Anda dihosting. Pastikan dapat diakses oleh kami!",
+ "TIMEOUT": "Batas Waktu",
+ "TIMEOUT_DESCRIPTION": "Tetapkan waktu maksimum target Anda untuk merespons. Jika membutuhkan waktu lebih lama, kami akan menghentikan permintaan.",
+ "INTERRUPT_ON_ERROR": "Interupsi jika Terjadi Kesalahan",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Hentikan semua eksekusi saat target mengembalikan kesalahan",
+ "INTERRUPT_ON_ERROR_WARNING": "Perhatian: \"Interupsi jika Terjadi Kesalahan\" akan menghentikan operasi jika terjadi kegagalan, berisiko mengunci akses. Uji dengan opsi ini dinonaktifkan untuk mencegah pemblokiran login/pembuatan.",
+ "AWAIT_RESPONSE": "Tunggu Respons",
+ "AWAIT_RESPONSE_DESCRIPTION": "Kami akan menunggu respons sebelum melakukan hal lain. Berguna jika Anda berniat menggunakan beberapa target untuk satu tindakan"
+ },
+ "TABLE": {
+ "NAME": "Nama",
+ "ENDPOINT": "Titik Akhir",
+ "CREATIONDATE": "Tanggal Pembuatan"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "Memiliki kendali atas seluruh instansi, termasuk semua organisasi",
"IAM_OWNER_VIEWER": "Memiliki izin untuk meninjau seluruh instansi, termasuk semua organisasi",
@@ -1234,6 +1368,7 @@
"BRANDING": "merek",
"PRIVACYPOLICY": "Tautan eksternal",
"OIDC": "Masa berlaku dan masa berlaku Token OIDC",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Pembuat Rahasia",
"SECURITY": "Pengaturan keamanan",
"EVENTS": "Acara",
@@ -1382,7 +1517,10 @@
},
"RESET": "Tetapkan semua untuk diwarisi",
"CONSOLEUSEV2USERAPI": "Gunakan API V2 di konsol untuk pembuatan pengguna",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "Ketika flag ini diaktifkan, konsol menggunakan API Pengguna V2 untuk membuat pengguna baru. Dengan API V2, pengguna yang baru dibuat dimulai tanpa keadaan awal."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "Ketika flag ini diaktifkan, konsol menggunakan API Pengguna V2 untuk membuat pengguna baru. Dengan API V2, pengguna yang baru dibuat dimulai tanpa keadaan awal.",
+ "LOGINV2": "Login V2",
+ "LOGINV2_DESCRIPTION": "Mengaktifkan ini akan mengaktifkan antarmuka login baru berbasis TypeScript dengan keamanan, performa, dan kustomisasi yang lebih baik.",
+ "LOGINV2_BASEURI": "URI dasar"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/it.json b/console/src/assets/i18n/it.json
index f4b45b2110..a42059d11c 100644
--- a/console/src/assets/i18n/it.json
+++ b/console/src/assets/i18n/it.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "La durata massima di un token di refresh inattivo è il tempo massimo in cui un token di refresh può rimanere inutilizzato."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Gestisci le tue chiavi Web OIDC per firmare e convalidare in modo sicuro i token per la tua istanza di ZITADEL.",
+ "TABLE": {
+ "TITLE": "Chiavi Web Attive e Future",
+ "DESCRIPTION": "Le tue chiavi web attive e future. L'attivazione di una nuova chiave disattiverà quella attuale.",
+ "NOTE": "Nota: L'endpoint JWKs OIDC restituisce una risposta memorizzabile nella cache (predefinito 5 min). Evita di attivare una chiave troppo presto, poiché potrebbe non essere ancora disponibile nelle cache e nei client.",
+ "ACTIVATE": "Attiva la prossima Chiave Web",
+ "ACTIVE": "Attualmente attiva",
+ "NEXT": "Prossima in coda",
+ "FUTURE": "Futura",
+ "WARNING": "La chiave web ha meno di 5 minuti"
+ },
+ "CREATE": {
+ "TITLE": "Crea una nuova Chiave Web",
+ "DESCRIPTION": "Creare una nuova chiave web la aggiungerà alla tua lista. ZITADEL utilizza chiavi RSA2048 con hash SHA256 per impostazione predefinita.",
+ "KEY_TYPE": "Tipo di Chiave",
+ "BITS": "Bit",
+ "HASHER": "Hasher",
+ "CURVE": "Curva"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Chiavi Web Precedenti",
+ "DESCRIPTION": "Queste sono le tue chiavi web precedenti che non sono più attive.",
+ "DEACTIVATED_ON": "Disattivata il"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "Testi dei Messaggi",
"DESCRIPTION": "Personalizza i testi delle tue email di notifica o messaggi SMS. Se vuoi disabilitare alcune lingue, limitale nelle impostazioni lingua delle tue istanze.",
@@ -501,6 +527,114 @@
"DOWNLOAD": "Scarica",
"APPLY": "Applicare"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Azioni",
+ "DESCRIPTION": "Le azioni consentono di eseguire codice personalizzato in risposta a richieste API, eventi o funzioni specifiche. Usale per estendere Zitadel, automatizzare i flussi di lavoro e integrarti con altri sistemi.",
+ "TYPES": {
+ "request": "Richiesta",
+ "response": "Risposta",
+ "events": "Eventi",
+ "function": "Funzione"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Crea un'azione",
+ "UPDATE_TITLE": "Aggiorna un'azione",
+ "TYPE": {
+ "DESCRIPTION": "Seleziona quando vuoi che venga eseguita questa azione",
+ "REQUEST": {
+ "TITLE": "Richiesta",
+ "DESCRIPTION": "Richieste che si verificano all'interno di Zitadel. Potrebbe trattarsi di una chiamata di richiesta di accesso."
+ },
+ "RESPONSE": {
+ "TITLE": "Risposta",
+ "DESCRIPTION": "Una risposta a una richiesta all'interno di Zitadel. Pensa alla risposta che ricevi quando recuperi un utente."
+ },
+ "EVENTS": {
+ "TITLE": "Eventi",
+ "DESCRIPTION": "Eventi che si verificano all'interno di Zitadel. Potrebbe trattarsi di qualsiasi cosa, come un utente che crea un account, un accesso riuscito, ecc."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Funzioni",
+ "DESCRIPTION": "Funzioni che puoi chiamare all'interno di Zitadel. Potrebbe trattarsi di qualsiasi cosa, dall'invio di un'e-mail alla creazione di un utente."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Scegli se questa azione si applica a tutte le richieste, a un servizio specifico (ad es. gestione utenti) o a una singola richiesta (ad es. crea utente).",
+ "ALL": {
+ "TITLE": "Tutte",
+ "DESCRIPTION": "Seleziona questa opzione se vuoi eseguire la tua azione su ogni richiesta"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Seleziona servizio",
+ "DESCRIPTION": "Scegli un servizio Zitadel per la tua azione."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Seleziona metodo",
+ "DESCRIPTION": "Se vuoi eseguire solo su una richiesta specifica, selezionala qui",
+ "NOTE": "Se non selezioni un metodo, la tua azione verrà eseguita su ogni richiesta nel servizio selezionato."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Nome funzione",
+ "DESCRIPTION": "Scegli la funzione che vuoi eseguire"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Imposta gruppo",
+ "DESCRIPTION": "Se vuoi eseguire solo su un gruppo di eventi, imposta il gruppo qui"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Seleziona evento",
+ "DESCRIPTION": "Se vuoi eseguire solo su un evento specifico, specificalo qui"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "Puoi scegliere di eseguire un obiettivo o di eseguirlo alle stesse condizioni di altri obiettivi.",
+ "TARGET": {
+ "DESCRIPTION": "L'obiettivo che vuoi eseguire per questa azione"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Condizioni di esecuzione"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Condizione",
+ "TYPE": "Tipo",
+ "TARGET": "Obiettivo",
+ "CREATIONDATE": "Data di creazione"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Obiettivi",
+ "DESCRIPTION": "Un obiettivo è la destinazione del codice che vuoi eseguire da un'azione. Crea un obiettivo qui e aggiungilo alle tue azioni.",
+ "CREATE": {
+ "TITLE": "Crea il tuo obiettivo",
+ "DESCRIPTION": "Crea il tuo obiettivo al di fuori di Zitadel",
+ "NAME": "Nome",
+ "NAME_DESCRIPTION": "Dai al tuo obiettivo un nome chiaro e descrittivo per renderlo facile da identificare in seguito",
+ "TYPE": "Tipo",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "Chiamata REST",
+ "restAsync": "REST Asincrono"
+ },
+ "ENDPOINT": "Endpoint",
+ "ENDPOINT_DESCRIPTION": "Inserisci l'endpoint in cui è ospitato il tuo codice. Assicurati che sia accessibile per noi!",
+ "TIMEOUT": "Timeout",
+ "TIMEOUT_DESCRIPTION": "Imposta il tempo massimo che il tuo obiettivo ha per rispondere. Se impiega più tempo, interromperemo la richiesta.",
+ "INTERRUPT_ON_ERROR": "Interrompi in caso di errore",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Interrompi tutte le esecuzioni quando gli obiettivi restituiscono un errore",
+ "INTERRUPT_ON_ERROR_WARNING": "Attenzione: “Interrompi in caso di errore” arresta le operazioni in caso di fallimento, rischiando il blocco. Testare con l’opzione disattivata per evitare il blocco dell’accesso/creazione.",
+ "AWAIT_RESPONSE": "Attendi risposta",
+ "AWAIT_RESPONSE_DESCRIPTION": "Aspetteremo una risposta prima di fare altro. Utile se intendi utilizzare più obiettivi per una singola azione"
+ },
+ "TABLE": {
+ "NAME": "Nome",
+ "ENDPOINT": "Endpoint",
+ "CREATIONDATE": "Data di creazione"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "Ha il controllo sull'intera istanza, comprese tutte le organizzazioni",
"IAM_OWNER_VIEWER": "Ha l'autorizzazione per esaminare l'intera istanza, comprese tutte le organizzazioni",
@@ -1356,6 +1490,7 @@
"BRANDING": "Branding",
"PRIVACYPOLICY": "Informativa sulla privacy e TOS",
"OIDC": "OIDC Token lifetime e scadenza",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Aspetto dei segreti",
"SECURITY": "Impostazioni di sicurezza",
"EVENTS": "Eventi",
@@ -1515,7 +1650,10 @@
},
"RESET": "Imposta tutto su predefinito",
"CONSOLEUSEV2USERAPI": "Utilizza l'API V2 nella console per la creazione degli utenti",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "Quando questa opzione è abilitata, la console utilizza l'API V2 User per creare nuovi utenti. Con l'API V2, i nuovi utenti creati iniziano senza uno stato iniziale."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "Quando questa opzione è abilitata, la console utilizza l'API V2 User per creare nuovi utenti. Con l'API V2, i nuovi utenti creati iniziano senza uno stato iniziale.",
+ "LOGINV2": "Accesso V2",
+ "LOGINV2_DESCRIPTION": "Abilitando questa opzione si attiva la nuova interfaccia di login basata su TypeScript con sicurezza, prestazioni e personalizzazione migliorate.",
+ "LOGINV2_BASEURI": "URI di base"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/ja.json b/console/src/assets/i18n/ja.json
index d323b961d2..8a9574b7d9 100644
--- a/console/src/assets/i18n/ja.json
+++ b/console/src/assets/i18n/ja.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "アイドル状態のリフレッシュトークンの有効期間は、リフレッシュトークンが使用されない最大時間です。"
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "ZITADELインスタンスのトークンを安全に署名および検証するために、OIDC Webキーを管理します。",
+ "TABLE": {
+ "TITLE": "アクティブおよび今後のWebキー",
+ "DESCRIPTION": "現在アクティブなWebキーと、今後使用予定のWebキーです。新しいキーをアクティブ化すると、現在のキーは無効になります。",
+ "NOTE": "注意: JWKs OIDCエンドポイントはキャッシュ可能なレスポンスを返します(デフォルト5分)。キーを早くアクティブ化しすぎると、キャッシュやクライアントでまだ利用できない可能性があります。",
+ "ACTIVATE": "次のWebキーをアクティブ化",
+ "ACTIVE": "現在アクティブ",
+ "NEXT": "次のキュー",
+ "FUTURE": "今後",
+ "WARNING": "ウェブキーは5分未満です。"
+ },
+ "CREATE": {
+ "TITLE": "新しいWebキーを作成",
+ "DESCRIPTION": "新しいWebキーを作成すると、リストに追加されます。ZITADELはデフォルトでRSA2048キーとSHA256ハッシュを使用します。",
+ "KEY_TYPE": "キーの種類",
+ "BITS": "ビット",
+ "HASHER": "ハッシュ方式",
+ "CURVE": "カーブ"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "以前のWebキー",
+ "DESCRIPTION": "これらは、すでに無効になった以前のWebキーです。",
+ "DEACTIVATED_ON": "無効化日"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "メッセージテキスト",
"DESCRIPTION": "通知メールやSMSメッセージのテキストをカスタマイズします。一部の言語を無効にしたい場合は、インスタンスの言語設定で制限してください。",
@@ -502,6 +528,114 @@
"DOWNLOAD": "ダウンロード",
"APPLY": "アプライ"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "アクション",
+ "DESCRIPTION": "アクションを使用すると、APIリクエスト、イベント、または特定の関数に応答してカスタムコードを実行できます。これらを使用して、Zitadelを拡張し、ワークフローを自動化し、他のシステムと統合します。",
+ "TYPES": {
+ "request": "リクエスト",
+ "response": "レスポンス",
+ "events": "イベント",
+ "function": "関数"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "アクションを作成",
+ "UPDATE_TITLE": "アクションを更新",
+ "TYPE": {
+ "DESCRIPTION": "このアクションを実行するタイミングを選択します",
+ "REQUEST": {
+ "TITLE": "リクエスト",
+ "DESCRIPTION": "Zitadel内で発生するリクエスト。これはログインリクエストの呼び出しのようなものです。"
+ },
+ "RESPONSE": {
+ "TITLE": "レスポンス",
+ "DESCRIPTION": "Zitadel内のリクエストからのレスポンス。ユーザーのフェッチから返されるレスポンスを考えてください。"
+ },
+ "EVENTS": {
+ "TITLE": "イベント",
+ "DESCRIPTION": "Zitadel内で発生するイベント。これは、ユーザーアカウントの作成、ログインの成功など、あらゆる可能性があります。"
+ },
+ "FUNCTIONS": {
+ "TITLE": "関数",
+ "DESCRIPTION": "Zitadel内で呼び出すことができる関数。これは、電子メールの送信からユーザーの作成まで、あらゆる可能性があります。"
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "このアクションをすべてのリクエスト、特定のサービス(例:ユーザー管理)、または単一のリクエスト(例:ユーザーの作成)に適用するかどうかを選択します。",
+ "ALL": {
+ "TITLE": "すべて",
+ "DESCRIPTION": "すべてのリクエストでアクションを実行する場合は、これを選択します"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "サービスを選択",
+ "DESCRIPTION": "アクションのZitadelサービスを選択します。"
+ },
+ "SELECT_METHOD": {
+ "TITLE": "メソッドを選択",
+ "DESCRIPTION": "特定のリクエストでのみ実行する場合は、ここで選択します",
+ "NOTE": "メソッドを選択しない場合、アクションは選択したサービスのすべてのリクエストで実行されます。"
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "関数名",
+ "DESCRIPTION": "実行する関数を選択します"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "グループを設定",
+ "DESCRIPTION": "イベントのグループでのみ実行する場合は、ここでグループを設定します"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "イベントを選択",
+ "DESCRIPTION": "特定のイベントでのみ実行する場合は、ここで指定します"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "ターゲットを実行するか、他のターゲットと同じ条件で実行するかを選択できます。",
+ "TARGET": {
+ "DESCRIPTION": "このアクションで実行するターゲット"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "実行条件"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "条件",
+ "TYPE": "タイプ",
+ "TARGET": "ターゲット",
+ "CREATIONDATE": "作成日"
+ }
+ },
+ "TARGET": {
+ "TITLE": "ターゲット",
+ "DESCRIPTION": "ターゲットは、アクションから実行するコードの宛先です。ここでターゲットを作成し、アクションに追加します。",
+ "CREATE": {
+ "TITLE": "ターゲットを作成",
+ "DESCRIPTION": "Zitadelの外部で独自のターゲットを作成します",
+ "NAME": "名前",
+ "NAME_DESCRIPTION": "後で簡単に識別できるように、ターゲットに明確でわかりやすい名前を付けます",
+ "TYPE": "タイプ",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "REST 呼び出し",
+ "restAsync": "REST 非同期"
+ },
+ "ENDPOINT": "エンドポイント",
+ "ENDPOINT_DESCRIPTION": "コードがホストされているエンドポイントを入力します。アクセス可能であることを確認してください。",
+ "TIMEOUT": "タイムアウト",
+ "TIMEOUT_DESCRIPTION": "ターゲットが応答する最大時間を設定します。これより時間がかかる場合は、リクエストを停止します。",
+ "INTERRUPT_ON_ERROR": "エラー時に中断",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "ターゲットがエラーを返した場合、すべての実行を停止します",
+ "INTERRUPT_ON_ERROR_WARNING": "注意:「エラー時に中断」を有効にすると、失敗時に処理が停止し、ロックアウトのリスクがあります。ログイン/作成のブロックを防ぐため、無効にしてテストしてください。",
+ "AWAIT_RESPONSE": "レスポンスを待機",
+ "AWAIT_RESPONSE_DESCRIPTION": "他の処理を行う前にレスポンスを待機します。単一のアクションに複数のターゲットを使用する場合に便利です"
+ },
+ "TABLE": {
+ "NAME": "名前",
+ "ENDPOINT": "エンドポイント",
+ "CREATIONDATE": "作成日"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "すべての組織を含むインスタンス全体を管理する権限を持ちます",
"IAM_OWNER_VIEWER": "すべての組織を含むインスタンス全体を閲覧する権限を持ちます",
@@ -1356,6 +1490,7 @@
"BRANDING": "ブランディング",
"PRIVACYPOLICY": "プライバシーポリシー",
"OIDC": "OIDCトークンのライフタイムと有効期限",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "シークレット設定",
"SECURITY": "セキュリティ設定",
"EVENTS": "イベント",
@@ -1515,7 +1650,10 @@
},
"RESET": "すべて継承に設定",
"CONSOLEUSEV2USERAPI": "コンソールでユーザー作成のためにV2 APIを使用してください。",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "このフラグが有効化されると、コンソールはV2ユーザーAPIを使用して新しいユーザーを作成します。V2 APIでは、新しく作成されたユーザーは初期状態なしで開始します。"
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "このフラグが有効化されると、コンソールはV2ユーザーAPIを使用して新しいユーザーを作成します。V2 APIでは、新しく作成されたユーザーは初期状態なしで開始します。",
+ "LOGINV2": "ログイン V2",
+ "LOGINV2_DESCRIPTION": "これを有効にすると、セキュリティ、パフォーマンス、およびカスタマイズ性が向上した、TypeScript ベースの新しいログイン UI が有効になります。",
+ "LOGINV2_BASEURI": "ベースURI"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/ko.json b/console/src/assets/i18n/ko.json
index e6184cb8d1..c596b3b067 100644
--- a/console/src/assets/i18n/ko.json
+++ b/console/src/assets/i18n/ko.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "유휴 갱신 토큰 수명은 갱신 토큰이 사용되지 않는 최대 기간을 의미합니다."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "ZITADEL 인스턴스의 토큰을 안전하게 서명하고 검증하기 위해 OIDC 웹 키를 관리하세요.",
+ "TABLE": {
+ "TITLE": "활성 및 예정된 웹 키",
+ "DESCRIPTION": "현재 활성화된 웹 키와 앞으로 활성화될 웹 키입니다. 새로운 키를 활성화하면 기존 키는 비활성화됩니다.",
+ "NOTE": "참고: JWKs OIDC 엔드포인트는 캐시 가능한 응답을 반환합니다 (기본값: 5분). 키를 너무 빨리 활성화하면 캐시 및 클라이언트에서 아직 사용할 수 없을 수 있습니다.",
+ "ACTIVATE": "다음 웹 키 활성화",
+ "ACTIVE": "현재 활성화됨",
+ "NEXT": "대기 중인 다음 키",
+ "FUTURE": "향후 사용 예정",
+ "WARNING": "웹 키가 5분 미만입니다."
+ },
+ "CREATE": {
+ "TITLE": "새 웹 키 생성",
+ "DESCRIPTION": "새 웹 키를 생성하면 목록에 추가됩니다. ZITADEL은 기본적으로 RSA2048 키와 SHA256 해시 알고리즘을 사용합니다.",
+ "KEY_TYPE": "키 유형",
+ "BITS": "비트",
+ "HASHER": "해시 알고리즘",
+ "CURVE": "곡선"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "이전 웹 키",
+ "DESCRIPTION": "더 이상 활성 상태가 아닌 이전 웹 키 목록입니다.",
+ "DEACTIVATED_ON": "비활성화된 날짜"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "메시지 텍스트",
"DESCRIPTION": "알림 이메일 또는 SMS 메시지의 텍스트를 사용자 정의하세요. 언어를 비활성화하려면 인스턴스의 언어 설정에서 제한하세요.",
@@ -502,6 +528,114 @@
"DOWNLOAD": "다운로드",
"APPLY": "적용"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "작업",
+ "DESCRIPTION": "작업을 통해 API 요청, 이벤트 또는 특정 함수에 대한 응답으로 사용자 지정 코드를 실행할 수 있습니다. 이를 사용하여 Zitadel을 확장하고 워크플로를 자동화하며 다른 시스템과 통합합니다.",
+ "TYPES": {
+ "request": "요청",
+ "response": "응답",
+ "events": "이벤트",
+ "function": "함수"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "작업 생성",
+ "UPDATE_TITLE": "작업 업데이트",
+ "TYPE": {
+ "DESCRIPTION": "이 작업을 실행할 시점을 선택하십시오.",
+ "REQUEST": {
+ "TITLE": "요청",
+ "DESCRIPTION": "Zitadel 내에서 발생하는 요청. 이는 로그인 요청 호출과 같은 것일 수 있습니다."
+ },
+ "RESPONSE": {
+ "TITLE": "응답",
+ "DESCRIPTION": "Zitadel 내 요청으로부터의 응답. 사용자를 가져올 때 받는 응답을 생각해 보십시오."
+ },
+ "EVENTS": {
+ "TITLE": "이벤트",
+ "DESCRIPTION": "Zitadel 내에서 발생하는 이벤트. 이는 사용자 계정 생성, 로그인 성공 등 모든 것이 될 수 있습니다."
+ },
+ "FUNCTIONS": {
+ "TITLE": "함수",
+ "DESCRIPTION": "Zitadel 내에서 호출할 수 있는 함수입니다. 이는 이메일 전송부터 사용자 생성까지 모든 것이 될 수 있습니다."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "이 작업이 모든 요청, 특정 서비스(예: 사용자 관리) 또는 단일 요청(예: 사용자 생성)에 적용되는지 선택하십시오.",
+ "ALL": {
+ "TITLE": "모두",
+ "DESCRIPTION": "모든 요청에서 작업을 실행하려면 이것을 선택하십시오."
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "서비스 선택",
+ "DESCRIPTION": "작업에 대한 Zitadel 서비스를 선택하십시오."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "메서드 선택",
+ "DESCRIPTION": "특정 요청에서만 실행하려면 여기에서 선택하십시오.",
+ "NOTE": "메서드를 선택하지 않으면 선택한 서비스의 모든 요청에서 작업이 실행됩니다."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "함수 이름",
+ "DESCRIPTION": "실행할 함수를 선택하십시오."
+ },
+ "SELECT_GROUP": {
+ "TITLE": "그룹 설정",
+ "DESCRIPTION": "이벤트 그룹에서만 실행하려면 여기에서 그룹을 설정하십시오."
+ },
+ "SELECT_EVENT": {
+ "TITLE": "이벤트 선택",
+ "DESCRIPTION": "특정 이벤트에서만 실행하려면 여기에서 지정하십시오."
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "타겟을 실행하거나 다른 타겟과 동일한 조건으로 실행하도록 선택할 수 있습니다.",
+ "TARGET": {
+ "DESCRIPTION": "이 작업에 대해 실행할 타겟"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "실행 조건"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "조건",
+ "TYPE": "유형",
+ "TARGET": "타겟",
+ "CREATIONDATE": "생성 날짜"
+ }
+ },
+ "TARGET": {
+ "TITLE": "타겟",
+ "DESCRIPTION": "타겟은 작업에서 실행하려는 코드의 대상입니다. 여기에서 타겟을 생성하고 작업에 추가하십시오.",
+ "CREATE": {
+ "TITLE": "타겟 생성",
+ "DESCRIPTION": "Zitadel 외부에서 자체 타겟을 생성하십시오.",
+ "NAME": "이름",
+ "NAME_DESCRIPTION": "나중에 쉽게 식별할 수 있도록 타겟에 명확하고 설명적인 이름을 지정하십시오.",
+ "TYPE": "유형",
+ "TYPES": {
+ "restWebhook": "REST 웹훅",
+ "restCall": "REST 호출",
+ "restAsync": "REST 비동기"
+ },
+ "ENDPOINT": "엔드포인트",
+ "ENDPOINT_DESCRIPTION": "코드가 호스팅되는 엔드포인트를 입력하십시오. 우리에게 액세스할 수 있는지 확인하십시오!",
+ "TIMEOUT": "시간 초과",
+ "TIMEOUT_DESCRIPTION": "타겟이 응답해야 하는 최대 시간을 설정하십시오. 시간이 더 오래 걸리면 요청을 중지합니다.",
+ "INTERRUPT_ON_ERROR": "오류 시 중단",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "타겟이 오류를 반환하면 모든 실행을 중지하십시오.",
+ "INTERRUPT_ON_ERROR_WARNING": "주의: “오류 시 중단” 기능은 실패 시 작업을 중단하며, 잠금 위험이 있습니다. 로그인/생성 차단을 방지하려면 비활성화된 상태로 테스트하세요.",
+ "AWAIT_RESPONSE": "응답 대기",
+ "AWAIT_RESPONSE_DESCRIPTION": "다른 작업을 수행하기 전에 응답을 기다립니다. 단일 작업에 여러 타겟을 사용하려는 경우 유용합니다."
+ },
+ "TABLE": {
+ "NAME": "이름",
+ "ENDPOINT": "엔드포인트",
+ "CREATIONDATE": "생성 날짜"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "인스턴스와 모든 조직에 대한 제어 권한이 있습니다",
"IAM_OWNER_VIEWER": "인스턴스와 모든 조직을 검토할 수 있는 권한이 있습니다",
@@ -1356,6 +1490,7 @@
"BRANDING": "브랜딩",
"PRIVACYPOLICY": "외부 링크",
"OIDC": "OIDC 토큰 수명 및 만료",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "시크릿 생성기",
"SECURITY": "보안 설정",
"EVENTS": "이벤트",
@@ -1515,7 +1650,10 @@
},
"RESET": "모두 상속으로 설정",
"CONSOLEUSEV2USERAPI": "콘솔에서 사용자 생성을 위해 V2 API를 사용하세요",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "이 플래그가 활성화되면 콘솔은 V2 사용자 API를 사용하여 새 사용자를 생성합니다. V2 API를 사용하면 새로 생성된 사용자는 초기 상태 없이 시작합니다."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "이 플래그가 활성화되면 콘솔은 V2 사용자 API를 사용하여 새 사용자를 생성합니다. V2 API를 사용하면 새로 생성된 사용자는 초기 상태 없이 시작합니다.",
+ "LOGINV2": "로그인 V2",
+ "LOGINV2_DESCRIPTION": "이 옵션을 활성화하면 보안, 성능 및 사용자 정의 기능이 향상된 새로운 TypeScript 기반 로그인 UI가 활성화됩니다.",
+ "LOGINV2_BASEURI": "기본 URI"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/mk.json b/console/src/assets/i18n/mk.json
index 9002ff2534..c01b485f0a 100644
--- a/console/src/assets/i18n/mk.json
+++ b/console/src/assets/i18n/mk.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "Животниот век на неактивниот токен за освежување е максималното време кое токен за освежување може да не се користи."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Управувајте со вашите OIDC веб-клучеви за безбедно потпишување и валидација на токени за вашата ZITADEL инстанца.",
+ "TABLE": {
+ "TITLE": "Активни и Идни Веб-Клучеви",
+ "DESCRIPTION": "Вашите активни и претстојни веб-клучеви. Активирањето на нов клуч ќе го деактивира тековниот.",
+ "NOTE": "Забелешка: JWKs OIDC крајната точка враќа одговор што може да се кешира (стандардно 5 минути). Избегнувајте активирање на клучот пребрзо, бидејќи можеби сè уште не е достапен во кешот и кај клиентите.",
+ "ACTIVATE": "Активирај го следниот веб-клуч",
+ "ACTIVE": "Моментално активен",
+ "NEXT": "Следен во редот",
+ "FUTURE": "Иднина",
+ "WARNING": "Веб-клучот е помалку од 5 минути стар"
+ },
+ "CREATE": {
+ "TITLE": "Креирај нов веб-клуч",
+ "DESCRIPTION": "Креирањето нов веб-клуч го додава на вашата листа. ZITADEL стандардно користи RSA2048 клучеви со SHA256 алгоритам за хаширање.",
+ "KEY_TYPE": "Тип на клуч",
+ "BITS": "Битови",
+ "HASHER": "Алгоритам за хаширање",
+ "CURVE": "Крива"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Претходни веб-клучеви",
+ "DESCRIPTION": "Ова се вашите претходни веб-клучеви кои повеќе не се активни.",
+ "DEACTIVATED_ON": "Деактивиран на"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "Текстови на пораки",
"DESCRIPTION": "Прилагодете ги текстовите на вашите е-маил или SMS пораки за известување. Ако сакате да оневозможите некои јазици, ограничете ги во поставките за јазик на вашите инстанци.",
@@ -502,6 +528,114 @@
"DOWNLOAD": "Преземи",
"APPLY": "Пријавете се"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Акции",
+ "DESCRIPTION": "Акциите ви овозможуваат да извршувате прилагоден код како одговор на API барања, настани или специфични функции. Користете ги за да го проширите Zitadel, да ги автоматизирате работните процеси и да се интегрирате со други системи.",
+ "TYPES": {
+ "request": "Барање",
+ "response": "Одговор",
+ "events": "Настани",
+ "function": "Функција"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Креирај акција",
+ "UPDATE_TITLE": "Ажурирај акција",
+ "TYPE": {
+ "DESCRIPTION": "Изберете кога сакате да се изврши оваа акција",
+ "REQUEST": {
+ "TITLE": "Барање",
+ "DESCRIPTION": "Барања што се случуваат во Zitadel. Ова може да биде нешто како повик за барање за најава."
+ },
+ "RESPONSE": {
+ "TITLE": "Одговор",
+ "DESCRIPTION": "Одговор од барање во Zitadel. Размислете за одговорот што го добивате при преземање на корисник."
+ },
+ "EVENTS": {
+ "TITLE": "Настани",
+ "DESCRIPTION": "Настани што се случуваат во Zitadel. Ова може да биде нешто како корисник што креира сметка, успешна најава итн."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Функции",
+ "DESCRIPTION": "Функции што можете да ги повикате во Zitadel. Ова може да биде сè, од испраќање е-пошта до креирање корисник."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Изберете дали оваа акција се однесува на сите барања, одредена услуга (на пр. управување со корисници) или едно барање (на пр. креирај корисник).",
+ "ALL": {
+ "TITLE": "Сите",
+ "DESCRIPTION": "Изберете го ова ако сакате да ја извршите вашата акција на секое барање"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Изберете услуга",
+ "DESCRIPTION": "Изберете Zitadel услуга за вашата акција."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Изберете метод",
+ "DESCRIPTION": "Ако сакате да извршите само на одредено барање, изберете го тука",
+ "NOTE": "Ако не изберете метод, вашата акција ќе се изврши на секое барање во вашата избрана услуга."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Име на функција",
+ "DESCRIPTION": "Изберете ја функцијата што сакате да ја извршите"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Постави група",
+ "DESCRIPTION": "Ако сакате да извршите само на група настани, поставете ја групата тука"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Изберете настан",
+ "DESCRIPTION": "Ако сакате да извршите само на одреден настан, наведете го тука"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "Можете да изберете да извршите цел или да ја извршите под истите услови како и другите цели.",
+ "TARGET": {
+ "DESCRIPTION": "Целта што сакате да ја извршите за оваа акција"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Услови за извршување"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Услов",
+ "TYPE": "Тип",
+ "TARGET": "Цел",
+ "CREATIONDATE": "Датум на создавање"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Цели",
+ "DESCRIPTION": "Целта е дестинација на кодот што сакате да го извршите од акција. Креирајте цел овде и додајте ја на вашите акции.",
+ "CREATE": {
+ "TITLE": "Креирајте ја вашата цел",
+ "DESCRIPTION": "Креирајте ја вашата сопствена цел надвор од Zitadel",
+ "NAME": "Име",
+ "NAME_DESCRIPTION": "Дајте ѝ на вашата цел јасно, опис на име за да биде лесно да се идентификува подоцна",
+ "TYPE": "Тип",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "REST Повик",
+ "restAsync": "REST Асинхроно"
+ },
+ "ENDPOINT": "Крајна точка",
+ "ENDPOINT_DESCRIPTION": "Внесете ја крајната точка каде што е хостиран вашиот код. Осигурете се дека е достапна за нас!",
+ "TIMEOUT": "Време на истекување",
+ "TIMEOUT_DESCRIPTION": "Поставете го максималното време што вашата цел треба да одговори. Ако трае подолго, ќе го запреме барањето.",
+ "INTERRUPT_ON_ERROR": "Прекини при грешка",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Запрете ги сите извршувања кога целите ќе вратат грешка",
+ "INTERRUPT_ON_ERROR_WARNING": "Внимание: „Прекини при грешка“ ги запира операциите при неуспех, со ризик од блокирање. Тестирајте со исклучена опција за да избегнете блокирање на најавата/креирањето.",
+ "AWAIT_RESPONSE": "Почекај одговор",
+ "AWAIT_RESPONSE_DESCRIPTION": "Ќе почекаме одговор пред да направиме нешто друго. Корисно ако планирате да користите повеќе цели за една акција"
+ },
+ "TABLE": {
+ "NAME": "Име",
+ "ENDPOINT": "Крајна точка",
+ "CREATIONDATE": "Датум на создавање"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "Има контрола врз целата инстанца, вклучувајќи ги сите организации",
"IAM_OWNER_VIEWER": "Има дозвола за преглед на целата инстанца, вклучувајќи ги сите организации",
@@ -1357,6 +1491,7 @@
"BRANDING": "Брендирање",
"PRIVACYPOLICY": "Политика за приватност",
"OIDC": "OIDC времетраење и истекување на токени",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Изглед на тајни",
"SECURITY": "Подесувања за безбедност",
"EVENTS": "Настани",
@@ -1516,7 +1651,10 @@
},
"RESET": "Поставете ги сите да наследат",
"CONSOLEUSEV2USERAPI": "Користете V2 API во конзолата за креирање на корисници",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "Кога ова знаме е овозможено, конзолата го користи V2 User API за креирање на нови корисници. Со V2 API, новосоздадените корисници започнуваат без почетна состојба."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "Кога ова знаме е овозможено, конзолата го користи V2 User API за креирање на нови корисници. Со V2 API, новосоздадените корисници започнуваат без почетна состојба.",
+ "LOGINV2": "Најава V2",
+ "LOGINV2_DESCRIPTION": "Овозможувањето на ова ја активира новата TypeScript-базирана најава со подобрена безбедност, перформанси и прилагодливост.",
+ "LOGINV2_BASEURI": "Основен URI"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/nl.json b/console/src/assets/i18n/nl.json
index 04e3174166..ab8243e2a5 100644
--- a/console/src/assets/i18n/nl.json
+++ b/console/src/assets/i18n/nl.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "De levensduur van het inactieve vernieuwingstoken is de maximale tijd dat een vernieuwingstoken ongebruikt kan zijn."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Beheer je OIDC Web Keys om tokens veilig te ondertekenen en te valideren voor je ZITADEL-instantie.",
+ "TABLE": {
+ "TITLE": "Actieve en Toekomstige Websleutels",
+ "DESCRIPTION": "Je actieve en aankomende websleutels. Het activeren van een nieuwe sleutel deactiveert de huidige.",
+ "NOTE": "Opmerking: Het JWKs OIDC-eindpunt geeft een cachebare respons terug (standaard 5 minuten). Vermijd het te vroeg activeren van een sleutel, omdat deze mogelijk nog niet beschikbaar is in caches en bij clients.",
+ "ACTIVATE": "Volgende Websleutel activeren",
+ "ACTIVE": "Momenteel actief",
+ "NEXT": "Volgende in de wachtrij",
+ "FUTURE": "Toekomstig",
+ "WARNING": "De websleutel is minder dan 5 minuten oud"
+ },
+ "CREATE": {
+ "TITLE": "Nieuwe Websleutel aanmaken",
+ "DESCRIPTION": "Het aanmaken van een nieuwe websleutel voegt deze toe aan je lijst. ZITADEL gebruikt standaard RSA2048-sleutels met een SHA256-hasher.",
+ "KEY_TYPE": "Sleuteltype",
+ "BITS": "Bits",
+ "HASHER": "Hasher",
+ "CURVE": "Curve"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Vorige Websleutels",
+ "DESCRIPTION": "Dit zijn je vorige websleutels die niet langer actief zijn.",
+ "DEACTIVATED_ON": "Gedeactiveerd op"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "Berichtteksten",
"DESCRIPTION": "Pas de teksten van je notificatie-e-mail of SMS-berichten aan. Als je sommige talen wilt uitschakelen, beperk ze dan in de taalinstellingen van je instanties.",
@@ -502,6 +528,114 @@
"DOWNLOAD": "Download",
"APPLY": "Toepassen"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Acties",
+ "DESCRIPTION": "Met acties kunt u aangepaste code uitvoeren als reactie op API-verzoeken, gebeurtenissen of specifieke functies. Gebruik ze om Zitadel uit te breiden, workflows te automatiseren en te integreren met andere systemen.",
+ "TYPES": {
+ "request": "Verzoek",
+ "response": "Reactie",
+ "events": "Gebeurtenissen",
+ "function": "Functie"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Een actie maken",
+ "UPDATE_TITLE": "Een actie bijwerken",
+ "TYPE": {
+ "DESCRIPTION": "Selecteer wanneer u deze actie wilt uitvoeren",
+ "REQUEST": {
+ "TITLE": "Verzoek",
+ "DESCRIPTION": "Verzoeken die binnen Zitadel plaatsvinden. Dit kan zoiets zijn als een inlogverzoek-oproep."
+ },
+ "RESPONSE": {
+ "TITLE": "Reactie",
+ "DESCRIPTION": "Een reactie op een verzoek binnen Zitadel. Denk aan de reactie die u terugkrijgt van het ophalen van een gebruiker."
+ },
+ "EVENTS": {
+ "TITLE": "Gebeurtenissen",
+ "DESCRIPTION": "Gebeurtenissen die binnen Zitadel plaatsvinden. Dit kan van alles zijn, zoals een gebruiker die een account aanmaakt, een succesvolle login enz."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Functies",
+ "DESCRIPTION": "Functies die u binnen Zitadel kunt aanroepen. Dit kan van alles zijn, van het verzenden van een e-mail tot het maken van een gebruiker."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Kies of deze actie van toepassing is op alle verzoeken, een specifieke service (bijv. gebruikersbeheer) of een enkel verzoek (bijv. gebruiker maken).",
+ "ALL": {
+ "TITLE": "Alle",
+ "DESCRIPTION": "Selecteer dit als u uw actie bij elk verzoek wilt uitvoeren"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Service selecteren",
+ "DESCRIPTION": "Kies een Zitadel-service voor uw actie."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Methode selecteren",
+ "DESCRIPTION": "Als u alleen bij een specifiek verzoek wilt uitvoeren, selecteert u dit hier",
+ "NOTE": "Als u geen methode selecteert, wordt uw actie bij elk verzoek in uw geselecteerde service uitgevoerd."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Functienaam",
+ "DESCRIPTION": "Kies de functie die u wilt uitvoeren"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Groep instellen",
+ "DESCRIPTION": "Als u alleen bij een groep gebeurtenissen wilt uitvoeren, stelt u de groep hier in"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Gebeurtenis selecteren",
+ "DESCRIPTION": "Als u alleen bij een specifieke gebeurtenis wilt uitvoeren, specificeert u deze hier"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "U kunt ervoor kiezen om een doel uit te voeren of om het onder dezelfde voorwaarden als andere doelen uit te voeren.",
+ "TARGET": {
+ "DESCRIPTION": "Het doel dat u voor deze actie wilt uitvoeren"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Uitvoeringsvoorwaarden"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Voorwaarde",
+ "TYPE": "Type",
+ "TARGET": "Doel",
+ "CREATIONDATE": "Aanmaakdatum"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Doelen",
+ "DESCRIPTION": "Een doel is de bestemming van de code die u vanuit een actie wilt uitvoeren. Maak hier een doel en voeg het toe aan uw acties.",
+ "CREATE": {
+ "TITLE": "Uw doel maken",
+ "DESCRIPTION": "Maak uw eigen doel buiten Zitadel",
+ "NAME": "Naam",
+ "NAME_DESCRIPTION": "Geef uw doel een duidelijke, beschrijvende naam om het later gemakkelijk te kunnen identificeren",
+ "TYPE": "Type",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "REST Aanroep",
+ "restAsync": "REST Asynchroon"
+ },
+ "ENDPOINT": "Eindpunt",
+ "ENDPOINT_DESCRIPTION": "Voer het eindpunt in waar uw code wordt gehost. Zorg ervoor dat het voor ons toegankelijk is!",
+ "TIMEOUT": "Time-out",
+ "TIMEOUT_DESCRIPTION": "Stel de maximale tijd in die uw doel heeft om te reageren. Als het langer duurt, stoppen we het verzoek.",
+ "INTERRUPT_ON_ERROR": "Onderbreken bij fout",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Stop alle uitvoeringen als de doelen een fout retourneren",
+ "INTERRUPT_ON_ERROR_WARNING": "Let op: “Onderbreken bij fout” stopt operaties bij een mislukking, met kans op blokkering. Test met deze optie uitgeschakeld om inloggen/aanmaken niet te blokkeren.",
+ "AWAIT_RESPONSE": "Wachten op reactie",
+ "AWAIT_RESPONSE_DESCRIPTION": "We wachten op een reactie voordat we iets anders doen. Handig als u van plan bent om meerdere doelen voor één actie te gebruiken"
+ },
+ "TABLE": {
+ "NAME": "Naam",
+ "ENDPOINT": "Eindpunt",
+ "CREATIONDATE": "Aanmaakdatum"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "Heeft controle over de hele instantie, inclusief alle organisaties",
"IAM_OWNER_VIEWER": "Heeft toestemming om de hele instantie te bekijken, inclusief alle organisaties",
@@ -1356,6 +1490,7 @@
"BRANDING": "Branding",
"PRIVACYPOLICY": "Privacybeleid",
"OIDC": "OIDC Token levensduur en vervaldatum",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Secret Generator",
"SECURITY": "Beveiligingsinstellingen",
"EVENTS": "Evenementen",
@@ -1515,7 +1650,10 @@
},
"RESET": "Alles instellen op overgenomen",
"CONSOLEUSEV2USERAPI": "Gebruik de V2 API in de console voor het aanmaken van gebruikers",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "Wanneer deze vlag is ingeschakeld, gebruikt de console de V2 User API om nieuwe gebruikers aan te maken. Met de V2 API beginnen nieuw aangemaakte gebruikers zonder een initiële status."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "Wanneer deze vlag is ingeschakeld, gebruikt de console de V2 User API om nieuwe gebruikers aan te maken. Met de V2 API beginnen nieuw aangemaakte gebruikers zonder een initiële status.",
+ "LOGINV2": "Inloggen V2",
+ "LOGINV2_DESCRIPTION": "Door dit in te schakelen wordt de nieuwe TypeScript-gebaseerde login-UI geactiveerd met verbeterde beveiliging, prestaties en aanpasbaarheid.",
+ "LOGINV2_BASEURI": "Basis-URI"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/pl.json b/console/src/assets/i18n/pl.json
index c76236e9a6..b071c4f99a 100644
--- a/console/src/assets/i18n/pl.json
+++ b/console/src/assets/i18n/pl.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "Czas życia bezczynnego tokena odświeżania to maksymalny czas, przez który token odświeżania może pozostać nieużywany."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Zarządzaj swoimi kluczami internetowymi OIDC, aby bezpiecznie podpisywać i weryfikować tokeny w swojej instancji ZITADEL.",
+ "TABLE": {
+ "TITLE": "Aktywne i Przyszłe Klucze Internetowe",
+ "DESCRIPTION": "Twoje aktywne i nadchodzące klucze internetowe. Aktywacja nowego klucza spowoduje dezaktywację obecnego.",
+ "NOTE": "Uwaga: Punkt końcowy JWKs OIDC zwraca odpowiedź możliwą do buforowania (domyślnie 5 minut). Unikaj zbyt wczesnej aktywacji klucza, ponieważ może on nie być jeszcze dostępny w pamięci podręcznej i dla klientów.",
+ "ACTIVATE": "Aktywuj następny klucz internetowy",
+ "ACTIVE": "Obecnie aktywny",
+ "NEXT": "Następny w kolejce",
+ "FUTURE": "Przyszłe",
+ "WARNING": "Klucz sieciowy ma mniej niż 5 minut"
+ },
+ "CREATE": {
+ "TITLE": "Utwórz nowy klucz internetowy",
+ "DESCRIPTION": "Utworzenie nowego klucza internetowego doda go do Twojej listy. ZITADEL domyślnie używa kluczy RSA2048 z haszowaniem SHA256.",
+ "KEY_TYPE": "Typ klucza",
+ "BITS": "Bity",
+ "HASHER": "Haszowanie",
+ "CURVE": "Krzywa"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Poprzednie Klucze Internetowe",
+ "DESCRIPTION": "To są Twoje poprzednie klucze internetowe, które nie są już aktywne.",
+ "DEACTIVATED_ON": "Dezaktywowany dnia"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "Teksty wiadomości",
"DESCRIPTION": "Dostosuj teksty swoich e-maili lub wiadomości SMS z powiadomieniami. Jeśli chcesz wyłączyć niektóre języki, ogranicz je w ustawieniach językowych swoich instancji.",
@@ -501,6 +527,114 @@
"DOWNLOAD": "Pobierz",
"APPLY": "Stosować"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Akcje",
+ "DESCRIPTION": "Akcje umożliwiają uruchamianie niestandardowego kodu w odpowiedzi na żądania API, zdarzenia lub określone funkcje. Użyj ich, aby rozszerzyć Zitadel, zautomatyzować przepływy pracy i zintegrować się z innymi systemami.",
+ "TYPES": {
+ "request": "Żądanie",
+ "response": "Odpowiedź",
+ "events": "Zdarzenia",
+ "function": "Funkcja"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Utwórz akcję",
+ "UPDATE_TITLE": "Aktualizuj akcję",
+ "TYPE": {
+ "DESCRIPTION": "Wybierz, kiedy chcesz uruchomić tę akcję",
+ "REQUEST": {
+ "TITLE": "Żądanie",
+ "DESCRIPTION": "Żądania występujące w Zitadel. Może to być coś takiego jak wywołanie żądania logowania."
+ },
+ "RESPONSE": {
+ "TITLE": "Odpowiedź",
+ "DESCRIPTION": "Odpowiedź na żądanie w Zitadel. Pomyśl o odpowiedzi, którą otrzymujesz po pobraniu użytkownika."
+ },
+ "EVENTS": {
+ "TITLE": "Zdarzenia",
+ "DESCRIPTION": "Zdarzenia, które mają miejsce w Zitadel. Mogą to być dowolne zdarzenia, takie jak utworzenie konta użytkownika, udane logowanie itp."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Funkcje",
+ "DESCRIPTION": "Funkcje, które można wywołać w Zitadel. Mogą to być dowolne funkcje, od wysłania wiadomości e-mail po utworzenie użytkownika."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Wybierz, czy ta akcja ma zastosowanie do wszystkich żądań, określonej usługi (np. zarządzanie użytkownikami) czy pojedynczego żądania (np. utwórz użytkownika).",
+ "ALL": {
+ "TITLE": "Wszystkie",
+ "DESCRIPTION": "Wybierz tę opcję, jeśli chcesz uruchomić akcję dla każdego żądania"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Wybierz usługę",
+ "DESCRIPTION": "Wybierz usługę Zitadel dla swojej akcji."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Wybierz metodę",
+ "DESCRIPTION": "Jeśli chcesz uruchomić tylko dla określonego żądania, wybierz je tutaj",
+ "NOTE": "Jeśli nie wybierzesz metody, akcja zostanie uruchomiona dla każdego żądania w wybranej usłudze."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Nazwa funkcji",
+ "DESCRIPTION": "Wybierz funkcję, którą chcesz uruchomić"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Ustaw grupę",
+ "DESCRIPTION": "Jeśli chcesz uruchomić tylko dla grupy zdarzeń, ustaw grupę tutaj"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Wybierz zdarzenie",
+ "DESCRIPTION": "Jeśli chcesz uruchomić tylko dla określonego zdarzenia, określ je tutaj"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "Możesz wybrać uruchomienie celu lub uruchomienie go na tych samych warunkach co inne cele.",
+ "TARGET": {
+ "DESCRIPTION": "Cel, który chcesz uruchomić dla tej akcji"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Warunki wykonania"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Warunek",
+ "TYPE": "Typ",
+ "TARGET": "Cel",
+ "CREATIONDATE": "Data utworzenia"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Cele",
+ "DESCRIPTION": "Celem jest miejsce docelowe kodu, który chcesz uruchomić z akcji. Utwórz cel tutaj i dodaj go do swoich akcji.",
+ "CREATE": {
+ "TITLE": "Utwórz swój cel",
+ "DESCRIPTION": "Utwórz własny cel poza Zitadel",
+ "NAME": "Nazwa",
+ "NAME_DESCRIPTION": "Nadaj swojemu celowi jasną, opisową nazwę, aby ułatwić jego późniejszą identyfikację",
+ "TYPE": "Typ",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "Wywołanie REST",
+ "restAsync": "REST Asynchroniczny"
+ },
+ "ENDPOINT": "Punkt końcowy",
+ "ENDPOINT_DESCRIPTION": "Wprowadź punkt końcowy, w którym hostowany jest Twój kod. Upewnij się, że jest dla nas dostępny!",
+ "TIMEOUT": "Limit czasu",
+ "TIMEOUT_DESCRIPTION": "Ustaw maksymalny czas, w jakim cel musi odpowiedzieć. Jeśli zajmie to więcej czasu, zatrzymamy żądanie.",
+ "INTERRUPT_ON_ERROR": "Przerwij w przypadku błędu",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Zatrzymaj wszystkie wykonania, gdy cele zwrócą błąd",
+ "INTERRUPT_ON_ERROR_WARNING": "Uwaga: „Przerwij w przypadku błędu” zatrzymuje operacje w przypadku błędu, co grozi zablokowaniem. Przetestuj przy wyłączonej opcji, aby uniknąć blokowania logowania/tworzenia.",
+ "AWAIT_RESPONSE": "Oczekuj na odpowiedź",
+ "AWAIT_RESPONSE_DESCRIPTION": "Przed wykonaniem jakichkolwiek innych czynności poczekamy na odpowiedź. Przydatne, jeśli zamierzasz użyć wielu celów dla jednej akcji"
+ },
+ "TABLE": {
+ "NAME": "Nazwa",
+ "ENDPOINT": "Punkt końcowy",
+ "CREATIONDATE": "Data utworzenia"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "Ma kontrolę nad całą instancją, włącznie z wszystkimi organizacjami",
"IAM_OWNER_VIEWER": "Ma uprawnienie do przeglądania całej instancji, włącznie z wszystkimi organizacjami",
@@ -1355,6 +1489,7 @@
"BRANDING": "Marka",
"PRIVACYPOLICY": "Polityka prywatności",
"OIDC": "Czas trwania tokenów OIDC i wygaśnięcie",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Wygląd sekretów",
"SECURITY": "Ustawienia bezpieczeństwa",
"EVENTS": "Zdarzenia",
@@ -1514,7 +1649,10 @@
},
"RESET": "Ustaw wszystko na dziedziczone",
"CONSOLEUSEV2USERAPI": "Użyj API V2 w konsoli do tworzenia użytkowników",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "Gdy ta flaga jest włączona, konsola używa API V2 User do tworzenia nowych użytkowników. W przypadku API V2 nowo utworzeni użytkownicy rozpoczynają bez stanu początkowego."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "Gdy ta flaga jest włączona, konsola używa API V2 User do tworzenia nowych użytkowników. W przypadku API V2 nowo utworzeni użytkownicy rozpoczynają bez stanu początkowego.",
+ "LOGINV2": "Logowanie V2",
+ "LOGINV2_DESCRIPTION": "Włączenie tej opcji aktywuje nowy interfejs logowania oparty na TypeScript z ulepszonym bezpieczeństwem, wydajnością i możliwością dostosowania.",
+ "LOGINV2_BASEURI": "Podstawowy URI"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/pt.json b/console/src/assets/i18n/pt.json
index 427ce218e8..a8ab833724 100644
--- a/console/src/assets/i18n/pt.json
+++ b/console/src/assets/i18n/pt.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "A vida útil do token de atualização inativo é o tempo máximo que um token de atualização pode ficar sem uso."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Gerencie suas Chaves Web OIDC para assinar e validar tokens com segurança em sua instância do ZITADEL.",
+ "TABLE": {
+ "TITLE": "Chaves Web Ativas e Futuras",
+ "DESCRIPTION": "Suas chaves web ativas e futuras. Ativar uma nova chave desativará a atual.",
+ "NOTE": "Nota: O endpoint JWKs OIDC retorna uma resposta que pode ser armazenada em cache (padrão: 5 min). Evite ativar uma chave muito cedo, pois ela pode ainda não estar disponível no cache e para os clientes.",
+ "ACTIVATE": "Ativar próxima Chave Web",
+ "ACTIVE": "Atualmente ativa",
+ "NEXT": "Próxima na fila",
+ "FUTURE": "Futuro",
+ "WARNING": "A chave da Web tem menos de 5 minutos"
+ },
+ "CREATE": {
+ "TITLE": "Criar nova Chave Web",
+ "DESCRIPTION": "Criar uma nova chave web a adicionará à sua lista. O ZITADEL usa, por padrão, chaves RSA2048 com um algoritmo de hash SHA256.",
+ "KEY_TYPE": "Tipo de Chave",
+ "BITS": "Bits",
+ "HASHER": "Algoritmo de Hash",
+ "CURVE": "Curva"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Chaves Web Anteriores",
+ "DESCRIPTION": "Estas são suas chaves web anteriores que não estão mais ativas.",
+ "DEACTIVATED_ON": "Desativada em"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "Textos de Mensagens",
"DESCRIPTION": "Personalize os textos do seu e-mail de notificação ou mensagens SMS. Se desejar desativar alguns idiomas, restrinja-os nas configurações de idioma da sua instância.",
@@ -502,6 +528,114 @@
"DOWNLOAD": "Baixar",
"APPLY": "Aplicar"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Ações",
+ "DESCRIPTION": "As ações permitem que você execute código personalizado em resposta a solicitações de API, eventos ou funções específicas. Use-as para estender o Zitadel, automatizar fluxos de trabalho e integrar-se a outros sistemas.",
+ "TYPES": {
+ "request": "Solicitação",
+ "response": "Resposta",
+ "events": "Eventos",
+ "function": "Função"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Criar uma Ação",
+ "UPDATE_TITLE": "Atualizar uma Ação",
+ "TYPE": {
+ "DESCRIPTION": "Selecione quando você deseja que esta Ação seja executada",
+ "REQUEST": {
+ "TITLE": "Solicitação",
+ "DESCRIPTION": "Solicitações que ocorrem dentro do Zitadel. Isso pode ser algo como uma chamada de solicitação de login."
+ },
+ "RESPONSE": {
+ "TITLE": "Resposta",
+ "DESCRIPTION": "Uma resposta de uma solicitação dentro do Zitadel. Pense na resposta que você recebe ao buscar um usuário."
+ },
+ "EVENTS": {
+ "TITLE": "Eventos",
+ "DESCRIPTION": "Eventos que acontecem dentro do Zitadel. Isso pode ser qualquer coisa, como um usuário criando uma conta, um login bem-sucedido, etc."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Funções",
+ "DESCRIPTION": "Funções que você pode chamar dentro do Zitadel. Isso pode ser qualquer coisa, desde enviar um e-mail até criar um usuário."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Escolha se esta ação se aplica a todas as solicitações, um serviço específico (por exemplo, gerenciamento de usuários) ou uma única solicitação (por exemplo, criar usuário).",
+ "ALL": {
+ "TITLE": "Todas",
+ "DESCRIPTION": "Selecione isso se você quiser executar sua ação em cada solicitação"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Selecionar Serviço",
+ "DESCRIPTION": "Escolha um Serviço Zitadel para sua ação."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Selecionar Método",
+ "DESCRIPTION": "Se você quiser executar apenas em uma solicitação específica, selecione-a aqui",
+ "NOTE": "Se você não selecionar um método, sua ação será executada em todas as solicitações em seu serviço selecionado."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Nome da Função",
+ "DESCRIPTION": "Escolha a função que você deseja executar"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Definir Grupo",
+ "DESCRIPTION": "Se você quiser executar apenas em um grupo de eventos, defina o grupo aqui"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Selecionar Evento",
+ "DESCRIPTION": "Se você quiser executar apenas em um evento específico, especifique-o aqui"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "Você pode escolher executar um destino ou executá-lo nas mesmas condições que outros destinos.",
+ "TARGET": {
+ "DESCRIPTION": "O destino que você deseja executar para esta ação"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Condições de Execução"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Condição",
+ "TYPE": "Tipo",
+ "TARGET": "Destino",
+ "CREATIONDATE": "Data de Criação"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Destinos",
+ "DESCRIPTION": "Um destino é o destino do código que você deseja executar a partir de uma ação. Crie um destino aqui e adicione-o às suas ações.",
+ "CREATE": {
+ "TITLE": "Criar seu Destino",
+ "DESCRIPTION": "Crie seu próprio destino fora do Zitadel",
+ "NAME": "Nome",
+ "NAME_DESCRIPTION": "Dê ao seu destino um nome claro e descritivo para torná-lo fácil de identificar mais tarde",
+ "TYPE": "Tipo",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "Chamada REST",
+ "restAsync": "REST Assíncrono"
+ },
+ "ENDPOINT": "Ponto de Extremidade",
+ "ENDPOINT_DESCRIPTION": "Insira o ponto de extremidade onde seu código está hospedado. Certifique-se de que ele esteja acessível para nós!",
+ "TIMEOUT": "Tempo Limite",
+ "TIMEOUT_DESCRIPTION": "Defina o tempo máximo que seu destino tem para responder. Se demorar mais, interromperemos a solicitação.",
+ "INTERRUPT_ON_ERROR": "Interromper em Caso de Erro",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Pare todas as execuções quando os destinos retornarem um erro",
+ "INTERRUPT_ON_ERROR_WARNING": "Atenção: “Interromper em caso de erro” interrompe as operações em caso de falha, com risco de bloqueio. Teste com esta opção desativada para evitar bloquear o login/criação.",
+ "AWAIT_RESPONSE": "Aguardar Resposta",
+ "AWAIT_RESPONSE_DESCRIPTION": "Aguardaremos uma resposta antes de fazermos qualquer outra coisa. Útil se você pretende usar vários destinos para uma única ação"
+ },
+ "TABLE": {
+ "NAME": "Nome",
+ "ENDPOINT": "Ponto de Extremidade",
+ "CREATIONDATE": "Data de Criação"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "Tem controle sobre toda a instância, incluindo todas as organizações",
"IAM_OWNER_VIEWER": "Tem permissão para revisar toda a instância, incluindo todas as organizações",
@@ -1357,6 +1491,7 @@
"BRANDING": "Marca",
"PRIVACYPOLICY": "Política de Privacidade",
"OIDC": "Tempo de Vida e Expiração do Token OIDC",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Aparência de Segredo",
"SECURITY": "Configurações de Segurança",
"EVENTS": "Eventos",
@@ -1516,7 +1651,10 @@
},
"RESET": "Definir tudo para herdar",
"CONSOLEUSEV2USERAPI": "Use a API V2 no console para criação de usuários",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "Quando esta opção está ativada, o console utiliza a API V2 de Usuários para criar novos usuários. Com a API V2, os novos usuários criados começam sem um estado inicial."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "Quando esta opção está ativada, o console utiliza a API V2 de Usuários para criar novos usuários. Com a API V2, os novos usuários criados começam sem um estado inicial.",
+ "LOGINV2": "Login V2",
+ "LOGINV2_DESCRIPTION": "Ativar esta opção ativa a nova interface de login baseada em TypeScript, com melhorias na segurança, desempenho e personalização.",
+ "LOGINV2_BASEURI": "URI base"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/ro.json b/console/src/assets/i18n/ro.json
index 7e8fdda7dd..987368d84f 100644
--- a/console/src/assets/i18n/ro.json
+++ b/console/src/assets/i18n/ro.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "Durata de viață inactivă a tokenului de reîmprospătare este timpul maxim în care un token de reîmprospătare poate fi neutilizat."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Gestionează-ți cheile web OIDC pentru a semna și valida în siguranță tokenurile pentru instanța ta ZITADEL.",
+ "TABLE": {
+ "TITLE": "Chei Web Active și Viitoare",
+ "DESCRIPTION": "Cheile tale web active și viitoare. Activarea unei noi chei va dezactiva cheia curentă.",
+ "NOTE": "Notă: Endpoint-ul JWKs OIDC returnează un răspuns care poate fi stocat în cache (implicit 5 min). Evită activarea unei chei prea devreme, deoarece este posibil să nu fie încă disponibilă în cache și pentru clienți.",
+ "ACTIVATE": "Activează următoarea Cheie Web",
+ "ACTIVE": "În prezent activă",
+ "NEXT": "Următoarea în coadă",
+ "FUTURE": "Viitoare",
+ "WARNING": "Cheia web are mai puțin de 5 minute"
+ },
+ "CREATE": {
+ "TITLE": "Creează o nouă Cheie Web",
+ "DESCRIPTION": "Crearea unei noi chei web o va adăuga pe lista ta. ZITADEL folosește implicit chei RSA2048 cu un algoritm de hash SHA256.",
+ "KEY_TYPE": "Tip de Cheie",
+ "BITS": "Biti",
+ "HASHER": "Algoritm de Hash",
+ "CURVE": "Curbă"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Chei Web Anterioare",
+ "DESCRIPTION": "Acestea sunt cheile tale web anterioare care nu mai sunt active.",
+ "DEACTIVATED_ON": "Dezactivată pe"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "Texte de mesaje",
"DESCRIPTION": "Personalizați textele mesajelor de e-mail sau SMS de notificare. Dacă doriți să dezactivați unele dintre limbi, restricționați-le în setările de limbă ale instanțelor dvs.",
@@ -502,6 +528,114 @@
"DOWNLOAD": "Descărcați",
"APPLY": "Aplicați"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Acțiuni",
+ "DESCRIPTION": "Acțiunile vă permit să rulați cod personalizat ca răspuns la cereri API, evenimente sau funcții specifice. Folosiți-le pentru a extinde Zitadel, a automatiza fluxurile de lucru și a vă integra cu alte sisteme.",
+ "TYPES": {
+ "request": "Cerere",
+ "response": "Răspuns",
+ "events": "Evenimente",
+ "function": "Funcție"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Creează o Acțiune",
+ "UPDATE_TITLE": "Actualizează o Acțiune",
+ "TYPE": {
+ "DESCRIPTION": "Selectați când doriți să rulați această Acțiune",
+ "REQUEST": {
+ "TITLE": "Cerere",
+ "DESCRIPTION": "Cereri care apar în Zitadel. Acesta ar putea fi ceva de genul unui apel de cerere de autentificare."
+ },
+ "RESPONSE": {
+ "TITLE": "Răspuns",
+ "DESCRIPTION": "Un răspuns la o cerere în Zitadel. Gândiți-vă la răspunsul pe care îl primiți la preluarea unui utilizator."
+ },
+ "EVENTS": {
+ "TITLE": "Evenimente",
+ "DESCRIPTION": "Evenimente care se întâmplă în Zitadel. Acesta ar putea fi orice, cum ar fi un utilizator care își creează un cont, o autentificare reușită etc."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Funcții",
+ "DESCRIPTION": "Funcții pe care le puteți apela în Zitadel. Acesta ar putea fi orice, de la trimiterea unui e-mail la crearea unui utilizator."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Alegeți dacă această acțiune se aplică tuturor cererilor, unui serviciu specific (de exemplu, gestionarea utilizatorilor) sau unei singure cereri (de exemplu, crearea unui utilizator).",
+ "ALL": {
+ "TITLE": "Toate",
+ "DESCRIPTION": "Selectați aceasta dacă doriți să rulați acțiunea la fiecare cerere"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Selectați Serviciul",
+ "DESCRIPTION": "Alegeți un Serviciu Zitadel pentru acțiunea dvs."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Selectați Metoda",
+ "DESCRIPTION": "Dacă doriți să rulați numai la o cerere specifică, selectați-o aici",
+ "NOTE": "Dacă nu selectați o metodă, acțiunea dvs. va rula la fiecare cerere din serviciul selectat."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Numele Funcției",
+ "DESCRIPTION": "Alegeți funcția pe care doriți să o rulați"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Setează Grupul",
+ "DESCRIPTION": "Dacă doriți să rulați numai pe un grup de evenimente, setați grupul aici"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Selectați Evenimentul",
+ "DESCRIPTION": "Dacă doriți să rulați numai la un eveniment specific, specificați-l aici"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "Puteți alege să rulați o țintă sau să o rulați în aceleași condiții ca și alte ținte.",
+ "TARGET": {
+ "DESCRIPTION": "Ținta pe care doriți să o rulați pentru această acțiune"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Condiții de Execuție"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Condiție",
+ "TYPE": "Tip",
+ "TARGET": "Țintă",
+ "CREATIONDATE": "Data Creării"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Ținte",
+ "DESCRIPTION": "O țintă este destinația codului pe care doriți să-l rulați dintr-o acțiune. Creați o țintă aici și adăugați-o la acțiunile dvs.",
+ "CREATE": {
+ "TITLE": "Creează-ți Ținta",
+ "DESCRIPTION": "Creați-vă propria țintă în afara Zitadel",
+ "NAME": "Nume",
+ "NAME_DESCRIPTION": "Dați țintei dvs. un nume clar, descriptiv, pentru a o identifica ușor mai târziu",
+ "TYPE": "Tip",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "Apel REST",
+ "restAsync": "REST Asincron"
+ },
+ "ENDPOINT": "Punct Final",
+ "ENDPOINT_DESCRIPTION": "Introduceți punctul final unde este găzduit codul dvs. Asigurați-vă că este accesibil pentru noi!",
+ "TIMEOUT": "Timeout",
+ "TIMEOUT_DESCRIPTION": "Setați timpul maxim pe care ținta dvs. îl are pentru a răspunde. Dacă durează mai mult, vom opri cererea.",
+ "INTERRUPT_ON_ERROR": "Întrerupe la Eroare",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Opriți toate execuțiile când țintele returnează o eroare",
+ "INTERRUPT_ON_ERROR_WARNING": "Atenție: „Întrerupe la eroare” oprește operațiunile în caz de eșec, riscând blocarea accesului. Testați cu această opțiune dezactivată pentru a evita blocarea autentificării/creării.",
+ "AWAIT_RESPONSE": "Așteaptă Răspuns",
+ "AWAIT_RESPONSE_DESCRIPTION": "Vom aștepta un răspuns înainte de a face altceva. Util dacă intenționați să utilizați mai multe ținte pentru o singură acțiune"
+ },
+ "TABLE": {
+ "NAME": "Nume",
+ "ENDPOINT": "Punct Final",
+ "CREATIONDATE": "Data Creării"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "Are control asupra întregii instanțe, inclusiv asupra tuturor organizațiilor",
"IAM_OWNER_VIEWER": "Are permisiunea de a revizui întreaga instanță, inclusiv toate organizațiile",
@@ -1354,6 +1488,7 @@
"BRANDING": "Branding",
"PRIVACYPOLICY": "Linkuri externe",
"OIDC": "Durata de viață și expirarea tokenului OIDC",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Generator de secrete",
"SECURITY": "Setări de securitate",
"EVENTS": "Evenimente",
@@ -1513,7 +1648,10 @@
},
"RESET": "Setați totul pentru a moșteni",
"CONSOLEUSEV2USERAPI": "Utilizați API-ul V2 în Consola pentru crearea utilizatorului",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "Când acest indicator este activat, consola utilizează API-ul de utilizator V2 pentru a crea utilizatori noi. Cu API-ul V2, utilizatorii nou creați încep fără o stare inițială."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "Când acest indicator este activat, consola utilizează API-ul de utilizator V2 pentru a crea utilizatori noi. Cu API-ul V2, utilizatorii nou creați încep fără o stare inițială.",
+ "LOGINV2": "Autentificare V2",
+ "LOGINV2_DESCRIPTION": "Activarea acestei opțiuni pornește noua interfață de autentificare bazată pe TypeScript, cu securitate, performanță și personalizare îmbunătățite.",
+ "LOGINV2_BASEURI": "URI de bază"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/ru.json b/console/src/assets/i18n/ru.json
index f3ebf21e7b..1289fb708f 100644
--- a/console/src/assets/i18n/ru.json
+++ b/console/src/assets/i18n/ru.json
@@ -185,6 +185,33 @@
"DESCRIPTION": "Срок действия неактивного токена обновления - это максимальное время, в течение которого токен обновления может оставаться неиспользованным."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Управляйте своими OIDC веб-ключами для безопасной подписи и валидации токенов в вашем экземпляре ZITADEL.",
+ "TABLE": {
+ "TITLE": "Активные и будущие веб-ключи",
+ "DESCRIPTION": "Ваши активные и будущие веб-ключи. Активация нового ключа приведёт к деактивации текущего.",
+ "NOTE": "Примечание: Конечная точка JWKs OIDC возвращает кэшируемый ответ (по умолчанию 5 минут). Избегайте слишком ранней активации ключа, так как он может ещё не быть доступен в кэше и у клиентов.",
+ "ACTIVATE": "Активировать следующий веб-ключ",
+ "ACTIVE": "В настоящее время активен",
+ "NEXT": "Следующий в очереди",
+ "FUTURE": "Будущий",
+ "WARNING": "Веб-ключу менее 5 минут"
+ },
+ "CREATE": {
+ "TITLE": "Создать новый веб-ключ",
+ "DESCRIPTION": "Создание нового веб-ключа добавит его в ваш список. ZITADEL по умолчанию использует ключи RSA2048 с хешированием SHA256.",
+ "KEY_TYPE": "Тип ключа",
+ "BITS": "Биты",
+ "HASHER": "Алгоритм хеширования",
+ "CURVE": "Кривая"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Предыдущие веб-ключи",
+ "DESCRIPTION": "Это ваши предыдущие веб-ключи, которые больше не активны.",
+ "DEACTIVATED_ON": "Деактивирован"
+ }
+ },
+
"MESSAGE_TEXTS": {
"TITLE": "Тексты сообщений",
"DESCRIPTION": "Настройте тексты ваших уведомлений по электронной почте или SMS. Если вы хотите отключить некоторые языки, ограничьте их в настройках языка ваших экземпляров.",
@@ -501,6 +528,114 @@
"DOWNLOAD": "Скачать",
"APPLY": "Применять"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Действия",
+ "DESCRIPTION": "Действия позволяют запускать пользовательский код в ответ на API-запросы, события или определенные функции. Используйте их для расширения Zitadel, автоматизации рабочих процессов и интеграции с другими системами.",
+ "TYPES": {
+ "request": "Запрос",
+ "response": "Ответ",
+ "events": "События",
+ "function": "Функция"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Создать действие",
+ "UPDATE_TITLE": "Обновить действие",
+ "TYPE": {
+ "DESCRIPTION": "Выберите, когда вы хотите запустить это действие",
+ "REQUEST": {
+ "TITLE": "Запрос",
+ "DESCRIPTION": "Запросы, которые происходят внутри Zitadel. Это может быть что-то вроде вызова запроса на вход."
+ },
+ "RESPONSE": {
+ "TITLE": "Ответ",
+ "DESCRIPTION": "Ответ на запрос внутри Zitadel. Подумайте об ответе, который вы получаете при получении пользователя."
+ },
+ "EVENTS": {
+ "TITLE": "События",
+ "DESCRIPTION": "События, которые происходят внутри Zitadel. Это может быть что угодно, например, создание пользователем учетной записи, успешный вход и т. д."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Функции",
+ "DESCRIPTION": "Функции, которые вы можете вызвать внутри Zitadel. Это может быть что угодно, от отправки электронной почты до создания пользователя."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Выберите, применяется ли это действие ко всем запросам, к определенной службе (например, управление пользователями) или к одному запросу (например, создать пользователя).",
+ "ALL": {
+ "TITLE": "Все",
+ "DESCRIPTION": "Выберите это, если вы хотите запустить свое действие при каждом запросе"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Выбрать службу",
+ "DESCRIPTION": "Выберите службу Zitadel для вашего действия."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Выбрать метод",
+ "DESCRIPTION": "Если вы хотите запустить только для определенного запроса, выберите его здесь",
+ "NOTE": "Если вы не выберете метод, ваше действие будет запускаться при каждом запросе в выбранной вами службе."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Имя функции",
+ "DESCRIPTION": "Выберите функцию, которую вы хотите запустить"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Установить группу",
+ "DESCRIPTION": "Если вы хотите запустить только для группы событий, установите группу здесь"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Выбрать событие",
+ "DESCRIPTION": "Если вы хотите запустить только для определенного события, укажите его здесь"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "Вы можете выбрать запуск цели или запустить ее в тех же условиях, что и другие цели.",
+ "TARGET": {
+ "DESCRIPTION": "Цель, которую вы хотите запустить для этого действия"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Условия выполнения"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Условие",
+ "TYPE": "Тип",
+ "TARGET": "Цель",
+ "CREATIONDATE": "Дата создания"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Цели",
+ "DESCRIPTION": "Цель — это место назначения кода, который вы хотите запустить из действия. Создайте цель здесь и добавьте ее к своим действиям.",
+ "CREATE": {
+ "TITLE": "Создать свою цель",
+ "DESCRIPTION": "Создайте свою собственную цель за пределами Zitadel",
+ "NAME": "Имя",
+ "NAME_DESCRIPTION": "Дайте своей цели четкое, описательное имя, чтобы ее было легко идентифицировать позже",
+ "TYPE": "Тип",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "REST Вызов",
+ "restAsync": "REST Асинхронный"
+ },
+ "ENDPOINT": "Конечная точка",
+ "ENDPOINT_DESCRIPTION": "Введите конечную точку, где размещен ваш код. Убедитесь, что он доступен для нас!",
+ "TIMEOUT": "Тайм-аут",
+ "TIMEOUT_DESCRIPTION": "Установите максимальное время, в течение которого ваша цель должна ответить. Если это займет больше времени, мы остановим запрос.",
+ "INTERRUPT_ON_ERROR": "Прервать при ошибке",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Остановите все выполнения, когда цели вернут ошибку",
+ "INTERRUPT_ON_ERROR_WARNING": "Внимание: опция «Прервать при ошибке» останавливает выполнение при сбое, что может привести к блокировке. Протестируйте с отключённой опцией, чтобы избежать блокировки входа/создания.",
+ "AWAIT_RESPONSE": "Ожидать ответа",
+ "AWAIT_RESPONSE_DESCRIPTION": "Мы подождем ответа, прежде чем делать что-либо еще. Полезно, если вы планируете использовать несколько целей для одного действия"
+ },
+ "TABLE": {
+ "NAME": "Имя",
+ "ENDPOINT": "Конечная точка",
+ "CREATIONDATE": "Дата создания"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "Имеет контроль над всем экземпляром, включая все организации",
"IAM_OWNER_VIEWER": "Имеет разрешение на просмотр всего экземпляра, включая все организации",
@@ -1400,6 +1535,7 @@
"BRANDING": "Брендинг",
"PRIVACYPOLICY": "Политика конфиденциальности",
"OIDC": "Срок действия токена OIDC",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Отображение ключа",
"SECURITY": "Настройки безопасности",
"EVENTS": "События",
@@ -1567,7 +1703,10 @@
},
"RESET": "Установить все по умолчанию",
"CONSOLEUSEV2USERAPI": "Используйте V2 API в консоли для создания пользователей",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "Когда этот флаг включен, консоль использует V2 User API для создания новых пользователей. С API V2 новые пользователи создаются без начального состояния."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "Когда этот флаг включен, консоль использует V2 User API для создания новых пользователей. С API V2 новые пользователи создаются без начального состояния.",
+ "LOGINV2": "Вход V2",
+ "LOGINV2_DESCRIPTION": "Включение этой опции активирует новый интерфейс входа на основе TypeScript с улучшенной безопасностью, производительностью и возможностью настройки.",
+ "LOGINV2_BASEURI": "Базовый URI"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/sv.json b/console/src/assets/i18n/sv.json
index 03e6f89862..44ca2fc200 100644
--- a/console/src/assets/i18n/sv.json
+++ b/console/src/assets/i18n/sv.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "Den inaktiva förnyelsetokenens livslängd är den maximala tiden en förnyelsetoken kan vara oanvänd."
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "Hantera dina OIDC-webbnycklar för att säkert signera och validera tokens för din ZITADEL-instans.",
+ "TABLE": {
+ "TITLE": "Aktiva och framtida webbnycklar",
+ "DESCRIPTION": "Dina aktiva och kommande webbnycklar. Aktivering av en ny nyckel kommer att inaktivera den nuvarande.",
+ "NOTE": "Observera: JWKs OIDC-slutpunkten returnerar ett cachebart svar (standard 5 min). Undvik att aktivera en nyckel för tidigt, eftersom den kanske ännu inte är tillgänglig i cache och för klienter.",
+ "ACTIVATE": "Aktivera nästa webbnyckel",
+ "ACTIVE": "För närvarande aktiv",
+ "NEXT": "Nästa i kön",
+ "FUTURE": "Framtida",
+ "WARNING": "Webbnyckeln är mindre än 5 minuter gammal"
+ },
+ "CREATE": {
+ "TITLE": "Skapa ny webbnyckel",
+ "DESCRIPTION": "Att skapa en ny webbnyckel lägger till den i din lista. ZITADEL använder som standard RSA2048-nycklar med en SHA256-hasher.",
+ "KEY_TYPE": "Nyckeltyp",
+ "BITS": "Bitar",
+ "HASHER": "Hasher",
+ "CURVE": "Kurva"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "Tidigare webbnycklar",
+ "DESCRIPTION": "Detta är dina tidigare webbnycklar som inte längre är aktiva.",
+ "DEACTIVATED_ON": "Inaktiverad den"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "Meddelandetexter",
"DESCRIPTION": "Anpassa texterna i dina notifikationsmail eller SMS-meddelanden. Om du vill inaktivera några av språken, begränsa dem i dina instansers språkinställningar.",
@@ -502,6 +528,114 @@
"DOWNLOAD": "Ladda ner",
"APPLY": "Tillämpa"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "Åtgärder",
+ "DESCRIPTION": "Åtgärder låter dig köra anpassad kod som svar på API-förfrågningar, händelser eller specifika funktioner. Använd dem för att utöka Zitadel, automatisera arbetsflöden och integrera med andra system.",
+ "TYPES": {
+ "request": "Förfrågan",
+ "response": "Svar",
+ "events": "Händelser",
+ "function": "Funktion"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "Skapa en åtgärd",
+ "UPDATE_TITLE": "Uppdatera en åtgärd",
+ "TYPE": {
+ "DESCRIPTION": "Välj när du vill att denna åtgärd ska köras",
+ "REQUEST": {
+ "TITLE": "Förfrågan",
+ "DESCRIPTION": "Förfrågningar som sker inom Zitadel. Detta kan vara något som ett inloggningsförfrågningsanrop."
+ },
+ "RESPONSE": {
+ "TITLE": "Svar",
+ "DESCRIPTION": "Ett svar från en förfrågan inom Zitadel. Tänk på svaret du får tillbaka från att hämta en användare."
+ },
+ "EVENTS": {
+ "TITLE": "Händelser",
+ "DESCRIPTION": "Händelser som händer inom Zitadel. Detta kan vara vad som helst som en användare som skapar ett konto, en lyckad inloggning etc."
+ },
+ "FUNCTIONS": {
+ "TITLE": "Funktioner",
+ "DESCRIPTION": "Funktioner som du kan anropa inom Zitadel. Detta kan vara allt från att skicka ett e-postmeddelande till att skapa en användare."
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "Välj om denna åtgärd gäller för alla förfrågningar, en specifik tjänst (t.ex. användarhantering) eller en enskild förfrågan (t.ex. skapa användare).",
+ "ALL": {
+ "TITLE": "Alla",
+ "DESCRIPTION": "Välj detta om du vill köra din åtgärd på varje förfrågan"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "Välj tjänst",
+ "DESCRIPTION": "Välj en Zitadel-tjänst för din åtgärd."
+ },
+ "SELECT_METHOD": {
+ "TITLE": "Välj metod",
+ "DESCRIPTION": "Om du bara vill köra på en specifik förfrågan, välj den här",
+ "NOTE": "Om du inte väljer en metod körs din åtgärd på varje förfrågan i din valda tjänst."
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "Funktionsnamn",
+ "DESCRIPTION": "Välj den funktion du vill köra"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "Ange grupp",
+ "DESCRIPTION": "Om du bara vill köra på en grupp händelser, ange gruppen här"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "Välj händelse",
+ "DESCRIPTION": "Om du bara vill köra på en specifik händelse, ange den här"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "Du kan välja att köra ett mål eller att köra det under samma villkor som andra mål.",
+ "TARGET": {
+ "DESCRIPTION": "Målet du vill köra för denna åtgärd"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "Körningsvillkor"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "Villkor",
+ "TYPE": "Typ",
+ "TARGET": "Mål",
+ "CREATIONDATE": "Skapat datum"
+ }
+ },
+ "TARGET": {
+ "TITLE": "Mål",
+ "DESCRIPTION": "Ett mål är destinationen för koden du vill köra från en åtgärd. Skapa ett mål här och lägg till det i dina åtgärder.",
+ "CREATE": {
+ "TITLE": "Skapa ditt mål",
+ "DESCRIPTION": "Skapa ditt eget mål utanför Zitadel",
+ "NAME": "Namn",
+ "NAME_DESCRIPTION": "Ge ditt mål ett tydligt, beskrivande namn för att göra det enkelt att identifiera senare",
+ "TYPE": "Typ",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "REST Anrop",
+ "restAsync": "REST Asynkron"
+ },
+ "ENDPOINT": "Slutpunkt",
+ "ENDPOINT_DESCRIPTION": "Ange slutpunkten där din kod finns. Se till att den är tillgänglig för oss!",
+ "TIMEOUT": "Tidsgräns",
+ "TIMEOUT_DESCRIPTION": "Ange den maximala tid ditt mål har att svara. Om det tar längre tid stoppar vi förfrågan.",
+ "INTERRUPT_ON_ERROR": "Avbryt vid fel",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "Stoppa alla körningar när målen returnerar ett fel",
+ "INTERRUPT_ON_ERROR_WARNING": "Varning: ”Avbryt vid fel” stoppar åtgärder vid fel och kan leda till att du blir utelåst. Testa med funktionen avstängd för att undvika att blockera inloggning/skapa.",
+ "AWAIT_RESPONSE": "Vänta på svar",
+ "AWAIT_RESPONSE_DESCRIPTION": "Vi väntar på ett svar innan vi gör något annat. Användbart om du avser att använda flera mål för en enda åtgärd"
+ },
+ "TABLE": {
+ "NAME": "Namn",
+ "ENDPOINT": "Slutpunkt",
+ "CREATIONDATE": "Skapat datum"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "Har kontroll över hela instansen, inklusive alla organisationer",
"IAM_OWNER_VIEWER": "Har behörighet att granska hela instansen, inklusive alla organisationer",
@@ -1360,6 +1494,7 @@
"BRANDING": "Varumärke",
"PRIVACYPOLICY": "Externa länkar",
"OIDC": "OIDC-token livstid och utgång",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "Hemlighetsgenerator",
"SECURITY": "Säkerhetsinställningar",
"EVENTS": "Händelser",
@@ -1519,7 +1654,10 @@
},
"RESET": "Återställ allt till arv",
"CONSOLEUSEV2USERAPI": "Använd V2 API i konsolen för att skapa användare",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "När denna flagga är aktiverad använder konsolen V2 User API för att skapa nya användare. Med V2 API startar nyligen skapade användare utan ett initialt tillstånd."
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "När denna flagga är aktiverad använder konsolen V2 User API för att skapa nya användare. Med V2 API startar nyligen skapade användare utan ett initialt tillstånd.",
+ "LOGINV2": "Inloggning V2",
+ "LOGINV2_DESCRIPTION": "Att aktivera detta startar det nya inloggningsgränssnittet baserat på TypeScript med förbättrad säkerhet, prestanda och anpassning.",
+ "LOGINV2_BASEURI": "Bas-URI"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/assets/i18n/zh.json b/console/src/assets/i18n/zh.json
index 4346bb2175..5df3b414ab 100644
--- a/console/src/assets/i18n/zh.json
+++ b/console/src/assets/i18n/zh.json
@@ -185,6 +185,32 @@
"DESCRIPTION": "空闲刷新令牌的生命周期是刷新令牌可以未使用的最长时间。"
}
},
+ "WEB_KEYS": {
+ "DESCRIPTION": "管理您的 OIDC Web 密钥,以安全地签署和验证您的 ZITADEL 实例的令牌。",
+ "TABLE": {
+ "TITLE": "活动和未来的 Web 密钥",
+ "DESCRIPTION": "您的当前活动和即将启用的 Web 密钥。激活新密钥将会停用当前密钥。",
+ "NOTE": "注意:JWKs OIDC 端点返回可缓存的响应(默认 5 分钟)。请避免过早激活密钥,否则它可能尚未在缓存或客户端中可用。",
+ "ACTIVATE": "激活下一个 Web 密钥",
+ "ACTIVE": "当前活动",
+ "NEXT": "队列中的下一个",
+ "FUTURE": "未来",
+ "WARNING": "Web密钥不到5分钟。"
+ },
+ "CREATE": {
+ "TITLE": "创建新的 Web 密钥",
+ "DESCRIPTION": "创建新的 Web 密钥会将其添加到您的列表。ZITADEL 默认使用 RSA2048 密钥和 SHA256 哈希算法。",
+ "KEY_TYPE": "密钥类型",
+ "BITS": "位数",
+ "HASHER": "哈希算法",
+ "CURVE": "曲线"
+ },
+ "PREVIOUS_TABLE": {
+ "TITLE": "先前的 Web 密钥",
+ "DESCRIPTION": "这些是您之前使用但不再活动的 Web 密钥。",
+ "DEACTIVATED_ON": "停用时间"
+ }
+ },
"MESSAGE_TEXTS": {
"TITLE": "消息文本",
"DESCRIPTION": "自定义您的通知电子邮件或短信消息的文本。如果您想禁用某些语言,请在您的实例语言设置中限制它们。",
@@ -502,6 +528,114 @@
"DOWNLOAD": "下载",
"APPLY": "申请"
},
+ "ACTIONSTWO": {
+ "EXECUTION": {
+ "TITLE": "操作",
+ "DESCRIPTION": "操作允许您运行自定义代码以响应 API 请求、事件或特定函数。使用它们来扩展 Zitadel、自动化工作流程并与其他系统集成。",
+ "TYPES": {
+ "request": "请求",
+ "response": "响应",
+ "events": "事件",
+ "function": "函数"
+ },
+ "DIALOG": {
+ "CREATE_TITLE": "创建操作",
+ "UPDATE_TITLE": "更新操作",
+ "TYPE": {
+ "DESCRIPTION": "选择您希望此操作运行的时间",
+ "REQUEST": {
+ "TITLE": "请求",
+ "DESCRIPTION": "Zitadel 中发生的请求。这可能是登录请求调用之类的操作。"
+ },
+ "RESPONSE": {
+ "TITLE": "响应",
+ "DESCRIPTION": "来自 Zitadel 中请求的响应。考虑一下从获取用户返回的响应。"
+ },
+ "EVENTS": {
+ "TITLE": "事件",
+ "DESCRIPTION": "Zitadel 中发生的事件。这可能是用户创建帐户、成功登录等任何操作。"
+ },
+ "FUNCTIONS": {
+ "TITLE": "函数",
+ "DESCRIPTION": "您可以在 Zitadel 中调用的函数。这可能是从发送电子邮件到创建用户的任何操作。"
+ }
+ },
+ "CONDITION": {
+ "REQ_RESP_DESCRIPTION": "选择此操作是适用于所有请求、特定服务(例如用户管理)还是单个请求(例如创建用户)。",
+ "ALL": {
+ "TITLE": "全部",
+ "DESCRIPTION": "如果您希望在每个请求上运行您的操作,请选择此项"
+ },
+ "SELECT_SERVICE": {
+ "TITLE": "选择服务",
+ "DESCRIPTION": "为您的操作选择一个 Zitadel 服务。"
+ },
+ "SELECT_METHOD": {
+ "TITLE": "选择方法",
+ "DESCRIPTION": "如果您只想在特定请求上执行,请在此处选择它",
+ "NOTE": "如果您不选择方法,您的操作将在您选择的服务中的每个请求上运行。"
+ },
+ "FUNCTIONNAME": {
+ "TITLE": "函数名称",
+ "DESCRIPTION": "选择您要执行的函数"
+ },
+ "SELECT_GROUP": {
+ "TITLE": "设置组",
+ "DESCRIPTION": "如果您只想在事件组上执行,请在此处设置组"
+ },
+ "SELECT_EVENT": {
+ "TITLE": "选择事件",
+ "DESCRIPTION": "如果您只想在特定事件上执行,请在此处指定它"
+ }
+ },
+ "TARGET": {
+ "DESCRIPTION": "您可以选择执行目标,或在与其他目标相同的条件下运行它。",
+ "TARGET": {
+ "DESCRIPTION": "您要为此操作执行的目标"
+ },
+ "CONDITIONS": {
+ "DESCRIPTION": "执行条件"
+ }
+ }
+ },
+ "TABLE": {
+ "CONDITION": "条件",
+ "TYPE": "类型",
+ "TARGET": "目标",
+ "CREATIONDATE": "创建日期"
+ }
+ },
+ "TARGET": {
+ "TITLE": "目标",
+ "DESCRIPTION": "目标是您要从操作中执行的代码的目标。在此处创建一个目标并将其添加到您的操作中。",
+ "CREATE": {
+ "TITLE": "创建您的目标",
+ "DESCRIPTION": "在 Zitadel 外部创建您自己的目标",
+ "NAME": "名称",
+ "NAME_DESCRIPTION": "为您的目标提供清晰、描述性的名称,以便稍后轻松识别",
+ "TYPE": "类型",
+ "TYPES": {
+ "restWebhook": "REST Webhook",
+ "restCall": "REST 调用",
+ "restAsync": "REST 异步"
+ },
+ "ENDPOINT": "端点",
+ "ENDPOINT_DESCRIPTION": "输入您的代码托管的端点。确保我们可以访问它!",
+ "TIMEOUT": "超时",
+ "TIMEOUT_DESCRIPTION": "设置您的目标必须响应的最大时间。如果花费的时间更长,我们将停止请求。",
+ "INTERRUPT_ON_ERROR": "错误时中断",
+ "INTERRUPT_ON_ERROR_DESCRIPTION": "当目标返回错误时,停止所有执行",
+ "INTERRUPT_ON_ERROR_WARNING": "注意:“出错时中断”会在失败时停止操作,存在被锁定的风险。请在禁用该选项的情况下进行测试,以避免阻止登录/创建。",
+ "AWAIT_RESPONSE": "等待响应",
+ "AWAIT_RESPONSE_DESCRIPTION": "我们将在执行任何其他操作之前等待响应。如果您打算为单个操作使用多个目标,这将非常有用"
+ },
+ "TABLE": {
+ "NAME": "名称",
+ "ENDPOINT": "端点",
+ "CREATIONDATE": "创建日期"
+ }
+ }
+ },
"MEMBERROLES": {
"IAM_OWNER": "控制整个实例,包括所有组织",
"IAM_OWNER_VIEWER": "有权审查整个实例,包括所有组织",
@@ -1356,6 +1490,7 @@
"BRANDING": "品牌标识",
"PRIVACYPOLICY": "隐私政策",
"OIDC": "OIDC 令牌有效期和过期时间",
+ "WEB_KEYS": "OIDC Web Keys",
"SECRETS": "验证码外观",
"SECURITY": "安全设置",
"EVENTS": "活动",
@@ -1515,7 +1650,10 @@
},
"RESET": "全部设置为继承",
"CONSOLEUSEV2USERAPI": "在控制台中使用V2 API创建用户。",
- "CONSOLEUSEV2USERAPI_DESCRIPTION": "启用此标志时,控制台使用V2用户API创建新用户。使用V2 API,新创建的用户将以无初始状态开始。"
+ "CONSOLEUSEV2USERAPI_DESCRIPTION": "启用此标志时,控制台使用V2用户API创建新用户。使用V2 API,新创建的用户将以无初始状态开始。",
+ "LOGINV2": "登录 V2",
+ "LOGINV2_DESCRIPTION": "启用此选项将激活基于 TypeScript 的新登录界面,具有更高的安全性、性能和可定制性。",
+ "LOGINV2_BASEURI": "基础 URI"
},
"DIALOG": {
"RESET": {
diff --git a/console/src/styles/table.scss b/console/src/styles/table.scss
index 933366607e..3b177e07e7 100644
--- a/console/src/styles/table.scss
+++ b/console/src/styles/table.scss
@@ -133,6 +133,11 @@
color: if($is-dark-theme, #ffc1c1, #620e0e);
background-color: if($is-dark-theme, map-get($background, state-inactive), #ffc1c1);
}
+
+ &.neutral {
+ background: if($is-dark-theme, #01489c78, #47a8ff82);
+ color: if($is-dark-theme, #47a8ff, #01489c);
+ }
}
.bg-state {
diff --git a/console/yarn.lock b/console/yarn.lock
index d91242c992..5dd602dfa8 100644
--- a/console/yarn.lock
+++ b/console/yarn.lock
@@ -3464,13 +3464,20 @@
"@zitadel/proto" "1.0.4"
jose "^5.3.0"
-"@zitadel/proto@1.0.4", "@zitadel/proto@^1.0.4":
+"@zitadel/proto@1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@zitadel/proto/-/proto-1.0.4.tgz#e2fe9895f2960643c3619191255aa2f4913ad873"
integrity sha512-s13ZMhuOTe0b+geV+JgJud+kpYdq7TgkuCe7RIY+q4Xs5KC0FHMKfvbAk/jpFbD+TSQHiwo/TBNZlGHdwUR9Ig==
dependencies:
"@bufbuild/protobuf" "^2.2.2"
+"@zitadel/proto@1.0.5-sha-4118a9d":
+ version "1.0.5-sha-4118a9d"
+ resolved "https://registry.yarnpkg.com/@zitadel/proto/-/proto-1.0.5-sha-4118a9d.tgz#e09025f31b2992b061d5416a0d1e12ef370118cc"
+ integrity sha512-7ZFwISL7TqdCkfEUx7/H6UJDqX8ZP2jqG1ulbELvEQ2smrK365Zs7AkJGeB/xbVdhQW9BOhWy2R+Jni7sfxd2w==
+ dependencies:
+ "@bufbuild/protobuf" "^2.2.2"
+
"@zkochan/js-yaml@0.0.6":
version "0.0.6"
resolved "https://registry.yarnpkg.com/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz#975f0b306e705e28b8068a07737fa46d3fc04826"
diff --git a/docs/docs/apis/actions/v3/testing-locally.md b/docs/docs/apis/actions/v2/testing-locally.md
similarity index 92%
rename from docs/docs/apis/actions/v3/testing-locally.md
rename to docs/docs/apis/actions/v2/testing-locally.md
index b5b3cb389f..9ded5a5db4 100644
--- a/docs/docs/apis/actions/v3/testing-locally.md
+++ b/docs/docs/apis/actions/v2/testing-locally.md
@@ -66,10 +66,10 @@ Where you can replace 'signingKey' with the key received in the next step 'Creat
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/zitadel-actions-create-target)
+[Create a target](/apis/resources/action_service_v2/action-service-create-target)
```shell
-curl -L -X POST 'https://$CUSTOM-DOMAIN/v3alpha/targets' \
+curl -L -X POST 'https://$CUSTOM-DOMAIN/v2beta/actions/targets' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ' \
@@ -89,10 +89,10 @@ 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.
-[Set an execution](/apis/resources/action_service_v3/zitadel-actions-set-execution)
+[Set an execution](/apis/resources/action_service_v2/action-service-set-execution)
```shell
-curl -L -X PUT 'https://$CUSTOM-DOMAIN/v3alpha/executions' \
+curl -L -X PUT 'https://$CUSTOM-DOMAIN/v2beta/actions/executions' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ' \
diff --git a/docs/docs/apis/actions/v3/usage.md b/docs/docs/apis/actions/v2/usage.md
similarity index 92%
rename from docs/docs/apis/actions/v3/usage.md
rename to docs/docs/apis/actions/v2/usage.md
index 2e89f3ce36..aab1a6dd7b 100644
--- a/docs/docs/apis/actions/v3/usage.md
+++ b/docs/docs/apis/actions/v2/usage.md
@@ -62,14 +62,14 @@ 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.
-The API documentation to create a target can be found [here](/apis/resources/action_service_v3/zitadel-actions-create-target)
+The API documentation to create a target can be found [here](/apis/resources/action_service_v2/action-service-create-target)
### Content Signing
To ensure the integrity of request content, each call includes a 'ZITADEL-Signature' in the headers. This header contains an HMAC value computed from the request content and a timestamp, which can be used to time out requests. The logic for this process is provided in 'pkg/actions/signing.go'. The goal is to verify that the HMAC value in the header matches the HMAC value computed by the Target, ensuring that the sent and received requests are identical.
-Each Target resource now contains also a Signing Key, which gets generated and returned when a Target is [created](/apis/resources/action_service_v3/zitadel-actions-create-target),
-and can also be newly generated when a Target is [patched](/apis/resources/action_service_v3/zitadel-actions-patch-target).
+Each Target resource now contains also a Signing Key, which gets generated and returned when a Target is [created](/apis/resources/action_service_v2/action-service-create-target),
+and can also be newly generated when a Target is [patched](/apis/resources/action_service_v2/action-service-patch-target).
## Execution
@@ -83,7 +83,7 @@ The condition can be defined for 4 types of processes:
- `Functions`, handling specific functionality in the logic of 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/zitadel-actions-set-execution)
+The API documentation to set an Execution can be found [here](/apis/resources/action_service_v2/action-service-set-execution)
### Condition Best Match
@@ -165,8 +165,8 @@ For Request and Response there are 3 levels the condition can be defined:
- `All`, handling any request or response under the ZITADEL API
The available conditions can be found under:
-- [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/zitadel-actions-list-execution-services), for example `zitadel.user.v2.UserService`
+- [All available Methods](/apis/resources/action_service_v2/action-service-list-execution-methods), for example `/zitadel.user.v2.UserService/AddHumanUser`
+- [All available Services](/apis/resources/action_service_v2/action-service-list-execution-services), for example `zitadel.user.v2.UserService`
### Condition for Functions
@@ -177,7 +177,7 @@ Replace the current Actions with the following flows:
- [Complement Token](/apis/actions/complement-token)
- [Customize SAML Response](/apis/actions/customize-samlresponse)
-The available conditions can be found under [all available Functions](/apis/resources/action_service_v3/zitadel-actions-list-execution-functions).
+The available conditions can be found under [all available Functions](/apis/resources/action_service_v2/action-service-list-execution-functions).
### Condition for Events
diff --git a/docs/docs/apis/benchmarks/_template.mdx b/docs/docs/apis/benchmarks/_template.mdx
index 4bbb9e0b74..f015d20768 100644
--- a/docs/docs/apis/benchmarks/_template.mdx
+++ b/docs/docs/apis/benchmarks/_template.mdx
@@ -48,7 +48,7 @@ TODO: describe the outcome of the test?
| ZITADEL Version | |
| ZITADEL Configuration | |
| ZITADEL feature flags | |
-| Database | type: crdb / psql version: |
+| Database | type: psql version: |
| Database location | |
| Database specification | vCPU: memory: Gb |
| ZITADEL metrics during test | |
diff --git a/docs/docs/apis/benchmarks/index.mdx b/docs/docs/apis/benchmarks/index.mdx
index e5d89dbae8..a0979f0081 100644
--- a/docs/docs/apis/benchmarks/index.mdx
+++ b/docs/docs/apis/benchmarks/index.mdx
@@ -57,9 +57,9 @@ The following metrics must be collected for each test iteration. The metrics are
| ZITADEL Version | Setup | The version of zitadel deployed | Semantic version or commit |
| ZITADEL Configuration | Setup | Configuration of zitadel which deviates from the defaults and is not secret | yaml |
| ZITADEL feature flags | Setup | Changed feature flags | yaml |
-| Database | Setup | Database type and version | **type**: crdb / psql **version**: semantic version |
+| Database | Setup | Database type and version | **type**: psql **version**: semantic version |
| Database location | Setup | Region or location of the deployment of the database. If not further specified the hoster is Google Cloud SQL | Location / Region |
-| Database specification | Setup | The description must at least clarify the following metrics: vCPU, Memory and egress bandwidth (Scale) | **vCPU**: Amount of threads ([additional info](https://cloud.google.com/compute/docs/cpu-platforms)) **memory**: GB **egress bandwidth**:Gbps **scale**: Amount of crdb nodes if crdb is used |
+| Database specification | Setup | The description must at least clarify the following metrics: vCPU, Memory and egress bandwidth (Scale) | **vCPU**: Amount of threads ([additional info](https://cloud.google.com/compute/docs/cpu-platforms)) **memory**: GB **egress bandwidth**:Gbps |
| ZITADEL metrics during test | Result | This metric helps understanding the bottlenecks of the executed test. At least the following metrics must be provided: CPU usage Memory usage | **CPU usage** in percent **Memory usage** in percent |
| Observed errors | Result | Errors worth mentioning, mostly unexpected errors | description |
| Top 3 most expensive database queries | Result | The execution plan of the top 3 most expensive database queries during the test execution | database execution plan |
diff --git a/docs/docs/concepts/architecture/software.md b/docs/docs/concepts/architecture/software.md
index 07265b6de5..dc6f2b56c7 100644
--- a/docs/docs/concepts/architecture/software.md
+++ b/docs/docs/concepts/architecture/software.md
@@ -1,51 +1,51 @@
---
-title: ZITADEL's Software Architecture
+title: Zitadel's Software Architecture
sidebar_label: Software Architecture
---
-ZITADEL is built with two essential patterns. Event Sourcing (ES) and Command and Query Responsibility Segregation (CQRS).
-Due to the nature of Event Sourcing ZITADEL provides the unique capability to generate a strong audit trail of ALL the things that happen to its resources, without compromising on storage cost or audit trail length.
+Zitadel is built with two essential patterns. Event Sourcing (ES) and Command and Query Responsibility Segregation (CQRS).
+Due to the nature of Event Sourcing Zitadel provides the unique capability to generate a strong audit trail of ALL the things that happen to its resources, without compromising on storage cost or audit trail length.
-The combination of ES and CQRS makes ZITADEL eventual consistent which, from our perspective, is a great benefit in many ways.
+The combination of ES and CQRS makes Zitadel eventual consistent which, from our perspective, is a great benefit in many ways.
It allows us to build a Source of Records (SOR) which is the one single point of truth for all computed states.
The SOR needs to be transaction safe to make sure all operations are in order.
You can read more about this in our [ES documentation](../eventstore/overview).
-Each ZITADEL binary contains all components necessary to serve traffic
+Each Zitadel binary contains all components necessary to serve traffic
From serving the API, rendering GUI's, background processing of events and task.
-This All in One (AiO) approach makes operating ZITADEL simple.
+This All in One (AiO) approach makes operating Zitadel simple.
## The Architecture
-ZITADELs software architecture is built around multiple components at different levels.
+Zitadels software architecture is built around multiple components at different levels.
This chapter should give you an idea of the components as well as the different layers.

### Service Layer
-The service layer includes all components who are potentially exposed to consumers of ZITADEL.
+The service layer includes all components who are potentially exposed to consumers of Zitadel.
#### HTTP Server
The http server is responsible for the following functions:
-- serving the management GUI called ZITADEL Console
+- serving the management GUI called Zitadel Console
- serving the static assets
- rendering server side html (login, password-reset, verification, ...)
#### API Server
-The API layer consist of the multiple APIs provided by ZITADEL. Each serves a dedicated purpose.
-All APIs of ZITADEL are always available as gRCP, gRPC-web and REST service.
+The API layer consist of the multiple APIs provided by Zitadel. Each serves a dedicated purpose.
+All APIs of Zitadel are always available as gRCP, gRPC-web and REST service.
The only exception is the [OpenID Connect & OAuth](/apis/openidoauth/endpoints) and [Asset API](/apis/introduction#assets) due their unique nature.
-- [OpenID Connect & OAuth](/apis/openidoauth/endpoints) - allows to request authentication and authorization of ZITADEL
-- [SAML](/apis/saml/endpoints) - allows to request authentication and authorization of ZITADEL through the SAML standard
+- [OpenID Connect & OAuth](/apis/openidoauth/endpoints) - allows to request authentication and authorization of Zitadel
+- [SAML](/apis/saml/endpoints) - allows to request authentication and authorization of Zitadel through the SAML standard
- [Authentication API](/apis/introduction#authentication) - allow a user to do operation in its own context
-- [Management API](/apis/introduction#management) - allows an admin or machine to manage the ZITADEL resources on an organization level
-- [Administration API](/apis/introduction#administration) - allows an admin or machine to manage the ZITADEL resources on an instance level
-- [System API](/apis/introduction#system) - allows to create and change new ZITADEL instances
+- [Management API](/apis/introduction#management) - allows an admin or machine to manage the Zitadel resources on an organization level
+- [Administration API](/apis/introduction#administration) - allows an admin or machine to manage the Zitadel resources on an instance level
+- [System API](/apis/introduction#system) - allows to create and change new Zitadel instances
- [Asset API](/apis/introduction#assets) - is used to upload and download static assets
### Core Layer
@@ -61,7 +61,7 @@ The Command Side has some unique requirements, these include:
##### Command Handler
-The command handler receives all operations who alter a resource managed by ZITADEL.
+The command handler receives all operations who alter a resource managed by Zitadel.
For example if a user changes his name. The API Layer will pass the instruction received through the API call to the command handler for further processing.
The command handler is then responsible of creating the necessary commands.
After creating the commands the command hand them down to the command validation.
@@ -75,14 +75,14 @@ These events now are being handed down to the storage layer for storage.
#### Events
-ZITADEL handles events in two ways.
+Zitadel handles events in two ways.
Events that should be processed in near real time are processed by a in memory pub sub system.
Some events can be handled asynchronously using the spooler.
##### Pub Sub
The pub sub system job is it to keep a query view up-to-date by feeding a constant stream of events to the projections.
-Our pub sub system built into ZITADEL works by placing events into an in memory queue for its subscribers.
+Our pub sub system built into Zitadel works by placing events into an in memory queue for its subscribers.
There is no need for specific guarantees from the pub sub system. Since the SOR is the ES everything can be retried without loss of data.
In case of an error an event can be reapplied in two ways:
@@ -90,8 +90,8 @@ In case of an error an event can be reapplied in two ways:
- The spooler takes care of background cleanups in a scheduled fashion
> The decision to incorporate an internal pub sub system with no need for specific guarantees is a deliberate choice.
-> We believe that the toll of operating an additional external service like a MQ system negatively affects the ease of use of ZITADEL as well as its availability guarantees.
-> One of the authors of ZITADEL did his thesis to test this approach against established MQ systems.
+> We believe that the toll of operating an additional external service like a MQ system negatively affects the ease of use of Zitadel as well as its availability guarantees.
+> One of the authors of Zitadel did his thesis to test this approach against established MQ systems.
##### Spooler
@@ -136,12 +136,16 @@ It is also responsible to execute authorization checks. To check if a request is
### Storage Layer
-As ZITADEL itself is built completely stateless only the storage layer is needed to persist states.
-The storage layer of ZITADEL is responsible for multiple tasks. For example:
+As Zitadel itself is built completely stateless only the storage layer is needed to persist states.
+The storage layer of Zitadel is responsible for multiple tasks. For example:
- Guarantee strong consistency for the command side
- Guarantee good query performance for the query side
- Backup and restore operation for disaster recovery purpose
-ZITADEL currently supports PostgreSQL and CockroachDB..
+Zitadel currently supports PostgreSQL.
Make sure to read our [Production Guide](/docs/self-hosting/manage/production#prefer-postgresql) before you decide on using one of them.
+
+:::info
+Zitadel v2 supported CockroachDB and PostgreSQL. Zitadel v3 only supports PostgreSQL. Please refer to [the mirror guide](cli/mirror) to migrate to PostgreSQL.
+:::
\ No newline at end of file
diff --git a/docs/docs/concepts/architecture/solution.md b/docs/docs/concepts/architecture/solution.md
index b99b8aa9dc..49e9e8f62f 100644
--- a/docs/docs/concepts/architecture/solution.md
+++ b/docs/docs/concepts/architecture/solution.md
@@ -1,21 +1,20 @@
---
-title: ZITADEL's Deployment Architecture
+title: Zitadel's Deployment Architecture
sidebar_label: Deployment Architecture
---
## High Availability
-ZITADEL can be run as high available system with ease.
+Zitadel can be run as high available system with ease.
Since the storage layer takes the heavy lifting of making sure that data in synched across, server, data centers or regions.
-Depending on your projects needs our general recommendation is to run ZITADEL and ZITADELs storage layer across multiple availability zones in the same region or if you need higher guarantees run the storage layer across multiple regions.
-Consult the [CockroachDB documentation](https://www.cockroachlabs.com/docs/) for more details or use the [CockroachCloud Service](https://www.cockroachlabs.com/docs/cockroachcloud/create-an-account.html)
-Alternatively you can run ZITADEL also with Postgres which is [Enterprise Supported](/docs/support/software-release-cycles-support#partially-supported).
-Make sure to read our [Production Guide](/self-hosting/manage/production#prefer-postgresql) before you decide to use it.
+Depending on your projects needs our general recommendation is to run Zitadel across multiple availability zones in the same region or across multiple regions.
+Make sure to read our [Production Guide](/docs/self-hosting/manage/production#prefer-postgresql) before you decide to use it.
+Consult the [Postgres documentation](https://www.postgresql.org/docs/) for more details.
## Scalability
-ZITADEL can be scaled in a linear fashion in multiple dimensions.
+Zitadel can be scaled in a linear fashion in multiple dimensions.
- Vertical on your compute infrastructure
- Horizontal in a region
@@ -23,45 +22,38 @@ ZITADEL can be scaled in a linear fashion in multiple dimensions.
Our customers can reuse the same already known binary or container and scale it across multiple server, data center and regions.
To distribute traffic an already existing proxy infrastructure can be reused.
-Simply steer traffic by path, hostname, IP address or any other metadata to the ZITADEL of your choice.
+Simply steer traffic by path, hostname, IP address or any other metadata to the Zitadel of your choice.
-> To improve your service quality we recommend steering traffic by path to different ZITADEL deployments
+> To improve your service quality we recommend steering traffic by path to different Zitadel deployments
> Feel free to [contact us](https://zitadel.com/contact/) for details
## Example Deployment Architecture
### Single Cluster / Region
-A ZITADEL Cluster is a highly available IAM system with each component critical for serving traffic laid out at least three times.
-As our storage layer (CockroachDB) relies on Raft, it is recommended to operate odd numbers of storage nodes to prevent "split brain" problems.
-Hence our reference design for Kubernetes is to have three application nodes and three storage nodes.
+A Zitadel Cluster is a highly available IAM system with each component critical for serving traffic laid out at least three times.
+Our storage layer (Postgres) is built for single region deployments.
+Hence our reference design for Kubernetes is to have three application nodes and one storage node.
-> If you are using a serverless offering like Google Cloud Run you can scale ZITADEL from 0 to 1000 Pods without the need of deploying the node across multiple availability zones.
-
-:::info
-CockroachDB needs to be configured with locality flags to proper distribute data over the zones
-:::
+> If you are using a serverless offering like Google Cloud Run you can scale Zitadel from 0 to 1000 Pods without the need of deploying the node across multiple availability zones.

### Multi Cluster / Region
-To scale ZITADEL across regions it is recommend to create at least three cluster.
-We recommend to run an odd number of storage clusters (storage nodes per data center) to compensate for "split brain" scenarios.
-In our reference design we recommend to create one cluster per region or cloud provider with a minimum of three regions.
+To scale Zitadel across regions it is recommend to create at least three clusters.
+Each cluster is a fully independent ZITADEL setup.
+To keep the data in sync across all clusters, we recommend using Postgres with read-only replicas as a storage layer.
+Make sure to read our [Production Guide](/docs/self-hosting/manage/production#prefer-postgresql) before you decide to use it.
+Consult the [Postgres documentation](https://www.postgresql.org/docs/current/high-availability.html) for more details.
-With this design even the outage of a whole data-center would have a minimal impact as all data is still available at the other two locations.
-
-:::info
-CockroachDB needs to be configured with locality flags to proper distribute data over the zones
-:::

## Zero Downtime Updates
Since an Identity system tends to be a critical piece of infrastructure, the "in place zero downtime update" is a well needed feature.
-ZITADEL is built in a way that upgrades can be executed without downtime by just updating to a more recent version.
+Zitadel is built in a way that upgrades can be executed without downtime by just updating to a more recent version.
The common update involves the following steps and do not need manual intervention of the operator:
@@ -78,5 +70,5 @@ Users who use [Kubernetes/Helm](/docs/self-hosting/deploy/kubernetes) or serverl
:::info
As a good practice we recommend creating Database Backups prior to an update.
It is also recommend to read the release notes on GitHub before upgrading.
-Since ZITADEL utilizes Semantic Versioning Breaking Changes of any kind will always increase the major version (e.g Version 2 would become Version 3).
+Since Zitadel utilizes Semantic Versioning Breaking Changes of any kind will always increase the major version (e.g Version 2 would become Version 3).
:::
diff --git a/docs/docs/concepts/features/actions_v2.md b/docs/docs/concepts/features/actions_v2.md
index 85f05b7c29..83c3ad480c 100644
--- a/docs/docs/concepts/features/actions_v2.md
+++ b/docs/docs/concepts/features/actions_v2.md
@@ -46,5 +46,5 @@ Currently, the defined Actions v2 will be executed additionally to the defined [
## Further reading
-- [Actions v2 reference](/apis/actions/v3/usage)
-- [Actions v2 example execution locally](/apis/actions/v3/testing-locally)
\ No newline at end of file
+- [Actions v2 reference](/apis/actions/v2/usage)
+- [Actions v2 example execution locally](/apis/actions/v2/testing-locally)
\ No newline at end of file
diff --git a/docs/docs/guides/integrate/external-audit-log.md b/docs/docs/guides/integrate/external-audit-log.md
index 93262d26f7..80dd41410d 100644
--- a/docs/docs/guides/integrate/external-audit-log.md
+++ b/docs/docs/guides/integrate/external-audit-log.md
@@ -20,7 +20,6 @@ The following table shows the available integration patterns for streaming audit
| | Description | Self-hosting | ZITADEL Cloud |
|-------------------------------------|----------------------------------------------------------------------------------------------------------------|-------------|---------------|
| Events-API | Pulling events of all ZITADEL resources such as Users, Projects, Apps, etc. (Events = Change Log of Resources) | ✅ | ✅ |
-| Cockroach Change Data Capture | Sending events of all ZITADEL resources such as Users, Projects, Apps, etc. (Events = Change Log of Resources) | ✅ | ❌ |
| ZITADEL Actions Log to Stdout | Custom log to messages possible on predefined triggers during login / register Flow | ✅ | ❌ |
| ZITADEL Actions trigger API/Webhook | Custom API/Webhook request on predefined triggers during login / register | ✅ | ✅ |
@@ -34,71 +33,6 @@ This API offers granular control through various filters, enabling you to:
You can find a comprehensive guide on how to use the events API for different use cases here: [Get Events from ZITADEL](/docs/guides/integrate/zitadel-apis/event-api)
-### Cockroach Change Data Capture
-
-For self-hosted ZITADEL deployments utilizing CockroachDB as the database, [CockroachDB's built-in Change Data Capture (CDC)](https://www.cockroachlabs.com/docs/stable/change-data-capture-overview) functionality provides a streamlined approach to integrate ZITADEL audit logs with external systems.
-
-CDC captures row-level changes in your database and streams them as messages to a configurable destination, such as Google BigQuery or a SIEM/SOC solution. This real-time data stream enables:
-- **Continuous monitoring**: Receive near-instantaneous updates on ZITADEL activity, facilitating proactive threat detection and response.
-- **Simplified integration**: Leverage CockroachDB's native capabilities for real-time data transfer, eliminating the need for additional tools or configurations.
-
-This approach is limited to self-hosted deployments using CockroachDB and requires expertise in managing the database and CDC configuration.
-
-#### Sending events to Google Cloud Storage using Change Data Capture
-
-This example will show you how you can utilize CDC for sending all ZITADEL events to Google Cloud Storage.
-For a detailed description please read [CockroachLab's Get Started Guide](https://www.cockroachlabs.com/docs/v23.2/create-and-configure-changefeeds) and [Cloud Storage Authentication](https://www.cockroachlabs.com/docs/v23.2/cloud-storage-authentication?filters=gcs#set-up-google-cloud-storage-assume-role) from Cockroach.
-
-You will need a Google Cloud Storage Bucket and a service account.
-1. [Create Google Cloud Storage Bucket](https://cloud.google.com/storage/docs/creating-buckets)
-2. [Create Service Account](https://cloud.google.com/iam/docs/service-accounts-create)
-3. Create a role with the `storage.objects.create` permission
-4. Grant service account access to the bucket
-5. Create key for service account and download it
-
-Now we need to enable and create the changefeed in the cockroach DB.
-1. [Enable rangefeeds on cockroach cluster](https://www.cockroachlabs.com/docs/v23.2/create-and-configure-changefeeds#enable-rangefeeds)
- ```bash
- SET CLUSTER SETTING kv.rangefeed.enabled = true;
- ```
-2. Encode the keyfile from the service account with base64 and replace the placeholder it in the script below
-3. Create Changefeed to send data into Google Cloud Storage
- The following example sends all events without payload to Google Cloud Storage
- Per default we do not want to send the payload of the events, as this could potentially include personally identifiable information (PII)
- If you want to include the payload, you can just add `payload` to the select list in the query.
- ```sql
- CREATE CHANGEFEED INTO 'gs://gc-storage-zitadel-data/events?partition_format=flat&AUTH=specified&CREDENTIALS=base64encodedkey'
- AS SELECT instance_id, aggregate_type, aggregate_id, owner, event_type, sequence, created_at
- FROM eventstore.events2;
- ```
-
-In some cases you might want the payload of only some specific events.
-This example shows you how to get all events and the instance domain events with the payload:
- ```sql
- CREATE CHANGEFEED INTO 'gs://gc-storage-zitadel-data/events?partition_format=flat&AUTH=specified&CREDENTIALS=base64encodedkey'
- AS SELECT instance_id, aggregate_type, aggregate_id, owner, event_type, sequence, created_at
- CASE WHEN event_type IN ('instance.domain.added', 'instance.domain.removed', 'instance.domain.primary.set' )
- THEN payload END AS payload
- FROM eventstore.events2;
- ```
-
-The partition format in the example above is flat, this means that all files for each timestamp will be created in the same folder.
-You will have files for different timestamps including the output for the events created in that time.
-Each event is represented as a json row.
-
-Example Output:
-```json lines
-{
- "aggregate_id": "26553987123463875",
- "aggregate_type": "user",
- "created_at": "2023-12-25T10:01:45.600913Z",
- "event_type": "user.human.added",
- "instance_id": "123456789012345667",
- "payload": null,
- "sequence": 1
-}
-```
-
## ZITADEL Actions
ZITADEL [Actions](/docs/concepts/features/actions) offer a powerful mechanism for extending the platform's capabilities and integrating with external systems tailored to your specific requirements.
diff --git a/docs/docs/guides/integrate/login/hosted-login.mdx b/docs/docs/guides/integrate/login/hosted-login.mdx
index e048eeb4e9..09fb86f8f0 100644
--- a/docs/docs/guides/integrate/login/hosted-login.mdx
+++ b/docs/docs/guides/integrate/login/hosted-login.mdx
@@ -138,6 +138,10 @@ In this initial release, the new login is available for self-hosting only. We'll
### Current State
+:::info
+The documentation describes the state of the feature in ZITADEL V3.
+:::
+
Our primary goal for the TypeScript login system is to replace the existing login functionality within Zitadel Core, which is shipped with Zitadel automatically. This will allow us to leverage the benefits of the new system, including its modular architecture and enhanced security features.
To achieve this, we are actively working on implementing the core features currently available in Zitadel Core, such as:
@@ -160,15 +164,10 @@ As we continue to develop the TypeScript login system, we will provide regular u
For the first implementation we have excluded the following features:
-- SAML (SP & OP)
- Generic JWT IDP
- LDAP IDP
- Device Authorization Grants
-- Timebased features
- - Lockout Settings
- - Password Expiry Settings
- - Login Settings - Multifactor init prompt
- - Force MFA on external authenticated users
+- Force MFA on external authenticated users
- Passkey/U2F Setup
- As passkey and u2f is bound to a domain, it is important to notice, that setting up the authentication possibility in the ZITADEL management console (Self-service), will not work if the login runs on a different domain
- Custom Login Texts
diff --git a/docs/docs/guides/integrate/login/oidc/webkeys.md b/docs/docs/guides/integrate/login/oidc/webkeys.md
index 2b414ae7e9..a66cae61a9 100644
--- a/docs/docs/guides/integrate/login/oidc/webkeys.md
+++ b/docs/docs/guides/integrate/login/oidc/webkeys.md
@@ -23,6 +23,7 @@ endpoints are called with a JWT access token.
:::info
Web keys are an [experimental](/docs/support/software-release-cycles-support#beta) feature. Be sure to enable the `web_key` [feature](/docs/apis/resources/feature_service_v2/feature-service-set-instance-features) before using it.
+The documentation describes the state of the feature in ZITADEL V3.
Test the feature and add improvement or bug reports directly to the [github repository](https://github.com/zitadel/zitadel) or let us know your general feedback in the [discord thread](https://discord.com/channels/927474939156643850/1329100936127320175/threads/1332344892629717075)!
:::
@@ -112,7 +113,7 @@ When the request does not contain any specific configuration,
[RSA](#rsa) is used as default with the default options as described below:
```bash
-curl -L 'https://$CUSTOM-DOMAIN/resources/v3alpha/web_keys' \
+curl -L 'https://$CUSTOM-DOMAIN/v2beta/web_keys' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ' \
@@ -136,7 +137,7 @@ The RSA generator config takes two enum values.
For example, to create a RSA web key with the size of 3072 bits and the SHA512 algorithm (RS512):
```bash
-curl -L 'https://$CUSTOM-DOMAIN/resources/v3alpha/web_keys' \
+curl -L 'https://$CUSTOM-DOMAIN/v2beta/web_keys' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ' \
@@ -160,7 +161,7 @@ The ECDSA generator config takes a single `curve` enum value which determines bo
For example, to create a ECDSA web key with a P-256 curve and the SHA256 algorithm:
```bash
-curl -L 'https://$CUSTOM-DOMAIN/resources/v3alpha/web_keys' \
+curl -L 'https://$CUSTOM-DOMAIN/v2beta/web_keys' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ' \
@@ -184,7 +185,7 @@ Clients which support both curves must inspect `crv` header value to assert the
For example, to create a ed25519 web key:
```bash
-curl -L 'https://$CUSTOM-DOMAIN/resources/v3alpha/web_keys' \
+curl -L 'https://$CUSTOM-DOMAIN/v2beta/web_keys' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ' \
@@ -246,11 +247,11 @@ For the sake of this example we will use simplified IDs and restrict timestamps
After one month, on 2025-02-01, we wish to activate the next available key and create a new key to be available for activation next month. This fulfills requirements 1 and 2.
```bash
-curl -L -X POST 'https://$CUSTOM-DOMAIN/resources/v3alpha/web_keys/2/_activate' \
+curl -L -X POST 'https://$CUSTOM-DOMAIN/v2beta/web_keys/2/_activate' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer '
-curl -L 'https://$CUSTOM-DOMAIN/resources/v3alpha/web_keys' \
+curl -L 'https://$CUSTOM-DOMAIN/v2beta/web_keys' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer ' \
@@ -282,7 +283,7 @@ In addition to the activate and create calls we made on this iteration,
we can now safely delete the oldest key, as both requirement 3 and 4 are now fulfilled:
```bash
-curl -L -X DELETE 'https://$CUSTOM-DOMAIN/resources/v3alpha/web_keys/1' \
+curl -L -X DELETE 'https://$CUSTOM-DOMAIN/v2beta/web_keys/1' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer '
```
diff --git a/docs/docs/guides/integrate/zitadel-apis/access-zitadel-system-api.md b/docs/docs/guides/integrate/zitadel-apis/access-zitadel-system-api.md
index 4e2b0b9973..4b96e9bbd5 100644
--- a/docs/docs/guides/integrate/zitadel-apis/access-zitadel-system-api.md
+++ b/docs/docs/guides/integrate/zitadel-apis/access-zitadel-system-api.md
@@ -16,6 +16,8 @@ To authenticate the user a self-signed JWT will be created and utilized.
You can define any id for your user. This guide will assume it's `system-user-1`.
+**NOTE:** system user id cannot contain capital letters
+
## Generate an RSA keypair
Generate an RSA private key with 2048 bit modulus:
diff --git a/docs/docs/guides/manage/console/_create-user.mdx b/docs/docs/guides/manage/console/_create-user.mdx
index ce9141af72..3434284de2 100644
--- a/docs/docs/guides/manage/console/_create-user.mdx
+++ b/docs/docs/guides/manage/console/_create-user.mdx
@@ -3,9 +3,34 @@ To create a new user, go to Users and click on **New**. Enter the required conta
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
+:::note
+If you started with Zitadel before version 3, you might have the "Human User [deprecated]" UI.
+In this case please enable the Feature Flag "Use V2 Api in Console for User creation" in the Default Settings.
+:::
+
+
+
+ When creating a new user you have different options.
+ First add the email, and select if the email address should be added automatically as "verified".
+
+ In the last section you can choose the authentication options:
+ - **Setup authentication later for this user**: This flow might be useful if an employee starts at a later point but you already want to prepare the account. The user will not have an authentication method, before they will be able to login, they need to setup a method.
+ - **Send an invitation E-Mail for authentication setup and E-Mail verification**: The user will receive an email and be able to setup an authentication method (e.g Password, Passkey, External SSO).
+ - When using the [Zitadel Login V1](/docs/guides/integrate/login/hosted-login) the user will be prompted to setup a password
+ - When using the [Zitadel Login V2](/docs/guides/integrate/login/hosted-login#hosted-login-version-2-beta) the user has the option to choose the authentication method (password, passkey, identity provider), based on the configuration of the organization
+
+ - **Set an initial password for the user**: The user will receive an email and be able to setup an authentication method (e.g Password, Passkey, External SSO)
+
+
+
+
+ After a human user is created, by default, an initialization mail with a code is sent to the registered email. This code then has to be verified on first login.
+ If you want to omit this mail, you can check the **email verified** and **set initial password** toggle.
+ If no password is set initially, the initialization mail prompting the user to set his password is sent.
+
-After a human user is created, by default, an initialization mail with a code is sent to the registered email. This code then has to be verified on first login.
-If you want to omit this mail, you can check the **email verified** and **set initial password** toggle.
-If no password is set initially, the initialization mail prompting the user to set his password is sent.
-
You can prompt the user to add a second factor method too by checking the **Force MFA** toggle in [Login behaviour settings](/docs/guides/manage/console/default-settings#login-behavior-and-access).
When logged in, a user can then manage the profile in the console, adding a profile picture, external IDPs and Passwordless authentication devices.
diff --git a/docs/docs/self-hosting/deploy/docker-compose-sa.yaml b/docs/docs/self-hosting/deploy/docker-compose-sa.yaml
index 95608fd76d..9edd95faa0 100644
--- a/docs/docs/self-hosting/deploy/docker-compose-sa.yaml
+++ b/docs/docs/self-hosting/deploy/docker-compose-sa.yaml
@@ -32,7 +32,7 @@ services:
db:
restart: 'always'
- image: postgres:16-alpine
+ image: postgres:17-alpine
environment:
PGUSER: postgres
POSTGRES_PASSWORD: postgres
diff --git a/docs/docs/self-hosting/deploy/docker-compose.yaml b/docs/docs/self-hosting/deploy/docker-compose.yaml
index e32700ace4..f5164eb3b7 100644
--- a/docs/docs/self-hosting/deploy/docker-compose.yaml
+++ b/docs/docs/self-hosting/deploy/docker-compose.yaml
@@ -24,7 +24,7 @@ services:
db:
restart: 'always'
- image: postgres:16-alpine
+ image: postgres:17-alpine
environment:
PGUSER: postgres
POSTGRES_PASSWORD: postgres
diff --git a/docs/docs/self-hosting/deploy/linux.mdx b/docs/docs/self-hosting/deploy/linux.mdx
index eb7f4dc90d..90774e97ab 100644
--- a/docs/docs/self-hosting/deploy/linux.mdx
+++ b/docs/docs/self-hosting/deploy/linux.mdx
@@ -1,5 +1,5 @@
---
-title: Install ZITADEL on Linux
+title: Install Zitadel on Linux
sidebar_label: Linux
---
@@ -11,7 +11,7 @@ import NoteInstanceNotFound from "./troubleshooting/_note_instance_not_found.mdx
## Install PostgreSQL
Download a `postgresql` binary as described [in the PostgreSQL docs](https://www.postgresql.org/download/linux/).
-ZITADEL is tested against PostgreSQL and CockroachDB latest stable tag and Ubuntu 22.04.
+Zitadel is tested against PostgreSQL latest stable tag and latest Ubuntu LTS.
## Run PostgreSQL
@@ -20,15 +20,15 @@ sudo systemctl start postgresql
sudo systemctl enable postgresql
```
-## Install ZITADEL
+## Install Zitadel
-Download the ZITADEL release according to your architecture from [Github](https://github.com/zitadel/zitadel/releases/latest), unpack the archive and copy zitadel binary to /usr/local/bin
+Download the Zitadel release according to your architecture from [Github](https://github.com/zitadel/zitadel/releases/latest), unpack the archive and copy zitadel binary to /usr/local/bin
```bash
LATEST=$(curl -i https://github.com/zitadel/zitadel/releases/latest | grep location: | cut -d '/' -f 8 | tr -d '\r'); ARCH=$(uname -m); case $ARCH in armv5*) ARCH="armv5";; armv6*) ARCH="armv6";; armv7*) ARCH="arm";; aarch64) ARCH="arm64";; x86) ARCH="386";; x86_64) ARCH="amd64";; i686) ARCH="386";; i386) ARCH="386";; esac; wget -c https://github.com/zitadel/zitadel/releases/download/$LATEST/zitadel-linux-$ARCH.tar.gz -O - | tar -xz && sudo mv zitadel-linux-$ARCH/zitadel /usr/local/bin
```
-## Run ZITADEL
+## Run Zitadel
```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_PASSWORD=postgres ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=disable ZITADEL_EXTERNALSECURE=false zitadel start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled
@@ -50,7 +50,7 @@ ZITADEL_DATABASE_POSTGRES_HOST=localhost ZITADEL_DATABASE_POSTGRES_PORT=5432 ZIT
allowfullscreen
>
-### Setup ZITADEL with a service account
+### Setup Zitadel with a service account
```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_FIRSTINSTANCE_MACHINEKEYPATH=/tmp/zitadel-admin-sa.json ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_USERNAME=zitadel-admin-sa ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINE_NAME=Admin ZITADEL_FIRSTINSTANCE_ORG_MACHINE_MACHINEKEY_TYPE=1 zitadel start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode disabled
diff --git a/docs/docs/self-hosting/deploy/loadbalancing-example/docker-compose.yaml b/docs/docs/self-hosting/deploy/loadbalancing-example/docker-compose.yaml
index 94d8f438dc..d1d8c95bb2 100644
--- a/docs/docs/self-hosting/deploy/loadbalancing-example/docker-compose.yaml
+++ b/docs/docs/self-hosting/deploy/loadbalancing-example/docker-compose.yaml
@@ -25,7 +25,7 @@ services:
- './example-zitadel-init-steps.yaml:/example-zitadel-init-steps.yaml:ro'
db:
- image: postgres:16-alpine
+ image: postgres:17-alpine
restart: always
environment:
- POSTGRES_USER=root
diff --git a/docs/docs/self-hosting/deploy/loadbalancing-example/loadbalancing-example.mdx b/docs/docs/self-hosting/deploy/loadbalancing-example/loadbalancing-example.mdx
index 7f25a9b210..d5e3984568 100644
--- a/docs/docs/self-hosting/deploy/loadbalancing-example/loadbalancing-example.mdx
+++ b/docs/docs/self-hosting/deploy/loadbalancing-example/loadbalancing-example.mdx
@@ -81,5 +81,5 @@ Read more about [the login process](/guides/integrate/login/oidc/login-users).
## Troubleshooting
-You can connect to cockroach like this: `docker exec -it loadbalancing-example-my-cockroach-db-1 cockroach sql --host my-cockroach-db --certs-dir /cockroach/certs/`
-For example, to show all login names: `docker exec -it loadbalancing-example-my-cockroach-db-1 cockroach sql --database zitadel --host my-cockroach-db --certs-dir /cockroach/certs/ --execute "select * from projections.login_names3"`
+You can connect to the database like this: `docker exec -it loadbalancing-example-db-1 psql --host localhost`
+For example, to show all login names: `docker exec -it loadbalancing-example-db-1 psql -d zitadel --host localhost -c 'select * from projections.login_names3'`
diff --git a/docs/docs/self-hosting/deploy/macos.mdx b/docs/docs/self-hosting/deploy/macos.mdx
index f736255478..beb3182208 100644
--- a/docs/docs/self-hosting/deploy/macos.mdx
+++ b/docs/docs/self-hosting/deploy/macos.mdx
@@ -11,7 +11,7 @@ import NoteInstanceNotFound from './troubleshooting/_note_instance_not_found.mdx
## Install PostgreSQL
Download a `postgresql` binary as described [in the PostgreSQL docs](https://www.postgresql.org/download/macosx/).
-ZITADEL is tested against PostgreSQL and CockroachDB latest stable tag and Ubuntu 22.04.
+ZITADEL is tested against PostgreSQL latest stable tag and latest Ubuntu LTS.
## Run PostgreSQL
diff --git a/docs/docs/self-hosting/deploy/overview.mdx b/docs/docs/self-hosting/deploy/overview.mdx
index 38517c52f4..68255d4ce3 100644
--- a/docs/docs/self-hosting/deploy/overview.mdx
+++ b/docs/docs/self-hosting/deploy/overview.mdx
@@ -14,7 +14,7 @@ Choose your platform and run ZITADEL with the most minimal configuration possibl
## Prerequisites
- For test environments, ZITADEL does not need many resources, 1 CPU and 512MB memory are more than enough. (With more CPU, the password hashing might be faster)
-- A PostgreSQL or CockroachDB as only needed storage. Make sure to read our [Production Guide](/docs/self-hosting/manage/production#prefer-postgresql) before you decide to use Postgresql.
+- A PostgreSQL as only needed storage. Make sure to read our [Production Guide](/docs/self-hosting/manage/production#prefer-postgresql) before you decide to use Postgresql.
## Releases
diff --git a/docs/docs/self-hosting/manage/cache.md b/docs/docs/self-hosting/manage/cache.md
index 30619ad283..32973d5586 100644
--- a/docs/docs/self-hosting/manage/cache.md
+++ b/docs/docs/self-hosting/manage/cache.md
@@ -110,7 +110,6 @@ Drawbacks:
- Slowest of the available caching options
- Might put additional strain on the database server, limiting horizontal scalability
-- CockroachDB does not support unlogged tables. When this connector is enabled against CockroachDB, it does work but little to no performance benefit is to be expected.
### Local memory cache
diff --git a/docs/docs/self-hosting/manage/cli/mirror.mdx b/docs/docs/self-hosting/manage/cli/mirror.mdx
index 1c32dc8741..45bac9b279 100644
--- a/docs/docs/self-hosting/manage/cli/mirror.mdx
+++ b/docs/docs/self-hosting/manage/cli/mirror.mdx
@@ -1,5 +1,5 @@
---
-title: Mirror data to another database
+title: Mirror data from cockroach to postgres
sidebar_label: Mirror command
---
@@ -9,15 +9,15 @@ The data can be mirrored to multiple database without influencing each other.
## Use cases
-Migrate from cockroachdb to postgres or vice versa.
+Migrate from cockroachdb to postgres.
Replicate data to a secondary environment for testing.
## Prerequisites
-You need an existing source database, most probably the database ZITADEL currently serves traffic from.
+You need an existing source database, most probably the database Zitadel currently serves traffic from.
-To mirror the data the destination database needs to be initialized and setup without an instance.
+To mirror the data, the destination database needs to be initialized and set up without an instance. You can find the commands to start an empty Zitadel deployment in [the example section](#prepare-the-destination-database).
### Start the destination database
@@ -38,14 +38,32 @@ docker compose up db --detach
## Example
-The following commands setup the database as described above. See [configuration](#configuration) for more details about the configuration options.
+### Prepare the destination database
+
+The following commands setup the database without an instance.
```bash
zitadel init --config /path/to/your/new/config.yaml
zitadel setup --for-mirror --config /path/to/your/new/config.yaml # make sure to set --tlsMode and masterkey analog to your current deployment
+```
+
+### Mirror the data
+
+The next step is to copy the data from the source to the destination database. For detailed configuration options, please refer to the [configuration section](#configuration).
+
+```bash
zitadel mirror --system --config /path/to/your/mirror/config.yaml # make sure to set --tlsMode and masterkey analog to your current deployment
```
+### Initialize the data and verify
+
+The last step is to setup the permissions and verify the data, there might be differences between source and destination, refer to [`zitadel mirror verify`](#zitadel-mirror-verify) to get an overview of possible diffs.
+
+```bash
+zitadel setup --for-mirror --config /path/to/your/new/config.yaml # make sure to set --tlsMode and masterkey analog to your current deployment
+zitadel mirror verify --system --config /path/to/your/mirror/config.yaml # make sure to set --tlsMode and masterkey analog to your current deployment
+```
+
## Usage
The general syntax for the mirror command is:
@@ -73,7 +91,7 @@ Flags:
--masterkey string masterkey as argument for en/decryption keys
-m, --masterkeyFile string path to the masterkey for en/decryption keys
--masterkeyFromEnv read masterkey for en/decryption keys from environment variable (ZITADEL_MASTERKEY)
- --tlsMode externalSecure start ZITADEL with (enabled), without (disabled) TLS or external component e.g. reverse proxy (external) terminating TLS, this flag will overwrite externalSecure and `tls.enabled` in configs files
+ --tlsMode externalSecure start Zitadel with (enabled), without (disabled) TLS or external component e.g. reverse proxy (external) terminating TLS, this flag will overwrite externalSecure and `tls.enabled` in configs files
```
## Configuration
@@ -87,8 +105,6 @@ Source:
Database: zitadel # ZITADEL_SOURCE_COCKROACH_DATABASE
MaxOpenConns: 6 # ZITADEL_SOURCE_COCKROACH_MAXOPENCONNS
MaxIdleConns: 6 # ZITADEL_SOURCE_COCKROACH_MAXIDLECONNS
- EventPushConnRatio: 0.33 # ZITADEL_SOURCE_COCKROACH_EVENTPUSHCONNRATIO
- ProjectionSpoolerConnRatio: 0.33 # ZITADEL_SOURCE_COCKROACH_PROJECTIONSPOOLERCONNRATIO
MaxConnLifetime: 30m # ZITADEL_SOURCE_COCKROACH_MAXCONNLIFETIME
MaxConnIdleTime: 5m # ZITADEL_SOURCE_COCKROACH_MAXCONNIDLETIME
Options: "" # ZITADEL_SOURCE_COCKROACH_OPTIONS
@@ -122,44 +138,23 @@ Source:
# The destination database the data are copied to. Use either cockroach or postgres, by default cockroach is used
Destination:
- cockroach:
- Host: localhost # ZITADEL_DESTINATION_COCKROACH_HOST
- Port: 26257 # ZITADEL_DESTINATION_COCKROACH_PORT
- Database: zitadel # ZITADEL_DESTINATION_COCKROACH_DATABASE
- MaxOpenConns: 0 # ZITADEL_DESTINATION_COCKROACH_MAXOPENCONNS
- MaxIdleConns: 0 # ZITADEL_DESTINATION_COCKROACH_MAXIDLECONNS
- MaxConnLifetime: 30m # ZITADEL_DESTINATION_COCKROACH_MAXCONNLIFETIME
- MaxConnIdleTime: 5m # ZITADEL_DESTINATION_COCKROACH_MAXCONNIDLETIME
- EventPushConnRatio: 0.01 # ZITADEL_DESTINATION_COCKROACH_EVENTPUSHCONNRATIO
- ProjectionSpoolerConnRatio: 0.5 # ZITADEL_DESTINATION_COCKROACH_PROJECTIONSPOOLERCONNRATIO
- Options: "" # ZITADEL_DESTINATION_COCKROACH_OPTIONS
- User:
- Username: zitadel # ZITADEL_DESTINATION_COCKROACH_USER_USERNAME
- Password: "" # ZITADEL_DESTINATION_COCKROACH_USER_PASSWORD
- SSL:
- Mode: disable # ZITADEL_DESTINATION_COCKROACH_USER_SSL_MODE
- RootCert: "" # ZITADEL_DESTINATION_COCKROACH_USER_SSL_ROOTCERT
- Cert: "" # ZITADEL_DESTINATION_COCKROACH_USER_SSL_CERT
- Key: "" # ZITADEL_DESTINATION_COCKROACH_USER_SSL_KEY
- # Postgres is used as soon as a value is set
- # The values describe the possible fields to set values
postgres:
- Host: # ZITADEL_DESTINATION_POSTGRES_HOST
- Port: # ZITADEL_DESTINATION_POSTGRES_PORT
- Database: # ZITADEL_DESTINATION_POSTGRES_DATABASE
- MaxOpenConns: # ZITADEL_DESTINATION_POSTGRES_MAXOPENCONNS
- MaxIdleConns: # ZITADEL_DESTINATION_POSTGRES_MAXIDLECONNS
- MaxConnLifetime: # ZITADEL_DESTINATION_POSTGRES_MAXCONNLIFETIME
- MaxConnIdleTime: # ZITADEL_DESTINATION_POSTGRES_MAXCONNIDLETIME
- Options: # ZITADEL_DESTINATION_POSTGRES_OPTIONS
+ Host: localhost # ZITADEL_DATABASE_POSTGRES_HOST
+ Port: 5432 # ZITADEL_DATABASE_POSTGRES_PORT
+ Database: zitadel # ZITADEL_DATABASE_POSTGRES_DATABASE
+ MaxOpenConns: 5 # ZITADEL_DATABASE_POSTGRES_MAXOPENCONNS
+ MaxIdleConns: 2 # ZITADEL_DATABASE_POSTGRES_MAXIDLECONNS
+ MaxConnLifetime: 30m # ZITADEL_DATABASE_POSTGRES_MAXCONNLIFETIME
+ MaxConnIdleTime: 5m # ZITADEL_DATABASE_POSTGRES_MAXCONNIDLETIME
+ Options: "" # ZITADEL_DATABASE_POSTGRES_OPTIONS
User:
- Username: # ZITADEL_DESTINATION_POSTGRES_USER_USERNAME
- Password: # ZITADEL_DESTINATION_POSTGRES_USER_PASSWORD
+ Username: zitadel # ZITADEL_DATABASE_POSTGRES_USER_USERNAME
+ Password: "" # ZITADEL_DATABASE_POSTGRES_USER_PASSWORD
SSL:
- Mode: # ZITADEL_DESTINATION_POSTGRES_USER_SSL_MODE
- RootCert: # ZITADEL_DESTINATION_POSTGRES_USER_SSL_ROOTCERT
- Cert: # ZITADEL_DESTINATION_POSTGRES_USER_SSL_CERT
- Key: # ZITADEL_DESTINATION_POSTGRES_USER_SSL_KEY
+ Mode: disable # ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE
+ RootCert: "" # ZITADEL_DATABASE_POSTGRES_USER_SSL_ROOTCERT
+ Cert: "" # ZITADEL_DATABASE_POSTGRES_USER_SSL_CERT
+ Key: "" # ZITADEL_DATABASE_POSTGRES_USER_SSL_KEY
# As cockroachdb first copies the data into memory this parameter is used to iterate through the events table and fetch only the given amount of events per iteration
EventBulkSize: 10000 # ZITADEL_EVENTBULKSIZE
@@ -227,6 +222,6 @@ It is not possible to use files as source or destination. See github issue [here
Currently the encryption keys of the source database must be copied to the destination database. See github issue [here](https://github.com/zitadel/zitadel/issues/7964)
-It is not possible to change the domain of the ZITADEL deployment.
+It is not possible to change the domain of the Zitadel deployment.
Once you mirrored an instance using the `--instance` flag, you have to make sure you don't mirror other preexisting instances. This means for example, you cannot mirror a few instances and then pass the `--system` flag. You have to pass all remaining instances explicitly, once you used the `--instance` flag
diff --git a/docs/docs/self-hosting/manage/database/_cockroachdb.mdx b/docs/docs/self-hosting/manage/database/_cockroachdb.mdx
index edc3f139fd..90c99470e6 100644
--- a/docs/docs/self-hosting/manage/database/_cockroachdb.mdx
+++ b/docs/docs/self-hosting/manage/database/_cockroachdb.mdx
@@ -1,8 +1,12 @@
-## ZITADEL with Cockroach
+## Zitadel v2 with Cockroach
-The default database of ZITADEL is [CockroachDB](https://www.cockroachlabs.com). The SQL database provides a bunch of features like horizontal scalability, data regionality and many more.
+:::warning
+Zitadel v3 removed CockroachDB support. See the [CLI mirror guide](../cli/mirror) for migrating to PostgreSQL.
+:::
-Currently versions >= 23.2 are supported.
+The default database of Zitadel v2 is [CockroachDB](https://www.cockroachlabs.com). The SQL database provides a bunch of features like horizontal scalability, data regionality and many more.
+
+Currently versions >= 25.1 are supported.
The default configuration of the database looks like this:
diff --git a/docs/docs/self-hosting/manage/database/_postgres.mdx b/docs/docs/self-hosting/manage/database/_postgres.mdx
index 604d6b39a5..719fb9469e 100644
--- a/docs/docs/self-hosting/manage/database/_postgres.mdx
+++ b/docs/docs/self-hosting/manage/database/_postgres.mdx
@@ -1,6 +1,8 @@
## ZITADEL with Postgres
-If you want to use a PostgreSQL database you can [overwrite the default configuration](../configure/configure.mdx).
+PostgreSQL is the default database for ZITADEL due to its reliability, robustness, and adherence to SQL standards. It is well-suited for handling the complex data requirements of an identity management system.
+
+If you are using Zitadel v2 and want to use a PostgreSQL database you can [overwrite the default configuration](../configure/configure.mdx).
Currently versions >= 14 are supported.
diff --git a/docs/docs/self-hosting/manage/database/database.mdx b/docs/docs/self-hosting/manage/database/database.mdx
index c67ecbaaba..df491e1565 100644
--- a/docs/docs/self-hosting/manage/database/database.mdx
+++ b/docs/docs/self-hosting/manage/database/database.mdx
@@ -11,10 +11,10 @@ import Postgres from './_postgres.mdx'
diff --git a/docs/docs/self-hosting/manage/production.md b/docs/docs/self-hosting/manage/production.md
index fde620b13e..98296281ea 100644
--- a/docs/docs/self-hosting/manage/production.md
+++ b/docs/docs/self-hosting/manage/production.md
@@ -111,14 +111,15 @@ but in the Projections.Customizations.Telemetry section
### Prefer PostgreSQL
-ZITADEL supports [CockroachDB](https://www.cockroachlabs.com/) and [PostgreSQL](https://www.postgresql.org/).
-We recommend using PostgreSQL, as it is the better choice when you want to prioritize performance and latency.
+ZITADEL supports [PostgreSQL](https://www.postgresql.org/).
-However, if [multi-regional data locality](https://www.cockroachlabs.com/docs/stable/multiregion-overview.html) is a critical requirement, CockroachDB might be a suitable option.
+:::info
+ZITADEL v2 supports [CockroachDB](https://www.cockroachlabs.com/) and [PostgreSQL](https://www.postgresql.org/). Please refer to [the mirror guide](cli/mirror) to migrate to postgres.
+:::
The indexes for the database are optimized using load tests from [ZITADEL Cloud](https://zitadel.com),
which runs with PostgreSQL.
-If you identify problems with your CockroachDB during load tests that indicate that the indexes are not optimized,
+If you identify problems with your database during load tests that indicate that the indexes are not optimized,
please create an issue in our [github repository](https://github.com/zitadel/zitadel).
### Configure ZITADEL
@@ -129,12 +130,13 @@ Depending on your environment, you maybe would want to tweak some settings about
Database:
postgres:
Host: localhost
- Port: 26257
+ Port: 5432
Database: zitadel
//highlight-start
- MaxOpenConns: 20
+ MaxOpenConns: 10
+ MaxIdleConns: 5
MaxConnLifetime: 30m
- MaxConnIdleTime: 30m
+ MaxConnIdleTime: 5m
//highlight-end
Options: ""
```
@@ -192,9 +194,7 @@ The ZITADEL binary itself is stateless,
so there is no need for a special backup job.
Generally, for maintaining your database management system in production,
-please refer to the corresponding docs
-[for CockroachDB](https://www.cockroachlabs.com/docs/stable/recommended-production-settings.html)
-or [for PostgreSQL](https://www.postgresql.org/docs/current/admin.html).
+please refer to the corresponding docs [for PostgreSQL](https://www.postgresql.org/docs/current/admin.html).
## Data initialization
@@ -240,8 +240,7 @@ you might want to [limit usage and/or execute tasks on certain usage units and l
### General resource usage
-ZITADEL consumes around 512MB RAM and can run with less than 1 CPU core.
-The database consumes around 2 CPU under normal conditions and 6GB RAM with some caching to it.
+ZITADEL itself requires approximately 512MB of RAM and can operate with less than one CPU core. The database component, under typical conditions, utilizes about one CPU core per 100 requests per second (req/s) and 4GB of RAM per core, which includes some caching.
:::info Password hashing
Be aware of CPU spikes when hashing passwords. We recommend to have 4 CPU cores available for this purpose.
@@ -249,5 +248,6 @@ Be aware of CPU spikes when hashing passwords. We recommend to have 4 CPU cores
### Production HA cluster
-It is recommended to build a minimal high-availability with 3 Nodes with 4 CPU and 16GB memory each.
-Excluding non-essential services, such as log collection, metrics etc, the resources could be reduced to around 4 CPU and 8GB memory each.
+For a minimal high-availability setup, we recommend a cluster of 3 nodes, each with 4 CPU cores and 16GB of memory.
+
+If you exclude non-essential services like log collection and metrics, you can reduce the resources to approximately 4 CPU cores and 8GB of memory per node.
diff --git a/docs/docs/self-hosting/manage/productionchecklist.md b/docs/docs/self-hosting/manage/productionchecklist.md
index fb85557a23..c4f6491d82 100644
--- a/docs/docs/self-hosting/manage/productionchecklist.md
+++ b/docs/docs/self-hosting/manage/productionchecklist.md
@@ -19,7 +19,9 @@ To apply best practices to your production setup we created a step by step check
- [ ] Use serverless platform such as Knative or a hyperscaler equivalent (e.g. CloudRun from Google)
- [ ] Split `zitadel init` and `zitadel setup` for fast start-up times when [scaling](/docs/self-hosting/manage/updating_scaling) ZITADEL
- [ ] High Availability for database
- - [ ] Follow the [Production Checklist](https://www.cockroachlabs.com/docs/stable/recommended-production-settings.html) for CockroachDB if you selfhost the database or use [CockroachDB cloud](https://www.cockroachlabs.com/docs/cockroachcloud/create-an-account.html)
+ - [ ] Follow [this guide](https://www.postgresql.org/docs/current/high-availability.html) to set up the database.
+ - [ ] Configure logging
+ - [ ] Configure timeouts
- [ ] Configure backups on a regular basis for the database
- [ ] Test the restore scenarios before going live
- [ ] Secure database connections from outside your network and/or use an internal subnet for database connectivity
diff --git a/docs/docs/self-hosting/manage/reverseproxy/docker-compose.yaml b/docs/docs/self-hosting/manage/reverseproxy/docker-compose.yaml
index 989b620fef..c4a4f93fb2 100644
--- a/docs/docs/self-hosting/manage/reverseproxy/docker-compose.yaml
+++ b/docs/docs/self-hosting/manage/reverseproxy/docker-compose.yaml
@@ -121,7 +121,7 @@ services:
db:
restart: 'always'
- image: postgres:16-alpine
+ image: postgres:17-alpine
environment:
POSTGRES_PASSWORD: postgres
healthcheck:
diff --git a/docs/docs/self-hosting/manage/updating_scaling.md b/docs/docs/self-hosting/manage/updating_scaling.md
index 7b8c72bd32..046c8891d0 100644
--- a/docs/docs/self-hosting/manage/updating_scaling.md
+++ b/docs/docs/self-hosting/manage/updating_scaling.md
@@ -53,10 +53,10 @@ The command `zitadel init` ensures the database connection is ready to use for t
It just needs to be executed once over ZITADELs full life cycle,
when you install ZITADEL from scratch.
During `zitadel init`, for connecting to your database,
-ZITADEL uses the privileged and preexisting database user configured in `Database..Admin.Username`.
+ZITADEL uses the privileged and preexisting database user configured in `Database.postgres.Admin.Username`.
, `zitadel init` ensures the following:
- If it doesn’t exist already, it creates a database with the configured database name.
-- If it doesn’t exist already, it creates the unprivileged user use configured in `Database..User.Username`.
+- If it doesn’t exist already, it creates the unprivileged user use configured in `Database.postgres.User.Username`.
Subsequent phases connect to the database with this user's credentials only.
- If not already done, it grants the necessary permissions ZITADEL needs to the non privileged user.
- If they don’t exist already, it creates all schemas and some basic tables.
diff --git a/docs/docs/support/advisory/a10015.md b/docs/docs/support/advisory/a10015.md
new file mode 100644
index 0000000000..0945f40361
--- /dev/null
+++ b/docs/docs/support/advisory/a10015.md
@@ -0,0 +1,21 @@
+---
+title: Technical Advisory 10015
+---
+
+## Date
+
+Versions: >= v3.0.0
+
+Date: 2025-03-31
+
+## Description
+
+CockroachDB was initially chosen due to its distributed nature and SQL compatibility. However, over time, it became apparent that the operational complexity and specific compatibility issues outweighed the benefits for our use case. We decided to focus on PostgreSQL to simplify our infrastructure and leverage its mature ecosystem.
+
+## Impact
+
+Zitadel v3 requires PostgreSQL as a database. Therefore, Zitadel v3 will not start if CockroachDB is configured as the database.
+
+## Mitigation
+
+To upgrade your self-hosted deployment to Zitadel v3 migrate to PostgreSQL. Please refer to [this guide](/docs/self-hosting/manage/cli/mirror) to mirror the data to PostgreSQL before you deploy Zitadel v3.
\ No newline at end of file
diff --git a/docs/docs/support/technical_advisory.mdx b/docs/docs/support/technical_advisory.mdx
index 8805e2e1d8..0d8818c32c 100644
--- a/docs/docs/support/technical_advisory.mdx
+++ b/docs/docs/support/technical_advisory.mdx
@@ -226,6 +226,18 @@ We understand that these advisories may include breaking changes, and we aim to