From a065ddc706ebe49fbe324efe0b2af082ea4e1239 Mon Sep 17 00:00:00 2001 From: Fabi Date: Wed, 7 Feb 2024 12:44:20 +0100 Subject: [PATCH] docs: Make Examples and SDK Pages easier to understand (#7291) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: first attempt to restructure the sdks and examples to make it better understandable * docs: first attempt to restructure the sdks and examples to make it better understandable * docs: first attempt to restructure the sdks and examples to make it better understandable * docs: first attempt to restructure the sdks and examples to make it better understandable * docs: first attempt to restructure the sdks and examples to make it better understandable * docs: first attempt to restructure the sdks and examples to make it better understandable * docs: adding more example pages * docs: adding more example pages * docs: add all sdk/examples * docs: add tile component * docs: introduction page * docs: introduction page * docs: add react * docs: remove old sdk and example pages * docs: fix broken links * docs: fix broken links * styles * Update docs/docs/sdk-examples/introduction.mdx Co-authored-by: Livio Spring * Update docs/docs/sdk-examples/java.mdx Co-authored-by: Livio Spring * Update docs/docs/sdk-examples/python.mdx Co-authored-by: Livio Spring * Update docs/docs/sdk-examples/python.mdx Co-authored-by: Livio Spring * docs: review changes * docs: smaller tiles * docs: changes from go and java review * docs: correct python description * Update docs/docs/sdk-examples/python.mdx Co-authored-by: Livio Spring * Update docs/docs/sdk-examples/introduction.mdx Co-authored-by: Tim Möhlmann * Update docs/docs/sdk-examples/python.mdx Co-authored-by: Tim Möhlmann * docs: flask logo * flask, rust imgs * docs: flask logo * Update go.mdx * Update java.mdx * Update docs/docs/sdk-examples/flutter.mdx Co-authored-by: Livio Spring * Update docs/src/css/tile.module.css Co-authored-by: Livio Spring * docs: sidebar alphabetic * docs: sidebar alphabetic * docs: django logo --------- Co-authored-by: peintnermax Co-authored-by: Livio Spring Co-authored-by: Tim Möhlmann Co-authored-by: Stefan Benz --- README.md | 4 +- .../src/app/pages/home/home.component.html | 2 +- docs/docs/apis/introduction.mdx | 2 +- docs/docs/apis/openidoauth/authrequest.mdx | 2 +- docs/docs/examples/introduction.mdx | 227 ------------------ .../login/{django.mdx => python-django.mdx} | 0 docs/docs/examples/login/{vue.md => vue.mdx} | 0 docs/docs/examples/sdks.md | 109 --------- .../docs/examples/secure-api/nodejs-nestjs.md | 2 +- .../{django.mdx => python-django.mdx} | 0 .../guides/manage/customize/user-metadata.md | 4 +- docs/docs/sdk-examples/angular.mdx | 51 ++++ docs/docs/sdk-examples/flutter.mdx | 67 ++++++ docs/docs/sdk-examples/go.mdx | 105 ++++++++ docs/docs/sdk-examples/introduction.mdx | 187 +++++++++++++++ docs/docs/sdk-examples/java.mdx | 101 ++++++++ docs/docs/sdk-examples/nestjs.mdx | 56 +++++ docs/docs/sdk-examples/nextjs.mdx | 54 +++++ docs/docs/sdk-examples/python-django.mdx | 71 ++++++ docs/docs/sdk-examples/python-flask.mdx | 53 ++++ docs/docs/sdk-examples/react.mdx | 72 ++++++ docs/docs/sdk-examples/symfony.mdx | 53 ++++ docs/docs/sdk-examples/vue.mdx | 62 +++++ docs/sidebars.js | 64 +++-- docs/src/components/tile.jsx | 35 +++ docs/src/css/custom.css | 42 +++- docs/src/css/tile.module.css | 69 ++++++ docs/src/pages/index.js | 8 +- docs/static/img/tech/django.png | Bin 0 -> 15390 bytes docs/static/img/tech/elixir.svg | 1 + docs/static/img/tech/flask.svg | 1 + docs/static/img/tech/flasklight.svg | 1 + docs/static/img/tech/nestjs.svg | 1 + docs/static/img/tech/nextjs.svg | 2 +- docs/static/img/tech/nextjslight.svg | 2 +- docs/static/img/tech/passportjs.svg | 9 + docs/static/img/tech/rust.svg | 61 +++++ docs/static/img/tech/rustlight.svg | 61 +++++ 38 files changed, 1274 insertions(+), 367 deletions(-) delete mode 100644 docs/docs/examples/introduction.mdx rename docs/docs/examples/login/{django.mdx => python-django.mdx} (100%) rename docs/docs/examples/login/{vue.md => vue.mdx} (100%) delete mode 100644 docs/docs/examples/sdks.md rename docs/docs/examples/secure-api/{django.mdx => python-django.mdx} (100%) create mode 100644 docs/docs/sdk-examples/angular.mdx create mode 100644 docs/docs/sdk-examples/flutter.mdx create mode 100644 docs/docs/sdk-examples/go.mdx create mode 100644 docs/docs/sdk-examples/introduction.mdx create mode 100644 docs/docs/sdk-examples/java.mdx create mode 100644 docs/docs/sdk-examples/nestjs.mdx create mode 100644 docs/docs/sdk-examples/nextjs.mdx create mode 100644 docs/docs/sdk-examples/python-django.mdx create mode 100644 docs/docs/sdk-examples/python-flask.mdx create mode 100644 docs/docs/sdk-examples/react.mdx create mode 100644 docs/docs/sdk-examples/symfony.mdx create mode 100644 docs/docs/sdk-examples/vue.mdx create mode 100644 docs/src/components/tile.jsx create mode 100644 docs/src/css/tile.module.css create mode 100644 docs/static/img/tech/django.png create mode 100644 docs/static/img/tech/elixir.svg create mode 100644 docs/static/img/tech/flask.svg create mode 100644 docs/static/img/tech/flasklight.svg create mode 100644 docs/static/img/tech/nestjs.svg create mode 100644 docs/static/img/tech/passportjs.svg create mode 100644 docs/static/img/tech/rust.svg create mode 100644 docs/static/img/tech/rustlight.svg diff --git a/README.md b/README.md index 0efd6d697e..ea4a57d5c2 100644 --- a/README.md +++ b/README.md @@ -83,11 +83,11 @@ Learn more about the [pay-as-you-go pricing](https://zitadel.com/pricing). ### Example applications -Clone one of our [example applications](https://zitadel.com/docs/examples/introduction#clone-a-sample-project) or deploy them directly to Vercel. +Clone one of our [example applications](https://zitadel.com/docs/sdk-examples/introduction) or deploy them directly to Vercel. ### SDKs -Use our [SDKs](https://zitadel.com/docs/examples/sdks) for your favorite language and framework. +Use our [SDKs](https://zitadel.com/docs/sdk-examples/introduction) for your favorite language and framework. ## Why choose ZITADEL diff --git a/console/src/app/pages/home/home.component.html b/console/src/app/pages/home/home.component.html index 207251c40b..58fdbbd65b 100644 --- a/console/src/app/pages/home/home.component.html +++ b/console/src/app/pages/home/home.component.html @@ -56,7 +56,7 @@ {{ 'HOME.GETSTARTED.TITLE' | translate }} - +
- angular - - Angular - - Guide - - - - - react - - React - - Guide - - - - - vue - - Vue - - Guide - SDK - - - -### Native/mobile app - - - - - - - - - - - - - - - - -
LanguageExampleQuickstartSDK
- flutter - FlutterGuide
- -### Regular web app - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LanguageExampleQuickstartSDK
- nextjs - NextJSGuideNextAuth Provider
- golang - Go WebGuideSDK
- java - Java Spring Boot WebGuide
- php - Symfony PHP FrameworkGuide
- python - Python Flask Web
- python - Python Django WebGuide
- dotnet - ASP.NET Core MVC WebGuideSDK
- -## Backend - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LanguageExampleQuickstartSDK
- golang - GolangGuideSDK
- phyton - Python FlaskGuide
- phyton - Python DjangoGuide
- dotnet - ASP.NET Core WebAPIGuideSDK
- node - Node.js NestJS APIGuide
- php - PHP API
- java - Java Spring Boot APIGuide
- -## Other example applications - -- [B2B customer portal](https://github.com/zitadel/zitadel-nextjs-b2b): Showcase the use of personal access tokens in a B2B environment. Uses NextJS Framework. -- [Frontend with backend API](https://github.com/zitadel/example-quote-generator-app): A simple web application using a React front-end and a Python back-end API, both secured using ZITADEL -- [Introspection](https://github.com/zitadel/examples-api-access-and-token-introspection): Python examples for securing an API and invoking it as a service user -- [Fine-grained authorization](https://github.com/zitadel/example-fine-grained-authorization): Leverage actions, custom metadata, and claims for attribute-based access control - -Search for the "example" tag in our repository to [explore all examples](https://github.com/search?q=topic%3Aexamples+org%3Azitadel&type=repositories). diff --git a/docs/docs/examples/login/django.mdx b/docs/docs/examples/login/python-django.mdx similarity index 100% rename from docs/docs/examples/login/django.mdx rename to docs/docs/examples/login/python-django.mdx diff --git a/docs/docs/examples/login/vue.md b/docs/docs/examples/login/vue.mdx similarity index 100% rename from docs/docs/examples/login/vue.md rename to docs/docs/examples/login/vue.mdx diff --git a/docs/docs/examples/sdks.md b/docs/docs/examples/sdks.md deleted file mode 100644 index 90d307bbee..0000000000 --- a/docs/docs/examples/sdks.md +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: ZITADEL SDKs -sidebar_label: SDKs ---- - -On this page you find our official SDKs, links to supporting frameworks and providers, and resources to help with SDKs. -The SDKs wrap either our [gRPC or REST APIs](/docs/apis/introduction) to provide the client with User Authentication and -Management for resources. - -## ZITADEL SDKs - -| Language / Framework | Link Github | User Authentication | Manage resources | Notes | -| -------------------- | ------------------------------------------------------------- | --------------------------------------------------------- | ---------------- | ----------- | -| Go | [zitadel-go](https://github.com/zitadel/zitadel-go) | 🚧 [WIP](https://github.com/zitadel/zitadel-go/tree/next) | ✔️ | `official` | -| Vue | [zitadel-vue](https://github.com/zitadel/zitadel-vue) | ✔️ | ❌ | `official` | -| React | [zitadel-react](https://github.com/zitadel/zitadel-react) | ✔️ | ❌ | `official` | -| .NET | [zitadel-net](https://github.com/smartive/zitadel-net) | ✔️ | ✔️ | `community` | -| Elixir | [zitadel_api](https://github.com/jshmrtn/zitadel_api) | ✔️ | ✔️ | `community` | -| NodeJS | [@zitadel/node](https://www.npmjs.com/package/@zitadel/node) | ❌ | ✔️ | `community` | -| Dart | [zitadel-dart](https://github.com/smartive/zitadel-dart) | ❌ | ✔️ | `community` | -| Rust | [zitadel-rust](https://github.com/smartive/zitadel-rust) | ✔️ | ✔️ | `community` | -| JVM | 🚧 [WIP](https://github.com/zitadel/zitadel/discussions/3650) | ❓ | ❓ | TBD | -| Python | 🚧 [WIP](https://github.com/zitadel/zitadel/issues/3675) | ❓ | ❓ | TBD | - -## Missing SDK - -Is your language/framework missing? Fear not, you can generate your gRPC API Client with ease. - -1. Make sure to install [buf](https://buf.build/docs/installation/) -2. Create a `buf.gen.yaml` and configure the [plugins](https://buf.build/plugins) you need -3. Run `buf generate https://github.com/zitadel/zitadel#format=git,tag=v2.23.1` (change the versions to your needs) - -Let us make an example with Ruby. Any other supported language by buf will work as well. Consult -the [buf plugin registry](https://buf.build/plugins) for more ideas. - -### Example with Ruby - -With gRPC we usually need to generate the client stub and the messages/types. This is why we need two plugins. -The plugin `grpc/ruby` generates the client stub and the plugin `protocolbuffers/ruby` takes care of the messages/types. - -```yaml -version: v1 -plugins: - - plugin: buf.build/grpc/ruby - out: gen - - plugin: buf.build/protocolbuffers/ruby - out: gen -``` - -If you now run `buf generate https://github.com/zitadel/zitadel#format=git,tag=v2.23.1` in the folder where -your `buf.gen.yaml` is located you should see the folder `gen` appear. - -If you run `ls -la gen/zitadel/` you should see something like this: - -```bash -ffo@ffo-pc:~/git/zitadel/ruby$ ls -la gen/zitadel/ -total 704 -drwxr-xr-x 2 ffo ffo 4096 Apr 11 16:49 . -drwxr-xr-x 3 ffo ffo 4096 Apr 11 16:49 .. --rw-r--r-- 1 ffo ffo 4397 Apr 11 16:49 action_pb.rb --rw-r--r-- 1 ffo ffo 141097 Apr 11 16:49 admin_pb.rb --rw-r--r-- 1 ffo ffo 25151 Apr 11 16:49 admin_services_pb.rb --rw-r--r-- 1 ffo ffo 6537 Apr 11 16:49 app_pb.rb --rw-r--r-- 1 ffo ffo 1134 Apr 11 16:49 auth_n_key_pb.rb --rw-r--r-- 1 ffo ffo 32881 Apr 11 16:49 auth_pb.rb --rw-r--r-- 1 ffo ffo 6896 Apr 11 16:49 auth_services_pb.rb --rw-r--r-- 1 ffo ffo 1571 Apr 11 16:49 change_pb.rb --rw-r--r-- 1 ffo ffo 2488 Apr 11 16:49 event_pb.rb --rw-r--r-- 1 ffo ffo 14782 Apr 11 16:49 idp_pb.rb --rw-r--r-- 1 ffo ffo 5031 Apr 11 16:49 instance_pb.rb --rw-r--r-- 1 ffo ffo 223348 Apr 11 16:49 management_pb.rb --rw-r--r-- 1 ffo ffo 44402 Apr 11 16:49 management_services_pb.rb --rw-r--r-- 1 ffo ffo 3020 Apr 11 16:49 member_pb.rb --rw-r--r-- 1 ffo ffo 855 Apr 11 16:49 message_pb.rb --rw-r--r-- 1 ffo ffo 1445 Apr 11 16:49 metadata_pb.rb --rw-r--r-- 1 ffo ffo 2370 Apr 11 16:49 object_pb.rb --rw-r--r-- 1 ffo ffo 621 Apr 11 16:49 options_pb.rb --rw-r--r-- 1 ffo ffo 4425 Apr 11 16:49 org_pb.rb --rw-r--r-- 1 ffo ffo 8538 Apr 11 16:49 policy_pb.rb --rw-r--r-- 1 ffo ffo 8223 Apr 11 16:49 project_pb.rb --rw-r--r-- 1 ffo ffo 1022 Apr 11 16:49 quota_pb.rb --rw-r--r-- 1 ffo ffo 5872 Apr 11 16:49 settings_pb.rb --rw-r--r-- 1 ffo ffo 20985 Apr 11 16:49 system_pb.rb --rw-r--r-- 1 ffo ffo 4784 Apr 11 16:49 system_services_pb.rb --rw-r--r-- 1 ffo ffo 28759 Apr 11 16:49 text_pb.rb --rw-r--r-- 1 ffo ffo 24170 Apr 11 16:49 user_pb.rb --rw-r--r-- 1 ffo ffo 13568 Apr 11 16:49 v1_pb.rb -``` - -Import these files into your project to start interacting with ZITADEL's APIs. - -## More - -While we are not actively maintaining the following projects, it is worth checking out if you're interested in exploring -ZITADEL in different programming languages or frameworks. - -- [NodeJS passport](https://github.com/buehler/node-passport-zitadel) authentication helper -- [NextAuth Provider for ZITADEL](https://next-auth.js.org/providers/zitadel) - -If we do not provide an example, SDK or guide, we strongly recommend using existing authentication libraries for your -language or framework instead of building your own. -Certified libraries have undergone rigorous testing and validation to ensure high security and reliability. -There are many recommended libraries available, this saves time and ensures that users' data is well-protected. - -You might want to check out the following links to find a good library: - -- [awesome-auth](https://github.com/casbin/awesome-auth) -- [OpenID General References](https://openid.net/developers/libraries/) -- [OpenID certified developer tools](https://openid.net/certified-open-id-developer-tools/) diff --git a/docs/docs/examples/secure-api/nodejs-nestjs.md b/docs/docs/examples/secure-api/nodejs-nestjs.md index 4984193108..13c2191140 100644 --- a/docs/docs/examples/secure-api/nodejs-nestjs.md +++ b/docs/docs/examples/secure-api/nodejs-nestjs.md @@ -1,6 +1,6 @@ --- title: ZITADEL with Node.js -sidebar_label: Node.js +sidebar_label: NestJS --- # ZITADEL with Node.js (NestJS) diff --git a/docs/docs/examples/secure-api/django.mdx b/docs/docs/examples/secure-api/python-django.mdx similarity index 100% rename from docs/docs/examples/secure-api/django.mdx rename to docs/docs/examples/secure-api/python-django.mdx diff --git a/docs/docs/guides/manage/customize/user-metadata.md b/docs/docs/guides/manage/customize/user-metadata.md index b4aff8fcbf..cc051a1c51 100644 --- a/docs/docs/guides/manage/customize/user-metadata.md +++ b/docs/docs/guides/manage/customize/user-metadata.md @@ -24,7 +24,7 @@ You can do so by using [Console](../console/users) or [setting user metadata](/d Most of the methods below require you to login with the correct user while setting some scopes. Make sure you pick the right user when logging into the test application. -Use the [OIDC authentication request playground](/docs/apis/openidoauth/authrequest) or the configuration of an [example client](/docs/examples/introduction) to set the required scopes and receive a valid access token. +Use the [OIDC authentication request playground](/docs/apis/openidoauth/authrequest) or the configuration of an [example client](/docs/sdk-examples/introduction) to set the required scopes and receive a valid access token. :::info Getting a token In case you want to test out different settings configure an application with code flow (PKCE). @@ -157,7 +157,7 @@ You can use the authentication service to request and search for the user's meta The introspection endpoint and the token endpoint in the examples above do not require a special scope to access. Yet when accessing the authentication service, you need to pass the [reserved scope](/docs/apis/openidoauth/scopes#reserved-scopes) `urn:zitadel:iam:org:project:id:zitadel:aud` along with the authentication request. This scope allows the user to access ZITADEL's APIs, specifically the authentication API that we need for this method. -Use the [OIDC authentication request playground](/docs/apis/openidoauth/authrequest) or the configuration of an [example client](/docs/examples/introduction) to set the required scopes and receive a valid access token. +Use the [OIDC authentication request playground](/docs/apis/openidoauth/authrequest) or the configuration of an [example client](/docs/sdk-examples/introduction) to set the required scopes and receive a valid access token. :::note Invalid audience If you get the error "invalid audience (APP-Zxfako)", then you need to add the reserved scope `urn:zitadel:iam:org:project:id:zitadel:aud` to your authentication request. diff --git a/docs/docs/sdk-examples/angular.mdx b/docs/docs/sdk-examples/angular.mdx new file mode 100644 index 0000000000..5211a8494c --- /dev/null +++ b/docs/docs/sdk-examples/angular.mdx @@ -0,0 +1,51 @@ +--- +title: Angular +sidebar_label: Angular +--- + + + + + + +
+ angular logo + + Angular is a popular JavaScript framework for building single-page applications (SPAs) that is known for its two-way data binding, dependency injection, and modular architecture. + Integrate authentication to your Angular application easily by using the zitadel-angular Example. +
+ +### Resources +- [Angular Example Application with ZITADEL Login](https://github.com/zitadel/zitadel-angular) +- [Step-By-Step Guide](/docs/examples/login/angular) +- [ZITADEL Console](https://github.com/zitadel/zitadel/tree/main/console) is built with Angular and can also be used as a reference + + +### Angular SDK + +ZITADEL does not provide an Angular specific SDK. +But you can integrate ZITADEL to your application by using any OIDC Library such as [angular-oauth2-oidc](https://github.com/manfredsteyer/angular-oauth2-oidc). + +Check out our [Example Application](/docs/sdk-examples/angular#example-application) + +### Example Application + +The [zitadel-angular](https://github.com/zitadel/zitadel-angular) repository includes an Example Application ready to start and show how an Angular application looks like with integrated ZITADEL Login. + +What does the Example include: +- Home Page with Login Button +- Authenticating user with OIDC PKCE Flow +- Private Page: Shows user information of authenticated user, only accessible after login +- Logout + +### Step-By-Step Guide + +The [Step-By-Step Guide](/docs/examples/login/angular) leads you through the whole process from configuring the right application in ZITADEL to a ready application with integrated Login. + +After completing the Step-By-Step Guide you will have: +1. Example Web Application with integrated ZITADEL Login +2. Example page accessible by authenticated user showing retrieved user information +3. Logout +4. Correct setup for your application in ZITADEL + +![App in console](/img/angular/app-screen.png) diff --git a/docs/docs/sdk-examples/flutter.mdx b/docs/docs/sdk-examples/flutter.mdx new file mode 100644 index 0000000000..c0b19429ac --- /dev/null +++ b/docs/docs/sdk-examples/flutter.mdx @@ -0,0 +1,67 @@ +--- +title: Flutter +sidebar_label: Flutter +--- + + + + + + +
+ flutter logo + + Flutter is a cross-platform mobile app development framework that allows developers to build native iOS and Android apps using a single codebase. + Integrate authentication to your Flutter App easily by using the zitadel-flutter Example. +
+ +### Resources +- [Flutter Example Application Repository](https://github.com/zitadel/zitadel_flutter) +- [Step-By-Step Guide](/docs/examples/login/flutter) to create your Flutter App with ZITADEL Login +- [Dart Client Library for ZITADEL](https://github.com/smartive/zitadel-dart) + +### Flutter SDK + +ZITADEL doesn't provide a specific Flutter SDK for authentication in your Web/Mobile App. +You can use any OIDC Library such as [package:oidc](https://pub.dev/packages/oidc). +For Mobile Apps we recommend [Flutter AppAuth](https://pub.dev/packages/flutter_appauth). + +Check out our [Example Application](/docs/sdk-examples/flutter#example-application). + +Additionally, you can use [smartive/zitadel-dart](https://github.com/smartive/zitadel-dart) for user and resource management. +- Manage Resources through ZITADEL APIs + - Authenticate Service User + - Generated gRPC Clients for integrating ZITADEL API + - User, Organization, Project, etc. Management + +:::note +This library is built by our community. +::: + +### Example Application + +The [zitadel-flutter](https://github.com/zitadel/zitadel_flutter) repository includes an Example Application ready to start and show how an Flutter application looks like with integrated ZITADEL Login. + +What does the Example include: +- Home Page with Login Button +- Authenticating user with OIDC PKCE Flow +- Private Page: Only accessible after login + +### Step-By-Step Guide + +The [Step-By-Step Guide](/docs/examples/login/flutter) leads you through the whole process from configuring the right application in ZITADEL to a ready application with integrated Login. + +After completing the Step-By-Step Guide you will have: +1. Example Mobile App with integrated ZITADEL Login +2. Example page accessible by authenticated user +3. Correct setup for your application in ZITADEL + +
+ Unauthenticated + Flutter Authenticated +
+ +
+ Unauthenticated + Flutter Authenticated +
diff --git a/docs/docs/sdk-examples/go.mdx b/docs/docs/sdk-examples/go.mdx new file mode 100644 index 0000000000..77e11f37d9 --- /dev/null +++ b/docs/docs/sdk-examples/go.mdx @@ -0,0 +1,105 @@ +--- +title: Go +sidebar_label: Go +--- + + + + + + +
+ go logo + + Go is an open-source, compiled programming language that is known for its simplicity, efficiency, and concurrency capabilities. + Get started integrating authentication to your Go Application by checking out our zitadel-go SDK. +
+ + +### Resources +- [Example App Repository](https://github.com/zitadel/zitadel-go) +- [Go SDK](https://github.com/zitadel/zitadel-go) +- [Web APP Step-By-Step Guide](/docs/examples/login/go) +- [API APP Step-By-Step Guide](/docs/examples/secure-api/go) +- [Go OIDC Library](https://github.com/zitadel/oidc) + +### Go SDK + +The [zitadel-go](https://github.com/zitadel/zitadel-go) SDK is a wrapper around the [zitadel/oidc](https://github.com/zitadel/oidc) to integrate Login into your Web App and abstracts the handling of specific configurations for ZITADEL. +Additionally secure your business APIs and handle permission checks for your users. +Last part is the integration of the ZITADEL APIs to handle user and resource management. + +The following features are covered by the SDK: +- Authentication in your Web App + - Authenticate your user with ZITADEL using OIDC + - Requesting ZITADEL userinfo endpoint to get user data + - Refresh Token + - Requesting User Roles from userinfo + - Check if user has specified role + - Logout +- Secure your APIs + - Authorization Check using OAuth2 Introspection + - Check User Roles on Endpoint +- Manage Resources through ZITADEL APIs + - Authenticate Service User + - Generated gRPC Clients for integrating ZITADEL API + - User, Organization, Project, etc. Management + +The goal is to extend the SDK over the time with the following features: +- Build your own login UI using our Session API + +### Go Examples + +You can find different examples for building your Go application in the following package of the repository: +[zitadel-go/example](https://github.com/zitadel/zitadel-go/tree/next/example) + +#### Web Application Example + +What does the Web Application Example include: +- Home Page with Login Button +- Authenticating user with OIDC PKCE Flow +- Public Page: Accessible without authentication +- Private Page: Shows user information of authenticated user, only accessible after login +- Logout + +[Example Web App](https://github.com/zitadel/zitadel-go/tree/next/example/app) + +#### API Application Example + +What does the API Application Example include: +- REST API Application secured with Spring Security and OAuth2 +- Public Endpoint: Accessible without authentication +- Private Endpoint: Accessible with a token +- Administrator Endpoint: Accessible with a token of a user with admin role + +[Example API App](https://github.com/zitadel/zitadel-go/tree/next/example/api/http) + +### Step-By-Step Guide + +For Go we do have two different Step-By-Step Guides. +One to create your web application with integrated login and one to create your API with permission checks for calling users. +The guides lead you through the whole process from configuring the right application in ZITADEL to a ready application with integrated login or authentication checks. + +#### Web Application Guide + +After completing the Step-By-Step Guide you will have: +1. Example Web Application with integrated ZITADEL Login +2. Example page accessible by authenticated user showing retrieved user information +4. Logout +5. Correct setup for your application in ZITADEL + +[Web APP Step-By-Step Guide](/docs/examples/login/go) + +![Home Page](/img/go/app-home.png) +![Profile Page](/img/go/app-profile.png) + +#### API Application Guide + +After completing the Step-By-Step Guide you will have: +1. Example REST API checking tokens against ZITADEL with OAuth2 +2. Public Endpoint accessible by any user +3. Private Endpoint accessible by authenticated user +4. Private Endpoint accessible by user with role 'admin' +5. Correct setup for your application in ZITADEL + +[API APP Step-By-Step Guide](/docs/examples/secure-api/go) diff --git a/docs/docs/sdk-examples/introduction.mdx b/docs/docs/sdk-examples/introduction.mdx new file mode 100644 index 0000000000..5ee006c6c5 --- /dev/null +++ b/docs/docs/sdk-examples/introduction.mdx @@ -0,0 +1,187 @@ +--- +title: Introduction +sidebar_label: Introduction +--- + +You can integrate ZITADEL quickly into your application and be up and running within minutes. +To achieve your goals as fast as possible, we provide you with SDKs, Example Repositories and Guides. + +The SDKs and Integration depend on the framework and language you are using. + +import { Tile } from "../../src/components/tile"; + +### Resources + +
+ + + + + + + + + + + + + + + + + + + +
+ +### OIDC Libraries + +OIDC is a standard for authentication and most languages and frameworks do provide a OIDC library which can be easily integrated to your application. +If we do not provide an specific example, SDK or guide, we strongly recommend using existing authentication libraries for your +language or framework instead of building your own. +Certified libraries have undergone rigorous testing and validation to ensure high security and reliability. +There are many recommended libraries available, this saves time and ensures that users' data is well-protected. + +You might want to check out the following links to find a good library: + +- [awesome-auth](https://github.com/casbin/awesome-auth) +- [OpenID General References](https://openid.net/developers/libraries/) +- [OpenID certified developer tools](https://openid.net/certified-open-id-developer-tools/) + +### Other example applications + +- [B2B customer portal](https://github.com/zitadel/zitadel-nextjs-b2b): Showcase the use of personal access tokens in a B2B environment. Uses NextJS Framework. +- [Frontend with backend API](https://github.com/zitadel/example-quote-generator-app): A simple web application using a React front-end and a Python back-end API, both secured using ZITADEL +- [Introspection](https://github.com/zitadel/examples-api-access-and-token-introspection): Python examples for securing an API and invoking it as a service user +- [Fine-grained authorization](https://github.com/zitadel/example-fine-grained-authorization): Leverage actions, custom metadata, and claims for attribute-based access control + +Search for the "example" tag in our repository to [explore all examples](https://github.com/search?q=topic%3Aexamples+org%3Azitadel&type=repositories). + +### Missing SDK + +Is your language/framework missing? Fear not, you can generate your gRPC API Client with ease. + +1. Make sure to install [buf](https://buf.build/docs/installation/) +2. Create a `buf.gen.yaml` and configure the [plugins](https://buf.build/plugins) you need +3. Run `buf generate https://github.com/zitadel/zitadel#format=git,tag=v2.23.1` (change the versions to your needs) + +Let us make an example with Ruby. Any other supported language by buf will work as well. Consult +the [buf plugin registry](https://buf.build/plugins) for more ideas. + +#### Example with Ruby + +With gRPC we usually need to generate the client stub and the messages/types. This is why we need two plugins. +The plugin `grpc/ruby` generates the client stub and the plugin `protocolbuffers/ruby` takes care of the messages/types. + +```yaml +version: v1 +plugins: + - plugin: buf.build/grpc/ruby + out: gen + - plugin: buf.build/protocolbuffers/ruby + out: gen +``` + +If you now run `buf generate https://github.com/zitadel/zitadel#format=git,tag=v2.23.1` in the folder where +your `buf.gen.yaml` is located you should see the folder `gen` appear. + +If you run `ls -la gen/zitadel/` you should see something like this: + +```bash +ffo@ffo-pc:~/git/zitadel/ruby$ ls -la gen/zitadel/ +total 704 +drwxr-xr-x 2 ffo ffo 4096 Apr 11 16:49 . +drwxr-xr-x 3 ffo ffo 4096 Apr 11 16:49 .. +-rw-r--r-- 1 ffo ffo 4397 Apr 11 16:49 action_pb.rb +-rw-r--r-- 1 ffo ffo 141097 Apr 11 16:49 admin_pb.rb +-rw-r--r-- 1 ffo ffo 25151 Apr 11 16:49 admin_services_pb.rb +-rw-r--r-- 1 ffo ffo 6537 Apr 11 16:49 app_pb.rb +-rw-r--r-- 1 ffo ffo 1134 Apr 11 16:49 auth_n_key_pb.rb +-rw-r--r-- 1 ffo ffo 32881 Apr 11 16:49 auth_pb.rb +-rw-r--r-- 1 ffo ffo 6896 Apr 11 16:49 auth_services_pb.rb +-rw-r--r-- 1 ffo ffo 1571 Apr 11 16:49 change_pb.rb +-rw-r--r-- 1 ffo ffo 2488 Apr 11 16:49 event_pb.rb +-rw-r--r-- 1 ffo ffo 14782 Apr 11 16:49 idp_pb.rb +-rw-r--r-- 1 ffo ffo 5031 Apr 11 16:49 instance_pb.rb +-rw-r--r-- 1 ffo ffo 223348 Apr 11 16:49 management_pb.rb +-rw-r--r-- 1 ffo ffo 44402 Apr 11 16:49 management_services_pb.rb +-rw-r--r-- 1 ffo ffo 3020 Apr 11 16:49 member_pb.rb +-rw-r--r-- 1 ffo ffo 855 Apr 11 16:49 message_pb.rb +-rw-r--r-- 1 ffo ffo 1445 Apr 11 16:49 metadata_pb.rb +-rw-r--r-- 1 ffo ffo 2370 Apr 11 16:49 object_pb.rb +-rw-r--r-- 1 ffo ffo 621 Apr 11 16:49 options_pb.rb +-rw-r--r-- 1 ffo ffo 4425 Apr 11 16:49 org_pb.rb +-rw-r--r-- 1 ffo ffo 8538 Apr 11 16:49 policy_pb.rb +-rw-r--r-- 1 ffo ffo 8223 Apr 11 16:49 project_pb.rb +-rw-r--r-- 1 ffo ffo 1022 Apr 11 16:49 quota_pb.rb +-rw-r--r-- 1 ffo ffo 5872 Apr 11 16:49 settings_pb.rb +-rw-r--r-- 1 ffo ffo 20985 Apr 11 16:49 system_pb.rb +-rw-r--r-- 1 ffo ffo 4784 Apr 11 16:49 system_services_pb.rb +-rw-r--r-- 1 ffo ffo 28759 Apr 11 16:49 text_pb.rb +-rw-r--r-- 1 ffo ffo 24170 Apr 11 16:49 user_pb.rb +-rw-r--r-- 1 ffo ffo 13568 Apr 11 16:49 v1_pb.rb +``` + +Import these files into your project to start interacting with ZITADEL's APIs. diff --git a/docs/docs/sdk-examples/java.mdx b/docs/docs/sdk-examples/java.mdx new file mode 100644 index 0000000000..e7afb5188b --- /dev/null +++ b/docs/docs/sdk-examples/java.mdx @@ -0,0 +1,101 @@ +--- +title: Java Spring Boot +sidebar_label: Java Spring Boot +--- + + + + + + +
+ java logo + + Java is a general-purpose programming language designed for object-oriented programming. + Spring Security is used to protect your applications from unauthorized access, protect sensitive data, and enforce access control policies. + Get started integrating authentication to your Java Web App or API by checking out our zitadel-java Example +
+ + +### Resources +- [Example App Repository with Spring Security](https://github.com/zitadel/zitadel-java) +- [Example Web App with Spring Security](https://github.com/zitadel/zitadel-java/tree/main/web) +- [Example API App with Spring Security](https://github.com/zitadel/zitadel-java/tree/main/api) +- [Web APP Step-By-Step Guide](/docs/examples/login/java-spring) +- [API APP Step-By-Step Guide](/docs/examples/secure-api/java-spring) + +### Java SDK + +Java Spring Security is a widely used and common framework to integrate Authentication and Authorization into your Applications. +As of this at the moment there is no specific ZITADEL SDK, but we do show you how to integrate ZITADEL with Java Spring Security. +You can use this for both your Web as for your API Applications. + +The following features are covered by Java Spring Security: +- Authenticate your user using OIDC +- Requesting ZITADEL userinfo endpoint to get user data +- Refresh Token +- Requesting User Roles from userinfo +- Check if user has specified role +- Logout + +The goal is to have a ZITADEL Java SDK in the future which will cover the following: +- Wrapper around Java Spring Security +- Authentication with OIDC +- Authorization and checking Rolls +- Integrate ZITADEL APIs to read and manage resources +- Integrate ZITADEL Session API to create your own login UI + +### Java Examples + +#### Web Application Example + +What does the Web Application Example include: +- Home Page with Login Button +- Authenticating user with OIDC PKCE Flow +- Public Page: Accessible without authentication +- Private Page: Shows user information of authenticated user, only accessible after login +- Task Page: Only accessible after login and uses the API example. Requires the admin role for the application for some interaction. +- Logout + +[Example Web App with Spring Security](https://github.com/zitadel/zitadel-java/web) + +#### API Application Example + +What does the API Application Example include: +- REST API Application secured with Spring Security and OAuth2 +- Public Endpoint: Accessible without authentication +- Private Endpoint: Accessible with a token +- Administrator Endpoint: Accessible with a token of a user with admin role + +[Example API App with Spring Security](https://github.com/zitadel/zitadel-java/api) + +### Step-By-Step Guide + +For Java Spring we do have two different Step-By-Step Guides. +One to create your web application with integrated login and one to create your API with permission checks for calling users. +The guides lead you through the whole process from configuring the right application in ZITADEL to a ready application with integrated login or authentication checks. + +#### Web Application Guide + +After completing the Step-By-Step Guide you will have: +1. Example Web Application with integrated ZITADEL Login +2. Example page accessible by authenticated user showing retrieved user information +3. Example page accessible by authenticated user showing task list + - Task list can be read by authenticated user + - New tasks can be created by user with admin role +4. Logout +5. Correct setup for your application in ZITADEL + +[Web APP Step-By-Step Guide](/docs/examples/login/java-spring) +![Profile Page](/img/java-spring/app-profile.png) + +#### API Application Guide + +After completing the Step-By-Step Guide you will have: +1. Example REST API checking tokens against ZITADEL with OAuth2 +2. Public Endpoint accessible by any user +3. Private Endpoint accessible by authenticated user +4. Private Endpoint accessible by user with role 'admin' +5. Correct setup for your application in ZITADEL + +[API APP Step-By-Step Guide](/docs/examples/secure-api/java-spring) diff --git a/docs/docs/sdk-examples/nestjs.mdx b/docs/docs/sdk-examples/nestjs.mdx new file mode 100644 index 0000000000..9238d823f7 --- /dev/null +++ b/docs/docs/sdk-examples/nestjs.mdx @@ -0,0 +1,56 @@ +--- +title: NestJS +sidebar_label: NestJS +--- + + + + + + +
+ nest js logo + + NestJS is a comprehensive and well-maintained TypeScript-based framework for building large-scale, scalable, and maintainable Node.js applications. + Get started integrating ZITADEL to your NestJS API by checking out the zitadel-nodejs-nestjs Example. +
+ + +### Resources +- [Example App Repository](https://github.com/ehwplus/zitadel-nodejs-nestjs) +- [Step-By-Step Guide](/docs/examples/secure-api/nodejs-nestjs) +- [Passport.js](https://github.com/buehler/node-passport-zitadel) for integrating authentication +- [Node.js gRPC Client Library](https://www.npmjs.com/package/@zitadel/node) for user and resource management + +### SDK + +ZITADEL doesn't provide a specific Nestjs SDK. You can use [passport-zitadel](https://github.com/buehler/node-passport-zitadel) for the authentication part. + +Check out the [Example Application](/docs/sdk-examples/nestjs#example-application). + +Additionally, you can use [@zitadel/node](https://www.npmjs.com/package/@zitadel/node) for user and resource management. +- Manage Resources through ZITADEL APIs +- Authenticate Service User +- Generated gRPC Clients for integrating ZITADEL API +- User, Organization, Project, etc. Management + +:::note +This library is built by our community. +::: + +### Example Application + +What does the API Application Example include: +- REST API Application secured with Spring Security and OAuth2 +- Private Endpoint: Accessible with a token + +[Example API Application](https://github.com/ehwplus/zitadel-nodejs-nestjs) + +### Step-By-Step Guide + +After completing the Step-By-Step Guide you will have: +1. Example REST API checking tokens against ZITADEL with OAuth2 +2. Private Endpoint accessible by authenticated user +3. Correct setup for your application in ZITADEL + +[API APP Step-By-Step Guide](/docs/examples/secure-api/nodejs-nestjs) \ No newline at end of file diff --git a/docs/docs/sdk-examples/nextjs.mdx b/docs/docs/sdk-examples/nextjs.mdx new file mode 100644 index 0000000000..8aebbc33f7 --- /dev/null +++ b/docs/docs/sdk-examples/nextjs.mdx @@ -0,0 +1,54 @@ +--- +title: Next.js +sidebar_label: Next.js +--- + + + + + + +
+ next js logo + next js logo + + Next.js is a React-based framework that provides a powerful and flexible set of tools for building high-performance, SEO-friendly web applications. + Get started integrating authentication to your Next.js Application by checking out our zitadel-nextjs Example. +
+ + +### Resources +- [Example App Repository](https://github.com/zitadel/zitadel-nextjs) +- [Step-By-Step Guide](/docs/examples/login/nextjs) +- [B2B customer portal](https://github.com/zitadel/zitadel-nextjs-b2b): Showcase the use of personal access tokens in a B2B environment built with Next.js + +### SDK + +ZITADEL does not provide a Next.js specific SDK. +However, for integrating authentication into your Next.js Application you can use [NextAuth ZITADEL Provider](https://next-auth.js.org/providers/zitadel) + +Check out our [Example Application](/docs/sdk-examples/nextjs#example-application) + + +### Example Application + +The [zitadel-nextjs](https://github.com/zitadel/zitadel-nextjs) repository includes an Example Application ready to start and show how a Next.js application looks like with integrated ZITADEL Login. + +What does the Example include: +TODO: ?? Update with correct infos +- Home Page with Login Button +- Authenticating user with OIDC PKCE Flow +- Private Page: Shows user information of authenticated user, only accessible after login +- Logout + +### Step-By-Step Guide + +The [Step-By-Step Guide](/docs/examples/login/nextjs) leads you through the whole process from configuring the right application in ZITADEL to a ready application with integrated Login. + +After completing the Step-By-Step Guide you will have: +TODO: ?? Updated with correct infos +1. Example Web Application with integrated ZITADEL Login +2. Example page accessible by authenticated user showing retrieved user information +3. Logout +4. Correct setup for your application in ZITADEL + diff --git a/docs/docs/sdk-examples/python-django.mdx b/docs/docs/sdk-examples/python-django.mdx new file mode 100644 index 0000000000..8c7b3a8898 --- /dev/null +++ b/docs/docs/sdk-examples/python-django.mdx @@ -0,0 +1,71 @@ +--- +title: Python Django +sidebar_label: Python Django +--- + + + + + + +
+ phyton logo + + Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. + Get started integrating authentication to your Django API Application by checking out our example-python-django-oauth or your Django Web application by checking out our example-python-django-oidc Example. +
+ + +### Resources +- [Example API App Repository](https://github.com/zitadel/example-python-django-oauth) +- [API App Step-By-Step Guide](/docs/examples/secure-api/python-django) +- [Example Web App Repository](https://github.com/zitadel/example-python-django-oidc) +- [Web App Step-By-Step Guide](/docs/examples/login/python-django) + +### Django SDK + +ZITADEL does not provide a Python Django specific SDK. +But you can integrate ZITADEL to your application by using any OIDC Library such as [mozilla-django-oidc](https://github.com/mozilla/mozilla-django-oidc) or [authlib](https://github.com/lepture/authlib). + +### Examples Application + +What does the API Application Example include: +- REST API Application secured with OAuth2 +- Public Endpoint: Accessible without authentication +- Private Endpoint: Accessible with a token +- Administrator Endpoint: Accessible with a token of a user with admin role + +[Example API App](https://github.com/zitadel/example-python-django-oauth) + +What does the Web Application Example include: +1. Example Web Application with integrated ZITADEL Login +2. Example page accessible by authenticated user showing retrieved user information +3. Example page accessible by authenticated user showing polls + - Votes for polls can only be done if authenticated + - New polls can be created by user with admin role +4. Logout +5. Correct setup for your application in ZITADEL + +[Example Web App](https://github.com/zitadel/example-python-django-oidc) + +### Step-By-Step Guide + +After completing the Step-By-Step Guide for an API you will have: +1. Example REST API checking tokens against ZITADEL with OAuth2 +2. Public Endpoint accessible by any user +3. Private Endpoint accessible by authenticated user +4. Private Endpoint accessible by user with role 'admin' +5. Correct setup for your application in ZITADEL + +[API App Step-By-Step Guide](/docs/examples/secure-api/python-django) + +After completing the Step-By-Step Guide for an Web application you will have: +1. Example Web Application with integrated ZITADEL Login +2. Example page accessible by authenticated user showing retrieved user information +3. Example page accessible by authenticated user showing polls + - Votes for polls can only be done if authenticated + - New polls can be created by user with admin role +4. Logout +5. Correct setup for your application in ZITADEL + +[Web App Step-By-Step Guide](/docs/examples/login/python-django) \ No newline at end of file diff --git a/docs/docs/sdk-examples/python-flask.mdx b/docs/docs/sdk-examples/python-flask.mdx new file mode 100644 index 0000000000..d443d0b260 --- /dev/null +++ b/docs/docs/sdk-examples/python-flask.mdx @@ -0,0 +1,53 @@ +--- +title: Python Flask +sidebar_label: Python Flask +--- + + + + + + +
+ phyton logo + phyton logo + + Flask is a lightweight and easy-to-use microframework for Python web development. + Get started integrating authentication to your Flask API Application by checking out our example-api-python3-flask Example. +
+ + +### Resources +- [Example App Repository](https://github.com/zitadel/example-api-python3-flask) +- [API APP Step-By-Step Guide](/docs/examples/secure-api/python-flask) +- [Frontend with backend API](https://github.com/zitadel/example-quote-generator-app): A simple web application using a React front-end and a Python back-end API, both secured using ZITADEL +- [Fine-grained authorization](https://github.com/zitadel/example-fine-grained-authorization): Leverage actions, custom metadata, and claims for attribute-based access control + +### Flask SDK + +ZITADEL does not provide a Python Flask specific SDK. +But you can integrate ZITADEL to your application by using any OIDC Library such as [angular-oauth2-oidc](https://github.com/manfredsteyer/angular-oauth2-oidc). + +Check out our [Example Application](/docs/sdk-examples/angular#example-application) + + +### Examples Application + +What does the API Application Example include: +- REST API Application secured with OAuth2 +- Public Endpoint: Accessible without authentication +- Private Endpoint: Accessible with a token +- Administrator Endpoint: Accessible with a token of a user with admin role + +[Example API App](https://github.com/zitadel/example-api-python3-flask) + +### Step-By-Step Guide + +After completing the Step-By-Step Guide you will have: +1. Example REST API checking tokens against ZITADEL with OAuth2 +2. Public Endpoint accessible by any user +3. Private Endpoint accessible by authenticated user +4. Private Endpoint accessible by user with role 'admin' +5. Correct setup for your application in ZITADEL + +[API APP Step-By-Step Guide](/docs/examples/secure-api/python-flask) \ No newline at end of file diff --git a/docs/docs/sdk-examples/react.mdx b/docs/docs/sdk-examples/react.mdx new file mode 100644 index 0000000000..edbd20bc9f --- /dev/null +++ b/docs/docs/sdk-examples/react.mdx @@ -0,0 +1,72 @@ +--- +title: React +sidebar_label: React +--- + + + + + + +
+ react + + + React + {" "} + is a declarative, component-based JavaScript library for building user + interfaces. Integrate authentication to your React application easily by + using the{" "} + + zitadel-react + {" "} + SDK. +
+ +### Resources + +- [SDK with Example App](https://github.com/zitadel/zitadel-react) +- [Step-By-Step Guide](/docs/examples/login/react) + +### React SDK + +The [zitadel-react](https://github.com/zitadel/zitadel-react) SDK is a wrapper around the [oidc-client-ts](https://www.npmjs.com/package/oidc-client-ts) and abstracts the handling of specific configurations for ZITADEL. + +The following features are covered by the SDK: + +- Authenticate your user with ZITADEL using OIDC +- Requesting ZITADEL userinfo endpoint to get user data +- Refresh Token +- Requesting User Roles from userinfo +- Check if user has specified role +- Logout + +The goal is to extend the SDK over the time with the following features: + +- Integrate ZITADEL APIs to read and manage resources +- Build your own login UI using our Session API + +### Example Application + +The [zitadel-react](https://github.com/zitadel/zitadel-react) repository also includes an Example Application ready to start and show how a React application looks like with integrated ZITADEL Login. + +What does the Example include: + +- Home Page with Login Button +- Authenticating user with OIDC PKCE Flow +- Public Page: Accessible without authentication +- Private Page: Shows user information of authenticated user, only accessible after login +- Administrator Page: Only accessible after login and with specific administrator role for the application +- Logout + +### Step-By-Step Guide + +The [Step-By-Step Guide](/docs/examples/login/react) leads you through the whole process from configuring the right application in ZITADEL to a ready application with integrated Login. + +After completing the Step-By-Step Guide you will have: + +1. Example Web Application with integrated ZITADEL Login +2. Example page accessible by authenticated user showing retrieved user information +3. Example administrator page accessible by user with administrator role +4. Logout +5. Correct setup for your application in ZITADEL diff --git a/docs/docs/sdk-examples/symfony.mdx b/docs/docs/sdk-examples/symfony.mdx new file mode 100644 index 0000000000..297f757486 --- /dev/null +++ b/docs/docs/sdk-examples/symfony.mdx @@ -0,0 +1,53 @@ +--- +title: Symfony PHP Framework +sidebar_label: Symfony PHP +--- + + + + + + +
+ php logo + + Symfony is a high-performance PHP framework that provides a solid foundation for building scalable and maintainable web applications. + Integrate authentication to your Symfony application easily by using the example-symfony-oidc Example. +
+ +### Resources +- [Example Web App with ZITADEL Login](https://github.com/zitadel/example-symfony-oidc) +- [Step-By-Step Guide](/docs/examples/login/symfony) + +### PHP SDK + +ZITADEL does not provide a Symfony specific SDK. +But you can integrate ZITADEL to your application by using any OIDC Library such as [symfony-oidc](https://github.com/Drenso/symfony-oidc). + +Check out our [Example Application](/docs/sdk-examples/symfony#example-application) + +### Example Application + +The [example-symfony-oidc](https://github.com/zitadel/example-symfony-oidc) repository includes an Example Application ready to start and show how a Symfony application looks like with integrated ZITADEL Login. + +What does the Example include: +- OIDC Code flow with User Info call after authentication. +- Fully integrated with Symfony security and firewall. +- User Role mapping +- Persistent user data using local sqlite file. See DATABASE_URL in .env. +- Public page at / +- Authenticated /profile page for all users. +- Authenticated /admin page for admin role users. +- Logout + +### Step-By-Step Guide + +The [Step-By-Step Guide](/docs/examples/login/symfony) leads you through the whole process from configuring the right application in ZITADEL to a ready application with integrated Login. + +After completing the Step-By-Step Guide you will have: +1. Example Web Application with integrated ZITADEL Login +2. Example page accessible without authentication +3. Example page accessible by authenticated user showing retrieved user information +4. Example administrator page accessible by user with administrator role +5. Logout +6. Correct setup for your application in ZITADEL diff --git a/docs/docs/sdk-examples/vue.mdx b/docs/docs/sdk-examples/vue.mdx new file mode 100644 index 0000000000..237b4c64a6 --- /dev/null +++ b/docs/docs/sdk-examples/vue.mdx @@ -0,0 +1,62 @@ +--- +title: Vue.js +sidebar_label: Vue.js +--- + + + + + + +
+ vue + + Vue.js is a JavaScript framework for building user interfaces that is simple, flexible, and versatile. + Integrate authentication to your Vue.js application easily by using the zitadel-vue SDK +
+ +### Resources +- [SDK with Example App](https://github.com/zitadel/zitadel-vue) +- [Step-By-Step Guide](/docs/examples/login/vue) + +### Vue SDK + +The [zitadel-vue](https://github.com/zitadel/zitadel-vue) SDK is a wrapper around the [vue-oidc-client](https://github.com/soukoku/vue-oidc-client) and abstracts the handling of specific configurations for ZITADEL. + +The following features are covered by the SDK: +- Authenticate your user with ZITADEL using OIDC +- Requesting ZITADEL userinfo endpoint to get user data +- Refresh Token +- Requesting User Roles from userinfo +- Check if user has specified role +- Logout + +The goal is to extend the SDK over the time with the following features: +- Integrate ZITADEL APIs to read and manage resources +- Build your own login UI using our Session API + +### Example Application + +The [zitadel-vue](https://github.com/zitadel/zitadel-vue) repository also includes an Example Application ready to start and show how a Vue application looks like with integrated ZITADEL Login. + +What does the Example include: +- Home Page with Login Button +- Authenticating user with OIDC PKCE Flow +- Public Page: Accessible without authentication +- Private Page: Shows user information of authenticated user, only accessible after login +- Administrator Page: Only accessible after login and with specific administrator role for the application +- Logout + +### Step-By-Step Guide + +The [Step-By-Step Guide](/docs/examples/login/vue) leads you through the whole process from configuring the right application in ZITADEL to a ready application with integrated Login. + +After completing the Step-By-Step Guide you will have: +1. Example Web Application with integrated ZITADEL Login +2. Example page accessible by authenticated user showing retrieved user information +3. Example administrator page accessible by user with administrator role +4. Logout +5. Correct setup for your application in ZITADEL + +![View Example App](/img/vue/app-screen.png) + diff --git a/docs/sidebars.js b/docs/sidebars.js index 9f1220f7c2..da50f8bc7b 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -11,14 +11,15 @@ module.exports = { type: "category", label: "Frontend", items: [ - "examples/login/react", - "examples/login/vue", "examples/login/angular", "examples/login/flutter", - "examples/login/nextjs", "examples/login/go", - "examples/login/symfony", "examples/login/java-spring", + "examples/login/nextjs", + "examples/login/python-django", + "examples/login/react", + "examples/login/symfony", + "examples/login/vue", { type: "link", label: ".Net", @@ -32,37 +33,72 @@ module.exports = { label: "Backend", items: [ "examples/secure-api/go", + "examples/secure-api/java-spring", + "examples/secure-api/python-django", "examples/secure-api/python-flask", + "examples/secure-api/nodejs-nestjs", { type: "link", label: ".Net", href: "https://github.com/smartive/zitadel-net", }, - "examples/secure-api/nodejs-nestjs", - "examples/secure-api/java-spring", ], collapsed: true, }, ], }, - "examples/sdks", { type: "category", - label: "Example Applications", + label: "Examples & SDKs", items: [ - "examples/introduction", + "sdk-examples/introduction", + "sdk-examples/angular", + "sdk-examples/flutter", + "sdk-examples/go", + "sdk-examples/java", + "sdk-examples/nestjs", + "sdk-examples/nextjs", + "sdk-examples/python-flask", + "sdk-examples/python-django", + "sdk-examples/react", + "sdk-examples/symfony", + "sdk-examples/vue", { type: "link", - label: "Frontend", // The link label - href: "/examples/introduction#frontend", // The internal path + label: "Dart", + href: "https://github.com/smartive/zitadel-dart", }, { type: "link", - label: "Backend", // The link label - href: "/examples/introduction#backend", // The internal path + label: "Elixir", + href: "https://github.com/maennchen/zitadel_api", + }, + { + type: "link", + label: "NextAuth", + href: "https://next-auth.js.org/providers/zitadel", + }, + { + type: "link", + label: "Node.js", + href: "https://www.npmjs.com/package/@zitadel/node", + }, + { + type: "link", + label: ".Net", + href: "https://github.com/smartive/zitadel-net", + }, + { + type: "link", + label: "Passport.js", + href: "https://github.com/buehler/node-passport-zitadel", + }, + { + type: "link", + label: "Rust", + href: "https://github.com/smartive/zitadel-rust", }, ], - collapsed: true, }, { type: "category", diff --git a/docs/src/components/tile.jsx b/docs/src/components/tile.jsx new file mode 100644 index 0000000000..e1066325ce --- /dev/null +++ b/docs/src/components/tile.jsx @@ -0,0 +1,35 @@ +import React from "react"; +import styles from "../css/tile.module.css"; + +export function Tile({ title, imageSource, imageSourceLight, link, external }) { + return ( + +

{title}

+ {title} + {imageSourceLight && ( + {title} + )} + {external && ( +
+ +
+ )} +
+ ); +} diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css index 5cb0c80ec9..38ac4bba88 100644 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -127,12 +127,20 @@ --gigibannerforeground: black; --footer-border: rgba(0, 0, 0, 0.12); --card-border: rgba(135, 149, 161, 0.2); + --card-border-hover: #6c8eef; --ifm-pagination-nav-color-hover: #000000; --input-border: #1a191954; --input-hover-border: #000000; --input-background: #00000004; } +.tile-wrapper { + margin: 0 -8px; + display: flex; + flex-direction: row; + flex-wrap: wrap; +} + pre code { font-size: 14px !important; } @@ -232,11 +240,22 @@ pre code { } h1 { - font-size: 2.2rem; + font-size: 3rem; } h2 { - font-size: 1.8rem; + font-size: 2.5rem; + margin-top: 2.5rem; +} + +h3 { + font-size: 2rem; + margin-top: 2.5rem; +} + +h4 { + font-size: 1.5rem; + margin-top: 2.5rem; } .navbar__brand { @@ -305,6 +324,7 @@ h2 { --gigibannerforeground: white; --footer-border: rgba(255, 255, 255, 0.12); --card-border: rgba(135, 149, 161, 0.2); + --card-border-hover: #ffffff; --ifm-pagination-nav-color-hover: #ffffff; --input-border: #f9f7f775; --input-hover-border: #ffffff; @@ -563,4 +583,20 @@ p strong { background-color: var(--ifm-color-secondary-contrast-background); color: var(--ifm-color-secondary-contrast-foreground); border-color: var(--ifm-color-secondary-dark); -} \ No newline at end of file +} + +.hideondark { + display: block !important; +} + +:root[data-theme="dark"] .hideondark { + display: none !important; +} + +.hideonlight { + display: none !important; +} + +:root[data-theme="dark"] .hideonlight { + display: block !important; +} diff --git a/docs/src/css/tile.module.css b/docs/src/css/tile.module.css new file mode 100644 index 0000000000..c2f2ff2eb1 --- /dev/null +++ b/docs/src/css/tile.module.css @@ -0,0 +1,69 @@ +.tile { + position: relative; + margin: 0.5rem; + border-radius: 0.5rem; + display: flex; + flex-direction: column; + align-items: center; + min-width: 230px; + background: var(--card-background); + padding: 0.1rem; + text-align: center; + text-decoration: none; + transition: all 0.2s ease-in-out; + border: 1px solid var(--card-border); + overflow: hidden; + text-decoration: none; +} + +.tile h4 { + margin-top: 0.5rem; + margin-bottom: 0; + text-decoration: none; +} + +.tile:hover { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), + 0 2px 4px -1px rgba(0, 0, 0, 0.06); + cursor: pointer; + text-decoration: none !important; + border-color: var(--card-border-hover); +} + +.tile p { + font-size: 14px; + margin: 0; + color: var(--ifm-font-color-base); +} + +.tile img { + display: block; + width: auto; + height: 60px; + background-size: cover; + object-fit: contain; + background-position: center; + pointer-events: none; + box-shadow: none !important; + margin: 0 auto; +} + +.external { + position: absolute; + top: -1rem; + right: -1rem; + border-radius: 50vw; + padding: 1rem; + height: 4rem; + width: 4rem; + display: flex; + align-items: center; + justify-content: center; + border: 1px solid var(--card-border); + background: #ffffff20; +} + +.external i { + margin-bottom: -0.5rem; + margin-left: -0.5rem; +} diff --git a/docs/src/pages/index.js b/docs/src/pages/index.js index 0e88b075ac..630a7d4fbd 100644 --- a/docs/src/pages/index.js +++ b/docs/src/pages/index.js @@ -38,13 +38,13 @@ const features = [ description="" /> Learn how to integrate your applications and build secure workflows and @@ -133,7 +133,7 @@ const features = [ description="" /> v> z_x=I*{_x%(?k{IPGjq<_d#$tgTF-jcb3zs6CGl`5a3Bx}-aDzc$`A;883cm*7>Wvh zQ5VYH0w3t6Vsc^-$i&o`g2qem{gI=%hU0r%6Gs<=PsR{2BioP0bnmPUOpTR|4UF9E zdyEAk5P`CHZ^cwxXLjc0WWP*ivD-P@?(3(c@9eD6#d=9FqJ7ghvePA$v#_jh_50p= z;hgcj+T?Th+vkXf2L42HW>zUGSRGu}JEDC3Hr83#-%uo;zZ89xIz;Ef6tlCMHmq}? z5~bQJ;VP0=owmr{K9uTk;*}mlbZyE#bhV-9AS;ksateLs8n|NP(w14I5#52AGF z5Xk=r2N)Cu0{LGYTmxKmP@Q+yOIsp0M!oHB9jos`g(Bs!W@ik4(hW|kt&^?^b%KRU zzw@@BvRB;ogH(V>2T@#}si_4l4h7Qv>b(S*>HkmGg5&?Yb$_(1^A*DM_YnCncwM3E z$UMEYxZW57!8p$oarxJws&9IGc+v9ss_O33!QvbU1g=RhvcW<}rT-rtO5G=)K_I@X zPF2+{lT%eUch?<%a}HMOu@P@C)Ar4+wx$+u)$Upx6xP)z)SCVsNIIEbcqzOeoxR0l zE-G@sJ)Yi=CiC{_l@fI^o$S5)z&}=<(qer$JyOb!qdSQ0CJ&_<{$^=ygDvtQaD1lm z^}l9aQ77l!qf$HgJ;~j~A4JdbV&ux17qA z%bB~AD5dEmCSo;eYpe}MU^63zmON<-u{@xZjh*y>cZJUP;i`3{N}Z8m5K#> zct|F;z`5g1Ai>=W7@>Jb68GWu1&_5(UeLKrWx)(Q<>HS-FE4R%N^I#2HA;e)O2q=d z&`HP1Cj~Vr)TQ%A60^H1zTtz9Kg=B{0$Iv$`e<#uHiwoDOz~~q>r%G+J0uAz<9^=| zLZ`=PX_AZSQ6}o%TovnH)H}Y#Ml`CXm}kHG`>Qol@92`rdUzu}*^AfhF3nCOHp=(M zCKb-Og=|57>8Up&@N!dPyh!HP4Kq0MGto2D{EF1C4-pMDqi4S7qi z3E?D|g0i^3X9JpkMm(E6%Ak9} z+1|o}{``O(A;4?DjwSwCw41hhS4eV^z^9YjlOER0_BJ-X`IhGk?n@zo=JXBb^E4Kz9@5`AJ=ZPYUw?QkmZSL@MbHoFygyx3Bp7StJQ>MyH(cy_WGWS(7g z!b@8`)gESiD*p0W zXrMWC_Zqk$UjOoZ>2lQR9d*_po)pGR{`YLyh%7o(gC$f0SL2G*FM=fv4^a*BC6D=3 zH1b&uR<@+cTbvv`mxHPUrOW&iwG#KQF0$(dpQ>X9i?>>j=sbgk`9l%n*a&CMLWyhP zxw&sUWen(@kE`n09_aDBx5QGoSp038pl^Q(W)%6l_5mxRywzZ(Qy_l;_>!v0dprjQ zU5V*OA-~#*lc9&95e+h1O1)d9f~FU#y(#R-%eA+CisByC%#J6)z@=r{ zY&&^21Fw-*G?i?WDAg;PZW;Gkn;YtoVQQFvP3e7gHJg7fPXr~J9G;-b%D{(DMeUqG z9SSX2g%ZM*Mu` zX#a~!Y0Bg!XRY+}r@1(Ll`< z5SF%TTPP?*{&9x)vc0(j1FRZzlD=`ABx1yPbhYRuPEw^eEKjemqlb6}5MKx--=o_~T1KQXy zU}T>ursO)*tAg|9X34Vt44KxTz3aL{!6bTJc-2RIAXi{Jd@?`IemV(7RDW@b*F?v7 z%QTj%S=)`!+TPnqzP#-!l_+ujK=^)qsWmekEiI{@oRSJ(eZdI^wfqilX#p+ehm~3x zKA1#FI*4vIH2ZLC6vLoI~p8JWyTd94*GzinV$BSJbg` zVQ~p?ecG+pjPk6}=%4x7@hRV@jrgw??>5Q{8k9}H$}+;#YHx8B64j}tf>eigG-^yG z+(~X+)LXbR`K`x!BbpO?Egf|E-NG@D7CB$7mP6?-TvT&F(0BxbJooER$f4)S7yJ>BWylw1n$LTL6tICK0UgN<~6<`EQ;M(_JN z-f4zw=jb6tJuhs&Ye1g$eJ@%2$xh$cP6U@mAL>>Z^%y!b)!f=97Sqq4F`akwaTz68 z4?*s)z9^(ruU!v*b65$>t|-DXOn;$M$6r!ASTcjUBwvUV-s`tqR{6N0^tGY6tub|T z4IX>^Z+wCv$@#3&jgxe~^%87^t$I-sCWKhp>@oAnR1R=#y+e8h(n0w6COYjb>vC;? zAmOSAp3hN3^3pVo z5T;Kvhwj(Sfo29=SK8MalDUhGMjfvghGDp z%MA`7L}=OjN`Dj=|0o$??K8c*9_zfjRWN4Gl@6}gOgVS1s@6iHFXc?FZNGnbc9)R} zZwsKOas7hxZ1wIil#+z6TA3~)NENAQm-+Kx`)Firr>($5<5+0Kx9m^4Fz~*$)x+TEI3KKp)T*nG}(NQr+BE0<}hs&)}m1%)3k{L_!`pM_5{C85s_2yHLx#@>MD`aME78|AV~k5dBEGop*;tsl8gI$ zJJPO4y&yM&kb;5yWUH5{hHXn6MX;V$QXAyL5&H3{wMl)3b6ez^;JXfE%t#w;VUwo3 zrpJm5vGA{iR)g!rXLRvdl&QE1NQdg-KMOs5Rq8a|ieG{Vs~tD&+|jhTi>z@4J~$rx zJ*f6PyPmzd)1#7NfvFjt{$Y6WWqj%I!gJXqKiXN*B5;oP^s#yHSAO(7yU-Dj6{I@u z_(}WxEUE!LaV8OGWBpQUdgGmps|T|HEkC7+dEK>E=1=d8b%`gPDjuImP#N|YJ+_0C z67+f$g4thNIZFMM9PW`w$fFgS`%pW>(>o5*OT`y6$I*yd#T4(h+gIy2+J&`o zLITVS)!+!MAuRd1%cTT^rmbrGHp|MxHSOE3mAes(@4E0C;l!NUH}ErwsaB;b|Y z>*6sSh==S%K#hU6n^{8yVOd`?&PW( zb%KakEq|**4PJtYR_m?MCUXVQ!8zNyJf3#G?K<4dB#;2c^aDLgvhb{Mj5(mqTtVpr ztA{a0#j_z8>8>K#OKd{R_p zb@=1px7waH@tq-Ft%K>V443DEIn|s?sv_KWO997uIbtJUiVL>@l0@s0S^A1jb8%O9 z7e4#@EKoFYSBlvBuScD4jL9%+`qobSUZXtwcq*g-)`t^=Rv zZusul_r)Y5))cz2W1YiyiUz0}<9RSNv~{lz{%yWTBa^)>$X58?`r8Y!BFO2*_=pXXV#ZUe=DQ0lqK zGZ>@-oBQ%o@IBwPpumvBYNBXjMoYqbUe)J~I#In(-(|kM2IB#*VNA>JtNX=JSC^}x zv{cW3CZ~B|tiyN?A1F1yQtQva%bPBl-%Yzbt7q!9<}{~vLxGJn z@(z4QJ;H&h+{spSvVWqa1HMyWq^6+Gk{!K?V8&*qgc9*m(k1nia}#gdoP=Bc+*N}r zTm;s+NbNDLZO2&AMR?I1{Fw^j3SoqDy%mts5GyZ5>EXGH!90Gl(BqehUp&2eEI@>` zXvDh8;cQi;lU;QVO3v;MHjGOIm2ei_jzlW~6%L8}SZd?tG)|n{p|FxtL<`s_q_*dh z1u+2#b4+CZdN{~IdNp~B*h$H$4>1g0BPogJWmH}EARZK5a-4X-NIA3Z{0=s*IlXtp zv;x#$1jQpj{nZQR$Zvn{JivV7U;Fx_ z6=M(=`98Ye#uwqvS$jHI^S4cc_KWf-sn`&!Y()!@;c!I6w{5=T>|T7d=Azh)r#<%i zbf?`>D`<6e%YLYPAl1ba&SQC^b1FH{%Em5!RRh6ekE;Km_qD?QKvQzo@0=nf?58ca ziekjEIK$q8F3Xm88O4<<;lAf^zuMj$($n#46DYOeO=RydkU!)|=eus_4(QtHh}rM6 zf8a&!>!-h(GJj2z9T()qIOIS*T=57j7}c~<-+MC9{v*_(W6}JZra~7{C9-fpx2nj~ zQ)%eq!LzI$=G?{+I)}b1-dC&|B6ffIFu=-xgi<17p?qW189j0VWqZ4S;tU#RA`_w@p{k#3&JlcM)_L_(? zr&3Y!Omc#6Lz&QVScTr;u;F}aa6d+%l-^REuw6}gGv!wYPWcD#)_%HEEs=%V_?L^4 z?|P(3g8?$pH}-Y_)b|EJJvRV8=f_dQx}1w!ImBpz_2e7F5pRNMT}2JWeDllV+=xOE z6?&Kq{sU}|UcVB|@AUPo%Y?k-8FZ)O+O)3rZZC3l*bL{?CFmj!g>1og4E{QY3ZE*E zf%G!S|MrVX+sKWO-&}}X{uySy`e(9AGc?)|7ZDg%x`~e5FhSL@g$P)_2%@@pXPfSp z8T0+XqU+R|fhXegNjAxJck4ZvE{H^4{4XoN+=*Uhm z@=x}lSWHp=R=GKfjTpw;DfzLbh_EKYAp&v#N&++cGwIpKDLFxB~P=nt^Gjm zYq&-i)7$jNRyox_jW?E`H3Y#kcg(|fy!1r$Bgx;o47h$Yd>>uyfq^WXqSb9YrlYa*!C6dkS#CC)iK2he4o z9cErM-x;bB+G=X?B9J$V(t_TQ)Q4`rd(iM6FxsDxd#q4hhXjh^%)BaU4udTGZeAlL%iLQdUBiGE&PqE!WJJCHS*=JkMD$_; z`_|kDdx74HxK;g$y5N>563nI^TDE&Gj#VzIAqT?R-m_I{uqyv92v4F&O^JEwmRVng z00)o|OIbSff~&N#e5u?^D0SY%TDw}|(T|^{**lDI^YB`kKw}!ETy7J!T$QT?s_PoR zXKLti*5HJ_LQ|sqK}jw0y>Pv|{9uJ2(o=aHEXpWm{rPenkQ8$L18>ih&UfdxFQ2@- z=TK0~vSOkqw7OAMH(ague3=<8N94Ay! z_L!3RYKvQK__tx9w!VoRl^%OSR}L(`di+sJ2hxi2sGoVqnaUrub$>r+adL6KIXSIm zd-yclF`v29T)Mm}p2^kvO^^20PT0ma1J5UzPIIJvGT5w(9yG}V#r>>-?lV%lK9|~= zXK_6e|9FrKl`I$LWbolC9xaG+^%v#$nXegUzfSydaJ=Lh+d-wTh7s;8&(D^i^)Q~N z$zJ2igUavX_4&!WZog=SIavgTwey`;I%^=Ss`fph%RG63=AVWv5f5Uz&Ij!Xn z&0$>A;qM`&(hEPF4 zoK7m8%LnmuHg=VN8UEzgw}j+RccKoM`&b1ZLJdjGX?=XA#TMFGOSUWk?9!q2d5VKd za`IZ$?ZHQ?r#pZLJ?p)l%-)wgPcnQYP6l1nw>UG1pltxl7M}W7&fWd-i|se>>E5;u zZ>w9w2nvsWzg%R%;l#gw%5g!p0$p11XMOsP3C1QI{z)Js2J^aiop_XSyJ!wSk-&UN zQ%o^IJ@iuep$huLJt z?*aVwhGJK3A8bd}pFtnFPu}wWJ@OIuM3~q3dUc^1u#rD~s(ZPAsimzOhe=PWG&rW5 zu-?KSQqC6Qj^OB&>juRo%S_Rs{KrLx1;aNF2nj9e`fkiC0re>r01H2;>GYtfDipl? zNF@j*Q2klU{+kr8!LCZHe2xMKOrlA~>St}K!0o6BW3r%2Fkm{ObX(SF{GNNT7JZtHT>B7l z{hP~*YM*%Cfn@X7n&aV!zP}&Gna;-+s-GWgu#*E6J>aWkM@0YwbsMz-XC_Of&c4?~2kHr{0=cJQ~eoi)!Zn@)lVabEs7 zGRuOC_=%3B;@)miCq{wpamHQ5WfrP|kgd_27Fr-#^Ie4X?~t}u&q4hpPrE@O|Bd!p zqeZTh>1RZe0FBzPq;Uq^9{nWGYka170Y$JU`<`dpq6U!(Z?Oi^6NLSI02zr9P1$KE z($hqX8=aw_d4mC8;Rx%0u9>3sn3{&gO5_tTZR|1j4~i>`)vy8aBU`O$$raAGFHq?pE9*RwS~n6N{DsF1E? zCgB~pPs1ik(axKMW0FEZu5}3X_d^Xd_uU9Dg?kbBS&$5~xDP! zI@WXxd~W%?MJDs&Z}6n<-D61LOZ)X;qh=XNt?RyX5lzgvbW!qan4_@i69OG7Msa~s zRzX70Ny9}HJW8)i8ku}?eim5Yexd}yd0aL5eujc+*08f&nIbG9u3ut6RmN$fQsz*1 z&_Dfs0;rFEJnq?wyKj;$M5bhP^3UMcL1ESH$!3{X_zA8dfe)$K_cni5#v^tOP`TZ+m>0~3zp+qUnozBpq)5@n z0=j1;*E`GcXiKj{I@UHfQ|FHdEVUWC5mw98w`n&BrdnB&o;CTMEZfOLjQoQh&y?+N5a~hVEB4dXYL5SR@z8eMe_DbuEy)k5vB_yBxGj!NLg&_ z@JH}#OM_qvPs941N>E!4*1Cwo%`g$^UQ2^btN`zxTmQ>jHx&@VSK5!f{QZRZ$Y*f) zoIN^HWnVG!GSpOSvoUSZ;+v+p zn`n?4@ABE7{%fK2G*9G|@$#Ucth_5)+ zHa`7pg|u2`i>_q~RaGxd@V(*Wn^(nuC#Jap?pl(G1T7>hYHFGqu$6CLnZDOd7ZDQp zyahJ~l=DPzZ`kn93yBY3mu&S!5`;Nii=4*+z7eKw-cc6)4j**}z;s2Y81ts^#CQIZ zK1VdMMT=QN0U{Kv4mBrjruofTh-DbY##n9wEG6Fxp_oOD(tu0V@TKiYPq% z27Hw_$R}7!GS;4@%=AR^_m1B@>v~YRgxGr%+?HN&_7-t%qx8-X)u0s%JJbD0#Q5Z| ztgD+>w7Ez#xA;JR4 z3pDy3bAO2jEBgpEr7T_=TP{d zJ|J*zYuC+6uF6WTBcXMvU^)rJWuw^!btb!@^i#RJvs%+io1K672_Iu(3M(4(6`#}2 zy%N+I60HNckj*bFMa#9~=S%v>rBp+NGboh7UP2%4Box+b$wOQ((FdYx(DtoQIL+UP z;zcOTNm=!JeCjyLS|+EWw10?00e!7|S|lX7;PR0`W$5bi%i(#YQ7Bud5pIV880_~K zvS)5}s4d}WdfEa%_NBEk zk0SH-tQenQE{BB(b_b&)5Rt#v+7om-Blgd2mv< zDvg#BL1zSTO=;LTCI0gz5>P)1_2mIrwtKFLX{YT6lP}3bN0YHnVa*mttwOc};x!dD zYOS3~=2N1qffU;6#N)5r=OyCbCDnP%8iCG9KW3MN3WH)&*4Y378>*tr)pbGIfmtd= z-5>t%1~vw_6#-ZnNLEilyVh<@l3|^l>>j5^6mFAKta15=QS1s&X14_ip+e6Tv%e%Y zlVo)MxXma;j^;GHat3s8l>$1_hfVMq?KcrtBBTxT0JiCClxm**YDsRur%r!F=0CXs z^mj>sC?k>b6Ay|M9B&MG()Ke{3k5v+Q=@QfA$`u|v{cSbb-H-$f&$PzU_)N81|USK zlXooa3TNI{X>xZqoRwSqp~I74H9R-@M_M~k3UddTD9JldO@RFb8gC=EaS$)*Ps{Vl zhsB}$QDSh>P}b4}LVnk;g$Ly5IV@9*y(5MZ4fQSwR(I#%ApMx-pXv>At;Efv6% zObBKEjD1ea?v|);YFxgehmr(Kf|&!(Y$^8B#e><}(w`mTQ&uscJ5z`6D;pvk!o>*d zywL|9v9NJkM60PRm6c<9dVAFI_gOJ##$J-* zDRs4=0#7VI%rn!5=yGR%5*bwGF>6?D|4=B z4hA6k6sJ+uxF7;^YgS|D>f#B;L)Dk=H-(!VPFw&I$4Y!DXaX|XmDw}WKFa_<{;bVR6pr40$t-`j^L`tn+|CEKUet+>ubC(A-QySho^t7|^x0<|CUjG-loP{CnKqA|SJ)wiCq$y+t$CC>Xwg6!))&|sWSZkCqYBY1u0 z;`jm`IY+AT>Z3udxXV+oCZk^0lYTU(uXrRgg5Q`_oojMSe^}|;Nx#yfBgTCQW&WU3 zJW>3GqRE@P@j3VG8nJ%3S}rw8{?@2*!7LkSQ28+G;38r>k$?sU@WjIz_i_Czh6=)( z=F-rPb5R@y~H>($41MbwCe3qmI$f#g6Rc;UHsZDqVSvhZ-YL)_qm@_V0Tw zd;PJA-YwhWT+_{EyWH*$unh3MfbRLb@Oj2BO~J2hqX+a^o{n+RD;X^f8M_r-kl{pi z{52houF%_33u)&SOk5Y!r1-gX5pSZb_^b_&>;5?o5Q1^um!#gTpx8U5Y5j`A`qFj zx{WlN8XtD1`H8Wa$6eV$lK&Q&BRPrMYj9xcYTtZ( zlD*?1P}3@pRORVn_+F5f-Q^zDm_DdMQrLYErLb^k9PWIUmdh(W_IQW?i&H=iPwl^A zPo6Emjav7&l_fX{v7+6S2r|RtdFXiG)!;1}AXdXiZMkY6p7CgvP_~h|l|K0R?Papg zQk|y$G|RSKwINkp@pQvyycAO%27g+WeJ5NIU`J5RwR>h&OH;$K-Mr=2=IQhHHbp1* zL&NxD?MO$utKF>=)&?dR)a{MesNH$(oz=Y{G3Sj=algl;PblAGlPBJIEwmNgvvrF+ zfp#BP3u}7H=sj))&S)7mdHWvg@$@*{2+bs}CmqXwww)00&EE9tzB@`#)QsvpZZ|RZ zn5poKI(T)JB>@#F_RxY0&($hfs-LD0+!gfAUl)_F*kUo9pKSN(lqR3oSWS#2`OK6H+$g_jQt~KKwL9?HSpGF+`t@ib zkK;cIy0k2-uun7+nTs{LxCC21b9WsvPQ(!~2^Np83WLwXlVQ>4x>XS}!S&vHBD-F* zLy4;5rC-L_Pj4kSYbz-p>xd?fyuA6!plK`7UhfibwkkA+v*Q8*48*A{&I%OL)cRm(Zh9=>U^;^1JDfEujdD_%eTn^F}@;2eaX zx*gqXG`;U0uATwDo`Z%-`RbBh%7E1RIst>`BFAv?4Rh?`+^e=6(HVx zM=ze{0|a@lmp*P@ubm-BbXg?bPO-*i{m*{jv6}=NA0wG~#nuvvX)B_X<}*;~%N|0b zn`u|NZpZz(d_PuFYZg8%U+RcRm|SOQ+0EV9+`aY{g{ndk_EE4c2MoqK#u_tS&)n;Z zis}|lq1$^dbcY2`Vy3My41=*kgNgn4gD4%s6AQ_^9?sL4sEjJgNgc6@KDoZe>@N!a zS)Et@Vg%I8^rEf1MdxlE7R)dxz5C$+nQ99vvG(=?DH#e3YM_4AYx?A7_5LhlEW*{f zDr!Y=Q!4cw9qL$?U#|0GPqZRXi8Wb(#@Y||sSrpP8)+Ay^rErVYRlh`DD2>bP(;jP zVHJ=zZ3gRo&;nFu7|WMOY|KS9D-JZQ zj02Ebvo5|xW5B_$!Qj^i&-WJ{h){5fK-($#MYenn7PyH5oPa>SKo2F1^$P}KE&Sf*(fMhT(*ymsE6-uQIZ0ong|$tnG2&p-ba0Lx44~JE z8EklmWAX<={DH;1td%sI4hCNUG%r~%(?3?GNq_@t2{X!W)r2W~C96A8(Ba*&fZd%^ zC%`0f@wQ_I(*k6YVygI|5*`5<@A7E8I{`@5%YDLou<*Y@7)x$lgRuT%ivssXl0%Nv zz`=a|CvH9Bj51*8zJU>1B-A02pdUcq40D# zuc5?Ilm*0hNDvlKJj*@0_a*)J)+ra#et<*Bw$xt}XZYT8(V<&YPul{39c&SJ_>zvg zqZ55(7>qwQa_d2rxKZLK3UyN3+uas%V2j+ZsB1LxQSwEqnGQSIP|&0M!M60gytzL; zODa7Ex!{~QWGt;Smy7h%q`0J(hxTW2N*;brR=WH1w7qiUF~Ll%8PM9d^|h`?TND6! z0K;{O$uXQGvz|GigCZ0cxh?=Jl6w*fr>IJO0P`q&1UP$*iyAUk6;sZ=a2~fivRVRk zcz!gHTftA0G%VXZmFUVfczJl|X6BatpC(~a^3-%VV~Nor_!-a7yj)Iu+eiKYj0ym^ z4O@)z*rtfX9^eN)^N~tX#AAZfu5kOq<0tTJ0Ep=C$A|-x$`l~Mi}6IVmvrV@Exl<} zn)XzJK{N4zYAM{BsAiW#5c;%qY?|cv0Rv?(ZvT^hQsMTLd&44O;DK_3O=G@xP5XIA z2Yz>Ql}ZmcJ}v5S10FZ2Rg`pe!Iq1zhHi#kk6n4Pu$Drw3n-JP~@feb}knb zXv#)>*0e9M4Gi6#O+de~heb)|1&#?-9J-S!A_m@VLX_iGQZBDX_pIR&y=Qg|HlP&0 zC8vhkPjQUtWj@|!PnWZT{|IG`!IFT!)2{g=JeJ+#GYSB0E#;qRL>OHWZiPWx0SKHg z`+Rt{@22j>(a)#z%mp5Gqdh@<|1me~Vr<8|>(|=Pe>(OH!-YypqC*n8$oM@L3}r$) zAf!VO%r_lhlwB<3c{7sPwlr8(R0a?o4?Lj$6(>I$>xMhP?R35uqHu&Hv9)n9E(Umu?s^6+w#fwiQ&yPzk0->zKt z{5!loIaUB683<3aM~birASf6UK3O zy*WpI`+R6Y=QsmGilRN(aX>>>K~YPWYYOVQdAn_tLZesRBnEu$_xtWOx4;TN2+|~< z7v$$=%PVTGHV=$lXnpH6HbHMkMHaMJrvBJ*3fRbzV$kuc-Ny)$aQ`=C>2 zpo;!L>|6Kazs&0WowELv0Ddcp1xM5o496u1MWqk%ZvYJvcZ)y%ZJsD0G9mu=;1Zt> z=FeEi49dC%i&6(jcL45M&3`Uuiv-${b^+$d( z%*M?Q4_sN79!h?*^{U1B1)mi##V(c}DAcr{PC6PuT?9O!{frjOix1&K#V1zWW zZ~kb8jof`cg5Si?677O8P$?epd^aStaL-2SB6({ySX& z?^l=JUW3xX$?IRNdDj2=quMRYOJ}R>pw!3p_5_reHt7GE4m{P+fK{Q2;7;v=EbpkP z2M=P!I+ij**S@FVvv(0*1W5u(|xQ@kB>%w^_a zCFT1NexWnZ<9@Ssd*7Og4WrdbbjmIiK#>xyd6GkN&oSXF$ai`bpX+hUm@M$tmTQp)uakFfLuC;F2B6|Ny$gsu z4SwClV3R0=CQ8BMtla>lr9m<%?>_CI?_?pGKhAa8>g21{9@pBxD3(0hae$Bd>>1I zX3pf!6P)`Om9pp*p?BLpcj@Qa7!W%3w9?|+mb=@1kidb!LOZfhq7}F8t7J=^NfaaT z7aa){-+#ZOym$FNSw$OZ00FjbwC-0lu%aL#VxSAMzHv?esGhjtA>p5OqSq}yJ!bK< zz@vw}H36NzZbaPDEY6`VkS-pErT~t%1QRrPA;Yt>K_;JVQqk^T3%PaVzJE_pN)c?t z|7r^WwO0~E1%)CYq7Qe$D@}VlOw{~Tw+~*Fo9X$0;0@j#TD|dD3q%FRC^}Lul@)<9 z0vcQ(&)g6HbCUfi4|@O4uas(@T7O9;pd}u^*j9dY z*!fRWWN5Bxs(o@!b5JA^>YD@H7FiL^^nd0!jQ94fa&p@I&RTIc;{@)+&mmcK*`9XC4#s>uxvS7NesU8)R47>$-CoccC J1g`J@e*qEN=cE7t literal 0 HcmV?d00001 diff --git a/docs/static/img/tech/elixir.svg b/docs/static/img/tech/elixir.svg new file mode 100644 index 0000000000..63f8541228 --- /dev/null +++ b/docs/static/img/tech/elixir.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/static/img/tech/flask.svg b/docs/static/img/tech/flask.svg new file mode 100644 index 0000000000..b8f3980529 --- /dev/null +++ b/docs/static/img/tech/flask.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/static/img/tech/flasklight.svg b/docs/static/img/tech/flasklight.svg new file mode 100644 index 0000000000..d26a6e44e5 --- /dev/null +++ b/docs/static/img/tech/flasklight.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/static/img/tech/nestjs.svg b/docs/static/img/tech/nestjs.svg new file mode 100644 index 0000000000..69830240c2 --- /dev/null +++ b/docs/static/img/tech/nestjs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/static/img/tech/nextjs.svg b/docs/static/img/tech/nextjs.svg index 312dc61b92..803afe1d4b 100644 --- a/docs/static/img/tech/nextjs.svg +++ b/docs/static/img/tech/nextjs.svg @@ -5,7 +5,7 @@ Created with Sketch. - + diff --git a/docs/static/img/tech/nextjslight.svg b/docs/static/img/tech/nextjslight.svg index 803afe1d4b..312dc61b92 100644 --- a/docs/static/img/tech/nextjslight.svg +++ b/docs/static/img/tech/nextjslight.svg @@ -5,7 +5,7 @@ Created with Sketch. - + diff --git a/docs/static/img/tech/passportjs.svg b/docs/static/img/tech/passportjs.svg new file mode 100644 index 0000000000..daf12a04ff --- /dev/null +++ b/docs/static/img/tech/passportjs.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/docs/static/img/tech/rust.svg b/docs/static/img/tech/rust.svg new file mode 100644 index 0000000000..62424d8ffd --- /dev/null +++ b/docs/static/img/tech/rust.svg @@ -0,0 +1,61 @@ + + + diff --git a/docs/static/img/tech/rustlight.svg b/docs/static/img/tech/rustlight.svg new file mode 100644 index 0000000000..e53b4e738f --- /dev/null +++ b/docs/static/img/tech/rustlight.svg @@ -0,0 +1,61 @@ + + +