diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 17d0cab465..83b4ceee0a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,7 +31,6 @@ jobs: uses: ./.github/workflows/console.yml with: node_version: "20" - buf_version: "latest" docs: uses: ./.github/workflows/docs.yml diff --git a/.github/workflows/console.yml b/.github/workflows/console.yml index 04bdcb2227..b2f8119190 100644 --- a/.github/workflows/console.yml +++ b/.github/workflows/console.yml @@ -6,9 +6,6 @@ on: node_version: required: true type: string - buf_version: - required: true - type: string outputs: cache_key: value: ${{ jobs.build.outputs.cache_key }} @@ -35,11 +32,6 @@ jobs: restore-keys: | console- path: ${{ env.cache_path }} - - if: ${{ steps.cache.outputs.cache-hit != 'true' }} - uses: bufbuild/buf-setup-action@v1 - with: - github_token: ${{ github.token }} - version: ${{ inputs.buf_version }} - if: ${{ steps.cache.outputs.cache-hit != 'true' }} uses: pnpm/action-setup@v4 - if: ${{ steps.cache.outputs.cache-hit != 'true' }} diff --git a/apps/login/readme.md b/apps/login/readme.md deleted file mode 100644 index ca7070a901..0000000000 --- a/apps/login/readme.md +++ /dev/null @@ -1,394 +0,0 @@ -# ZITADEL Login UI - -This is going to be our next UI for the hosted login. It's based on Next.js 13 and its introduced `app/` directory. - -## Flow Diagram - -This diagram shows the available pages and flows. - -> Note that back navigation or retries are not displayed. - -```mermaid - flowchart TD - A[Start] --> register - A[Start] --> accounts - A[Start] --> loginname - loginname -- signInWithIDP --> idp-success - loginname -- signInWithIDP --> idp-failure - idp-success --> B[signedin] - loginname --> password - loginname -- hasPasskey --> passkey - loginname -- allowRegister --> register - passkey-add --passwordAllowed --> password - passkey -- hasPassword --> password - passkey --> B[signedin] - password -- hasMFA --> mfa - password -- allowPasskeys --> passkey-add - password -- reset --> password-set - email -- reset --> password-set - password-set --> B[signedin] - password-change --> B[signedin] - password -- userstate=initial --> password-change - - mfa --> otp - otp --> B[signedin] - mfa--> u2f - u2f -->B[signedin] - register -- password/passkey --> B[signedin] - password --> B[signedin] - password-- forceMFA -->mfaset - mfaset --> u2fset - mfaset --> otpset - u2fset --> B[signedin] - otpset --> B[signedin] - accounts--> loginname - password -- not verified yet -->verify - register-- withpassword -->verify - passkey-- notVerified --> verify - verify --> B[signedin] -``` - -### /loginname - -This page shows a loginname field and Identity Providers to login or register. -If `loginSettings(org?).allowRegister` is `true`, it also shows a link to jump to /register - -/loginame - -Requests to the APIs made: - -- `getLoginSettings(org?)` -- `getLegalAndSupportSettings(org?)` -- `getIdentityProviders(org?)` -- `getBrandingSettings(org?)` -- `getActiveIdentityProviders(org?)` -- `startIdentityProviderFlow` -- `listUsers(org?)` -- `listAuthenticationMethodTypes` -- `getOrgsByDomain` -- `createSession()` -- `getSession()` - -After a loginname is entered, a `listUsers` request is made using the loginName query to identify already registered users. - -**USER FOUND:** If only one user is found, we query `listAuthenticationMethodTypes` to identify future steps. -If no authentication methods are found, we render an error stating: _User has no available authentication methods._ (exception see below.) -Now if only one method is found, we continue with the corresponding step (/password, /passkey). -If multiple methods are set, we prefer passkeys over any other method, so we redirect to /passkey, second option is IDP, and third is password. -If password is the next step, we check `loginSettings.passkeysType` for PasskeysType.ALLOWED, and prompt the user to setup passkeys afterwards. - -**NO USER FOUND:** If no user is found, we check whether registering is allowed using `loginSettings.allowRegister`. -If `loginSettings?.allowUsernamePassword` is not allowed we continue to check for available IDPs. If a single IDP is available, we directly redirect the user to signup. - -If no single IDP is set, we check for `loginSettings.allowUsernamePassword` and if no organization is set as context, we check whether we can discover a organization from the loginname of the user (using: `getOrgsByDomain`). Then if an organization is found, we check whether domainDiscovery is allowed on it and redirect the user to /register page including the discovered domain or without. - -If no previous condition is met we throw an error stating the user was not found. - -**EXCEPTIONS:** If the outcome after this order produces a no authentication methods found, or user not found, we check whether `loginSettings?.ignoreUnknownUsernames` is set to `true` as in this case we redirect to the /password page regardless (to prevent username guessing). - -> NOTE: This page at this stage beeing ignores local sessions and executes a reauthentication. This is a feature which is not implemented yet. - -> NOTE: We ignore `loginSettings.allowExternalIdp` as the information whether IDPs are available comes as response from `getActiveIdentityProviders(org?)`. If a user has a cookie for the same loginname, a new session is created regardless and overwrites the old session. The old session is not deleted from the login as for now. - -> NOTE: `listAuthenticationMethodTypes()` does not consider different domains for u2f methods or passkeys. The check whether a user should be redirected to one of the pages `/passkey` or `/u2f`, should be extended to use a domain filter (https://github.com/zitadel/zitadel/issues/8615) - -### /password - -This page shows a password field to hydrate the current session with password as a factor. -Below the password field, a reset password link is shown which allows to send a reset email. - -/password - -Requests to the APIs made: - -- `getLoginSettings(org?)` -- `getBrandingSettings(org?)` -- `listAuthenticationMethodTypes` -- `getSession()` -- `updateSession()` -- `listUsers()` -- `getUserById()` - -**MFA AVAILABLE:** After the password has been submitted, additional authentication methods are loaded. -If the user has set up an additional **single** second factor, it is redirected to add the next factor. Depending on the available method he is redirected to `/otp/time-based`,`/otp/sms?`, `/otp/email?` or `/u2f?`. If the user has multiple second factors, he is redirected to `/mfa` to select his preferred method to continue. - -**NO MFA, USER STATE INITIAL** If the user has no MFA methods and is in an initial state, we redirect to `/password/change` where a new password can be set. - -**NO MFA, FORCE MFA:** If no MFA method is available, and the settings force MFA, the user is sent to `/mfa/set` which prompts to setup a second factor. - -**PROMPT PASSKEY** If the settings do not enforce MFA, we check if passkeys are allowed with `loginSettings?.passkeysType == PasskeysType.ALLOWED` and redirect the user to `/passkey/set` if no passkeys are setup. This step can be skipped. - -If none of the previous conditions apply, we continue to sign in. - -> NOTE: `listAuthenticationMethodTypes()` does not consider different domains for u2f methods or passkeys. The check whether a user should be redirected to one of the pages `/passkey` or `/u2f`, should be extended to use a domain filter (https://github.com/zitadel/zitadel/issues/8615) - -### /password/change - -This page allows to change the password. It is used after a user is in an initial state and is required to change the password, or it can be directly invoked with an active session. - -/password/change - -Requests to the APIs made: - -- `getLoginSettings(org?)` -- `getPasswordComplexitySettings(user?)` -- `getBrandingSettings(org?)` -- `getSession()` -- `setPassword()` - -> NOTE: The request to change the password is using the session of the user itself not the service user, therefore no code is required. - -### /password/set - -This page allows to set a password. It is used after a user has requested to reset the password on the `/password` page. - -/password/set - -Requests to the APIs made: - -- `getLoginSettings(org?)` -- `getPasswordComplexitySettings(user?)` -- `getBrandingSettings(org?)` -- `getUserByID()` -- `setPassword()` - -The page allows to enter a code or be invoked directly from a email link which prefills the code. The user can enter a new password and submit. - -### /otp/[method] - -This page shows a code field to check an otp method. The session of the user is then hydrated with the respective factor. Supported methods are `time-based`, `sms` and `email`. - -/otp/[method] - -Requests to the APIs made: - -- `getBrandingSettings(org?)` -- `getSession()` -- `updateSession()` - -If `email` or `sms` is requested as method, the current session of the user is updated to request the challenge. This will trigger an email or sms which can be entered in the code field. -The `time-based` (TOTP) method does not require a trigger, therefore no `updateSession()` is performed and no resendLink under the code field is shown. - -The submission of the code updates the session and continues to sign in the user. - -### /u2f - -This page requests a webAuthN challenge for the user and updates the session afterwards. - -/u2f - -Requests to the APIs made: - -- `getBrandingSettings(org?)` -- `getSession()` -- `updateSession()` - -When updating the session for the webAuthN challenge, we set `userVerificationRequirement` to `UserVerificationRequirement.DISCOURAGED` as this will request the webAuthN method as second factor and not as primary method. -After updating the session, the user is **always** signed in. :warning: required as this page is a follow up for setting up a u2f method. - -### /passkey - -This page requests a webAuthN challenge for the user and updates the session afterwards. -It is invoked directly after setting up a passkey `/passkey/set` or when loggin in a user after `/loginname`. - -/passkey - -Requests to the APIs made: - -- `getBrandingSettings(org?)` -- `getSession()` -- `updateSession()` - -When updating the session for the webAuthN challenge, we set `userVerificationRequirement` to `UserVerificationRequirement.REQUIRED` as this will request the webAuthN method as primary method to login. -After updating the session, the user is **always** signed in. :warning: required as this page is a follow up for setting up a passkey - -> NOTE: This page currently does not check whether a user contains passkeys. If this method is not available, this page should not be used. - -### /mfa/set - -This page loads login settings and the authentication methods for a user and shows setup options. - -/mfa/set - -Requests to the APIs made: - -- `getBrandingSettings(org?)` -- `getLoginSettings(user.org)` :warning: context taken from session -- `getSession()` -- `listAuthenticationMethodTypes()` -- `getUserByID()` - -If a user has already setup a certain method, a checkbox is shown alongside the button and the button is disabled. -OTP Email and OTP SMS only show up if the user has verified email or phone. -If the user chooses a method he is redirected to one of `/otp/time-based/set`, `/u2f/set`, `/otp/email/set`, or `/otp/sms/set`. -At the moment, U2F methods are hidden if a method is already added on the users resource. Reasoning is that the page should only be invoked for prompts. A self service page which shows up multiple u2f factors is implemented at a later stage. - -> NOTE: The session and therefore the user factor defines which login settings are checked for available options. - -> NOTE: `listAuthenticationMethodTypes()` does not consider different domains for u2f or passkeys. The check whether a user should be redirected to one of the pages `/passkey/set` or `/u2f/set`, should be extended to use a domain filter (https://github.com/zitadel/zitadel/issues/8615) - -### /passkey/set - -This page sets a passkey method for a user. This page can be either enforced, or optional depending on the Login Settings. - - -/passkey/set - -Requests to the APIs made: - -- `getBrandingSettings(org?)` -- `getSession()` -- `createPasskeyRegistrationLink()` TODO: check if this can be used with the session token (mfa required (AUTHZ-Kl3p0)) -- `registerPasskey()` -- `verifyPasskey()` - -If the loginname decides to redirect the user to this page, a button to skip appears which will sign the user in afterwards. -After a passkey is registered, we redirect the user to `/passkey` to verify it again and sign in with the new method. The `createPasskeyRegistrationLink()` uses the token of the session which is determined by the flow. - -> NOTE: this page allows passkeys to be created only if the current session is valid (self service), or no authentication method is set (register). TODO: to be implemented. - -> NOTE: Redirecting the user to `/passkey` will not be required in future and the currently used session will be hydrated directly after registering. (https://github.com/zitadel/zitadel/issues/8611) - -### /otp/time-based/set - -This page registers a time based OTP method for a user. - -/otp/time-based/set - -Requests to the APIs made: - -- `getBrandingSettings(org?)` -- `getSession()` -- `registerTOTP()` -- `verifyTOTP()` - -After the setup is done, the user is redirected to verify the TOTP method on `/otp/time-based`. - -> NOTE: Redirecting the user to `/otp/time-based` will not be required in future and the currently used session will be hydrated directly. (https://github.com/zitadel/zitadel/issues/8611) - -### /otp/email/set /otp/sms/set - -This page registers either an Email OTP method or SMS OTP method for a user. - -Requests to the APIs made: - -- `getBrandingSettings(org?)` -- `getSession()` -- `addOTPEmail()` / `addOTPSMS()` - -This page directly calls `addOTPEmail()` or `addOTPSMS()` when invoked and shows a success message. -Right afterwards, redirects to verify the method. - -### /u2f/set - -This page registers a U2F method for a user. - -/u2f/set - -Requests to the APIs made: - -- `getBrandingSettings(org?)` -- `getSession()` -- `registerU2F()` :warning: TODO: check if this can be used with the session token (mfa required (AUTHZ-Kl3p0)) -- `verifyU2FRegistration()` - -After a u2f method is registered, we redirect the user to `/passkey` to verify it again and sign in with the new method. The `createPasskeyRegistrationLink()` uses the token of the session which is determined by the flow. - -> NOTE: Redirecting the user to `/passkey` will not be required in future and the currently used session will be hydrated directly after registering. (https://github.com/zitadel/zitadel/issues/8611) - -### /register - -This page shows a register page, which gets firstname and lastname of a user as well as the email. It offers to setup a user, using password or passkeys. - -/register - -register with password - -Requests to the APIs made: - -- `listOrganizations()` :warning: TODO: determine the default organization if no context is set -- `getLegalAndSupportSettings(org)` -- `getPasswordComplexitySettings()` -- `getBrandingSettings()` -- `addHumanUser()` -- `createSession()` -- `getSession()` - -To register a user, the organization where the resource will be created is determined first. If no context is provided via url, we fall back to the default organization of the instance. - -**PASSWORD:** If a password is set, the user is created as a resource, then a session using the password check is created immediately. After creating the session, the user is directly logged in and eventually redirected back to the application. - -**PASSKEY:** If passkey is selected, the user is created as a resource first, then a session using the userId is created immediately. This session does not yet contain a check, we therefore redirect the user to setup a passkey at `/passkey/set`. As the passkey set page verifies the passkey right afterwards, the process ends with a signed in user. - -> NOTE: https://github.com/zitadel/zitadel/issues/8616 to determine the default organization of an instance must be implemented in order to correctly use the legal-, login-, branding- and complexitysettings. - -> NOTE: TODO: check which methods are allowed in the login settings, loginSettings.allowUsernamePassword / check for passkey - -### /idp - -This page doubles as /loginname but limits it to choose from IDPs - -/idp - -Requests to the APIs made: - -- `getBrandingSettings(org?)` -- `getActiveIdentityProviders(org?)` -- `startIdentityProviderFlow()` - -### /idp/[method]/success /idp/[method]/failure - -Both /success and /failure pages are designed to intercept the responses from the IDPs and decide on how to continue with the process. - -### /verify - -This page verifies the email to be valid. It page of the login can also be invoked without an active session. -The context of the user is taken from the url and is set in the email template. - -/accounts - -Requests to the APIs made: - -- `getBrandingSettings(org?)` -- `getLoginSettings(org?)` -- `verifyEmail()` - -If the page is invoked with an active session (right after a register with password), the user is signed in or redirected to the loginname if no context is known. - -> NOTE: This page will be extended to support invitations. In such case, authentication methods of the user are loaded and if none available, shown as possible next step (`/passkey/set`, `password/set`). - -### /accounts - -This page shows an overview of all current sessions. -Sessions with invalid token show a red dot on the right side, Valid session a green dot, and its last verified date. - -/accounts - -This page is a starting point for self management, reauthentication, or can be used to clear local sessions. -This page is also shown if used with OIDC and `prompt: select_account`. - -On all pages, where the current user is shown, you can jump to this page. This way, a session can quickly be reused if valid. - -jump to accounts - -### /signedin - -This is a success page which shows a completed login flow for a user, which did navigate to the login without a OIDC auth requrest. From here device authorization flows are completed. It checks if the requestId param of starts with `device_` and then executes the `authorizeOrDenyDeviceAuthorization` command. - -/signedin - -In future, self service options to jump to are shown below, like: - -- change password -- setup passkeys -- setup mfa -- change profile -- logout - -> NOTE: This page has to be explicitly enabled or act as a fallback if no default redirect is set. - -## Currently NOT Supported - -- forceMFA on login settings is not checked for IDPs - -Also note that IDP logins are considered as valid MFA. An additional MFA check will be implemented in future if enforced. diff --git a/console/package.json b/console/package.json index f0f4f639b2..698ea7984e 100644 --- a/console/package.json +++ b/console/package.json @@ -26,7 +26,7 @@ "@angular/platform-browser-dynamic": "^16.2.12", "@angular/router": "^16.2.12", "@angular/service-worker": "^16.2.12", - "@bufbuild/protobuf": "^2.2.2", + "@bufbuild/protobuf": "^2.6.1", "@connectrpc/connect": "^2.0.0", "@connectrpc/connect-web": "^2.0.0", "@ctrl/ngx-codemirror": "^6.1.0", @@ -67,7 +67,7 @@ "@angular/cli": "^16.2.15", "@angular/compiler-cli": "^16.2.5", "@angular/language-service": "^18.2.4", - "@bufbuild/buf": "^1.41.0", + "@bufbuild/buf": "^1.55.1", "@netlify/framework-info": "^9.8.13", "@types/file-saver": "^2.0.7", "@types/google-protobuf": "^3.15.3", diff --git a/console/src/app/modules/policies/oidc-webkeys/oidc-webkeys.component.ts b/console/src/app/modules/policies/oidc-webkeys/oidc-webkeys.component.ts index 16d3f056c1..1b2e8d743d 100644 --- a/console/src/app/modules/policies/oidc-webkeys/oidc-webkeys.component.ts +++ b/console/src/app/modules/policies/oidc-webkeys/oidc-webkeys.component.ts @@ -12,8 +12,6 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { State, WebKey } from '@zitadel/proto/zitadel/webkey/v2beta/key_pb'; import { CreateWebKeyRequestSchema } from '@zitadel/proto/zitadel/webkey/v2beta/webkey_service_pb'; import { RSAHasher, RSABits, ECDSACurve } from '@zitadel/proto/zitadel/webkey/v2beta/key_pb'; -import { NewFeatureService } from 'src/app/services/new-feature.service'; -import { ActivatedRoute, Router } from '@angular/router'; const CACHE_WARNING_MS = 5 * 60 * 1000; // 5 minutes diff --git a/console/src/app/pages/users/user-detail/user-detail/user-detail.component.ts b/console/src/app/pages/users/user-detail/user-detail/user-detail.component.ts index 90de097f35..45ed6cd30a 100644 --- a/console/src/app/pages/users/user-detail/user-detail/user-detail.component.ts +++ b/console/src/app/pages/users/user-detail/user-detail/user-detail.component.ts @@ -412,7 +412,10 @@ export class UserDetailComponent implements OnInit { public sendSetPasswordNotification(user: UserV2): void { this.newMgmtService - .sendHumanResetPasswordNotification(user.userId, SendHumanResetPasswordNotificationRequest_Type.EMAIL) + .sendHumanResetPasswordNotification({ + userId: user.userId, + type: SendHumanResetPasswordNotificationRequest_Type.EMAIL, + }) .then(() => { this.toast.showInfo('USER.TOAST.PASSWORDNOTIFICATIONSENT', true); this.refreshChanges$.emit(); diff --git a/console/src/app/services/action.service.ts b/console/src/app/services/action.service.ts index dabe2faf01..a3aec6b92d 100644 --- a/console/src/app/services/action.service.ts +++ b/console/src/app/services/action.service.ts @@ -5,6 +5,7 @@ import { CreateTargetRequestSchema, CreateTargetResponse, DeleteTargetRequestSchema, + DeleteTargetResponse, GetTargetRequestSchema, GetTargetResponse, ListExecutionFunctionsRequestSchema, @@ -37,7 +38,7 @@ export class ActionService { return this.grpcService.actionNew.createTarget(req); } - public deleteTarget(req: MessageInitShape): Promise { + public deleteTarget(req: MessageInitShape): Promise { return this.grpcService.actionNew.deleteTarget(req); } diff --git a/console/src/app/services/grpc.service.ts b/console/src/app/services/grpc.service.ts index d2add12f41..b8be808f8d 100644 --- a/console/src/app/services/grpc.service.ts +++ b/console/src/app/services/grpc.service.ts @@ -16,12 +16,9 @@ import { ExhaustedGrpcInterceptor } from './interceptors/exhausted.grpc.intercep import { I18nInterceptor } from './interceptors/i18n.interceptor'; import { NewConnectWebOrgInterceptor, OrgInterceptor, OrgInterceptorProvider } from './interceptors/org.interceptor'; import { UserServiceClient } from '../proto/generated/zitadel/user/v2/User_serviceServiceClientPb'; -//@ts-ignore 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 { WebKeyService } from '@zitadel/proto/zitadel/webkey/v2beta/webkey_service_pb'; @@ -77,30 +74,10 @@ export class GrpcService { ], }; - this.auth = new AuthServiceClient( - env.api, - null, - // @ts-ignore - interceptors, - ); - this.mgmt = new ManagementServiceClient( - env.api, - null, - // @ts-ignore - interceptors, - ); - this.admin = new AdminServiceClient( - env.api, - null, - // @ts-ignore - interceptors, - ); - this.user = new UserServiceClient( - env.api, - null, - // @ts-ignore - interceptors, - ); + this.auth = new AuthServiceClient(env.api, null, interceptors); + this.mgmt = new ManagementServiceClient(env.api, null, interceptors); + this.admin = new AdminServiceClient(env.api, null, interceptors); + this.user = new UserServiceClient(env.api, null, interceptors); const transport = createGrpcWebTransport({ baseUrl: env.api, diff --git a/console/src/app/services/new-auth.service.ts b/console/src/app/services/new-auth.service.ts index 4864d8d95f..37f0545459 100644 --- a/console/src/app/services/new-auth.service.ts +++ b/console/src/app/services/new-auth.service.ts @@ -44,27 +44,27 @@ export class NewAuthService { } public listMyMultiFactors(): Promise { - return this.grpcService.authNew.listMyAuthFactors(create(ListMyAuthFactorsRequestSchema), null); + return this.grpcService.authNew.listMyAuthFactors(create(ListMyAuthFactorsRequestSchema)); } public removeMyAuthFactorOTPSMS(): Promise { - return this.grpcService.authNew.removeMyAuthFactorOTPSMS(create(RemoveMyAuthFactorOTPSMSRequestSchema), null); + return this.grpcService.authNew.removeMyAuthFactorOTPSMS(create(RemoveMyAuthFactorOTPSMSRequestSchema)); } public getMyLoginPolicy(): Promise { - return this.grpcService.authNew.getMyLoginPolicy(create(GetMyLoginPolicyRequestSchema), null); + return this.grpcService.authNew.getMyLoginPolicy(create(GetMyLoginPolicyRequestSchema)); } public removeMyMultiFactorOTP(): Promise { - return this.grpcService.authNew.removeMyAuthFactorOTP(create(RemoveMyAuthFactorOTPRequestSchema), null); + return this.grpcService.authNew.removeMyAuthFactorOTP(create(RemoveMyAuthFactorOTPRequestSchema)); } public removeMyMultiFactorU2F(tokenId: string): Promise { - return this.grpcService.authNew.removeMyAuthFactorU2F(create(RemoveMyAuthFactorU2FRequestSchema, { tokenId }), null); + return this.grpcService.authNew.removeMyAuthFactorU2F(create(RemoveMyAuthFactorU2FRequestSchema, { tokenId })); } public removeMyAuthFactorOTPEmail(): Promise { - return this.grpcService.authNew.removeMyAuthFactorOTPEmail(create(RemoveMyAuthFactorOTPEmailRequestSchema), null); + return this.grpcService.authNew.removeMyAuthFactorOTPEmail(create(RemoveMyAuthFactorOTPEmailRequestSchema)); } public getMyPasswordComplexityPolicy(): Promise { diff --git a/console/src/app/services/new-mgmt.service.ts b/console/src/app/services/new-mgmt.service.ts index 6798d25f41..9e0c9dc6e4 100644 --- a/console/src/app/services/new-mgmt.service.ts +++ b/console/src/app/services/new-mgmt.service.ts @@ -64,11 +64,10 @@ export class NewMgmtService { } public sendHumanResetPasswordNotification( - userId: string, - type: SendHumanResetPasswordNotificationRequest_Type, + req: MessageInitShape, ): Promise { return this.grpcService.mgmtNew.sendHumanResetPasswordNotification( - create(SendHumanResetPasswordNotificationRequestSchema, { userId, type }), + create(SendHumanResetPasswordNotificationRequestSchema, req), ); } diff --git a/console/src/app/services/webkeys.service.ts b/console/src/app/services/webkeys.service.ts index 9a26be4712..b70b60da81 100644 --- a/console/src/app/services/webkeys.service.ts +++ b/console/src/app/services/webkeys.service.ts @@ -16,18 +16,18 @@ export class WebKeysService { constructor(private readonly grpcService: GrpcService) {} public ListWebKeys(): Promise { - return this.grpcService.webKey.listWebKeys({}); + return this.grpcService.webKey['listWebKeys']({}); } public DeleteWebKey(id: string): Promise { - return this.grpcService.webKey.deleteWebKey({ id }); + return this.grpcService.webKey['deleteWebKey']({ id }); } public CreateWebKey(req: MessageInitShape): Promise { - return this.grpcService.webKey.createWebKey(req); + return this.grpcService.webKey['createWebKey'](req); } public ActivateWebKey(id: string): Promise { - return this.grpcService.webKey.activateWebKey({ id }); + return this.grpcService.webKey['activateWebKey']({ id }); } } diff --git a/packages/zitadel-client/node/package.json b/packages/zitadel-client/node/package.json new file mode 100644 index 0000000000..0245d755cb --- /dev/null +++ b/packages/zitadel-client/node/package.json @@ -0,0 +1,6 @@ +{ + "name": "@zitadel/client-node", + "main": "../dist/node.js", + "types": "../dist/node.d.ts", + "type": "module" +} diff --git a/packages/zitadel-client/package.json b/packages/zitadel-client/package.json index 0a9684b8c3..9dcdcc324e 100644 --- a/packages/zitadel-client/package.json +++ b/packages/zitadel-client/package.json @@ -13,31 +13,53 @@ "require": "./dist/index.cjs" }, "./v1": { - "types": "./dist/v1.d.ts", + "types": { + "import": "./dist/v1.d.ts", + "require": "./dist/v1.d.cts", + "default": "./dist/v1.d.ts" + }, "import": "./dist/v1.js", "require": "./dist/v1.cjs" }, "./v2": { - "types": "./dist/v2.d.ts", + "types": { + "import": "./dist/v2.d.ts", + "require": "./dist/v2.d.cts", + "default": "./dist/v2.d.ts" + }, "import": "./dist/v2.js", "require": "./dist/v2.cjs" }, "./v3alpha": { - "types": "./dist/v3alpha.d.ts", + "types": { + "import": "./dist/v3alpha.d.ts", + "require": "./dist/v3alpha.d.cts", + "default": "./dist/v3alpha.d.ts" + }, "import": "./dist/v3alpha.js", "require": "./dist/v3alpha.cjs" }, "./node": { - "types": "./dist/node.d.ts", + "types": { + "import": "./dist/node.d.ts", + "require": "./dist/node.d.cts", + "default": "./dist/node.d.ts" + }, "import": "./dist/node.js", "require": "./dist/node.cjs" }, "./web": { - "types": "./dist/web.d.ts", + "types": { + "import": "./dist/web.d.ts", + "require": "./dist/web.d.cts", + "default": "./dist/web.d.ts" + }, "import": "./dist/web.js", "require": "./dist/web.cjs" } }, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", "files": [ "dist/**" ], diff --git a/packages/zitadel-client/v1/package.json b/packages/zitadel-client/v1/package.json new file mode 100644 index 0000000000..653354b919 --- /dev/null +++ b/packages/zitadel-client/v1/package.json @@ -0,0 +1,6 @@ +{ + "name": "@zitadel/client-v1", + "main": "../dist/v1.js", + "types": "../dist/v1.d.ts", + "type": "module" +} diff --git a/packages/zitadel-client/v2/package.json b/packages/zitadel-client/v2/package.json new file mode 100644 index 0000000000..6466dd136c --- /dev/null +++ b/packages/zitadel-client/v2/package.json @@ -0,0 +1,6 @@ +{ + "name": "@zitadel/client-v2", + "main": "../dist/v2.js", + "types": "../dist/v2.d.ts", + "type": "module" +} diff --git a/packages/zitadel-client/v3alpha/package.json b/packages/zitadel-client/v3alpha/package.json new file mode 100644 index 0000000000..27bf54f799 --- /dev/null +++ b/packages/zitadel-client/v3alpha/package.json @@ -0,0 +1,6 @@ +{ + "name": "@zitadel/client-v3alpha", + "main": "../dist/v3alpha.js", + "types": "../dist/v3alpha.d.ts", + "type": "module" +} diff --git a/packages/zitadel-client/web/package.json b/packages/zitadel-client/web/package.json new file mode 100644 index 0000000000..fd55cc9c5c --- /dev/null +++ b/packages/zitadel-client/web/package.json @@ -0,0 +1,6 @@ +{ + "name": "@zitadel/client-web", + "main": "../dist/web.js", + "types": "../dist/web.d.ts", + "type": "module" +} diff --git a/packages/zitadel-proto/.gitignore b/packages/zitadel-proto/.gitignore index 20bdea6767..0a725b8969 100644 --- a/packages/zitadel-proto/.gitignore +++ b/packages/zitadel-proto/.gitignore @@ -3,3 +3,6 @@ google protoc-gen-openapiv2 validate node_modules +cjs +es +types diff --git a/packages/zitadel-proto/buf.gen.yaml b/packages/zitadel-proto/buf.gen.yaml index 84ecfaea9d..9601096d5b 100644 --- a/packages/zitadel-proto/buf.gen.yaml +++ b/packages/zitadel-proto/buf.gen.yaml @@ -3,8 +3,24 @@ managed: enabled: true plugins: - remote: buf.build/bufbuild/es:v2.2.0 - out: . + out: es include_imports: true opt: + - target=js + - json_types=true + - import_extension=js + - remote: buf.build/bufbuild/es:v2.2.0 + out: cjs + include_imports: true + opt: + - target=js + - json_types=true + - import_extension=js + - js_import_style=legacy_commonjs + - remote: buf.build/bufbuild/es:v2.2.0 + out: types + include_imports: true + opt: + - target=dts - json_types=true - import_extension=js diff --git a/packages/zitadel-proto/package.json b/packages/zitadel-proto/package.json index 3ed1bac786..9c4b708b00 100644 --- a/packages/zitadel-proto/package.json +++ b/packages/zitadel-proto/package.json @@ -6,21 +6,76 @@ "access": "public" }, "type": "module", - "files": [ - "zitadel/**", - "validate/**", - "google/**", - "protoc-gen-openapiv2/**" - ], + "main": "./cjs/index.js", + "types": "./types/index.d.ts", + "exports": { + "./zitadel/*": { + "types": "./types/zitadel/*.d.ts", + "import": "./es/zitadel/*.js", + "require": "./cjs/zitadel/*.js" + }, + "./zitadel/*.js": { + "types": "./types/zitadel/*.d.ts", + "import": "./es/zitadel/*.js", + "require": "./cjs/zitadel/*.js" + }, + "./validate/*": { + "types": "./types/validate/*.d.ts", + "import": "./es/validate/*.js", + "require": "./cjs/validate/*.js" + }, + "./validate/*.js": { + "types": "./types/validate/*.d.ts", + "import": "./es/validate/*.js", + "require": "./cjs/validate/*.js" + }, + "./google/*": { + "types": "./types/google/*.d.ts", + "import": "./es/google/*.js", + "require": "./cjs/google/*.js" + }, + "./google/*.js": { + "types": "./types/google/*.d.ts", + "import": "./es/google/*.js", + "require": "./cjs/google/*.js" + }, + "./protoc-gen-openapiv2/*": { + "types": "./types/protoc-gen-openapiv2/*.d.ts", + "import": "./es/protoc-gen-openapiv2/*.js", + "require": "./cjs/protoc-gen-openapiv2/*.js" + }, + "./protoc-gen-openapiv2/*.js": { + "types": "./types/protoc-gen-openapiv2/*.d.ts", + "import": "./es/protoc-gen-openapiv2/*.js", + "require": "./cjs/protoc-gen-openapiv2/*.js" + } + }, + "typesVersions": { + "*": { + "zitadel/*": [ + "./types/zitadel/*" + ], + "validate/*": [ + "./types/validate/*" + ], + "google/*": [ + "./types/google/*" + ], + "protoc-gen-openapiv2/*": [ + "./types/protoc-gen-openapiv2/*" + ] + } + }, "sideEffects": false, "scripts": { "generate": "buf generate ../../proto", - "clean": "rm -rf zitadel .turbo node_modules google protoc-gen-openapiv2 validate" + "clean": "rm -rf zitadel .turbo node_modules google protoc-gen-openapiv2 validate cjs types es" }, "dependencies": { - "@bufbuild/protobuf": "^2.2.2" + "@bufbuild/protobuf": "^2.6.1" }, "devDependencies": { - "@bufbuild/buf": "^1.53.0" + "@bufbuild/buf": "^1.55.1", + "glob": "^11.0.0" } } \ No newline at end of file diff --git a/packages/zitadel-proto/turbo.json b/packages/zitadel-proto/turbo.json index ee259461b7..76e7fc47ad 100644 --- a/packages/zitadel-proto/turbo.json +++ b/packages/zitadel-proto/turbo.json @@ -2,7 +2,15 @@ "extends": ["//"], "tasks": { "generate": { - "outputs": ["zitadel/**"] + "outputs": [ + "zitadel/**", + "google/**", + "validate/**", + "protoc-gen-openapiv2/**", + "cjs/**", + "es/**", + "types/**" + ] } } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e2d8086321..1ec624ad54 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -270,7 +270,7 @@ importers: specifier: ^16.2.12 version: 16.2.12(@angular/common@16.2.12(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3))(rxjs@7.8.2))(@angular/core@16.2.12(rxjs@7.8.2)(zone.js@0.13.3)) '@bufbuild/protobuf': - specifier: ^2.2.2 + specifier: ^2.6.1 version: 2.6.2 '@connectrpc/connect': specifier: ^2.0.0 @@ -388,7 +388,7 @@ importers: specifier: ^18.2.4 version: 18.2.13 '@bufbuild/buf': - specifier: ^1.41.0 + specifier: ^1.55.1 version: 1.55.1 '@netlify/framework-info': specifier: ^9.8.13 @@ -640,12 +640,15 @@ importers: packages/zitadel-proto: dependencies: '@bufbuild/protobuf': - specifier: ^2.2.2 + specifier: ^2.6.1 version: 2.6.2 devDependencies: '@bufbuild/buf': - specifier: ^1.53.0 + specifier: ^1.55.1 version: 1.55.1 + glob: + specifier: ^11.0.0 + version: 11.0.3 packages: @@ -3102,6 +3105,14 @@ packages: '@inkeep/cxkit-types@0.5.96': resolution: {integrity: sha512-ljOudxIY5JC4LLXyAi5hNUfJcQGirmBv4Okup0EczF4tosSDZFG6fzLYXOZ/wNvJ4vNq+TGsXu2yJuAvp9crMA==} + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -8382,6 +8393,11 @@ packages: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true + glob@11.0.3: + resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==} + engines: {node: 20 || >=22} + hasBin: true + glob@7.1.4: resolution: {integrity: sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==} deprecated: Glob versions prior to v9 are no longer supported @@ -9211,6 +9227,10 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jackspeak@4.1.1: + resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} + engines: {node: 20 || >=22} + jake@10.9.2: resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} engines: {node: '>=10'} @@ -9747,6 +9767,10 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.1.0: + resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -10294,6 +10318,10 @@ packages: minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + minimatch@10.0.3: + resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} + engines: {node: 20 || >=22} + minimatch@3.0.5: resolution: {integrity: sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==} @@ -11002,6 +11030,10 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-scurry@2.0.0: + resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==} + engines: {node: 20 || >=22} + path-to-regexp@0.1.12: resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} @@ -18343,6 +18375,12 @@ snapshots: '@inkeep/cxkit-types@0.5.96': {} + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -22829,7 +22867,7 @@ snapshots: copy-webpack-plugin@11.0.0(webpack@5.100.2(@swc/core@1.13.2(@swc/helpers@0.5.17))): dependencies: - fast-glob: 3.3.3 + fast-glob: 3.3.1 glob-parent: 6.0.2 globby: 13.2.2 normalize-path: 3.0.0 @@ -24978,6 +25016,15 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 + glob@11.0.3: + dependencies: + foreground-child: 3.3.1 + jackspeak: 4.1.1 + minimatch: 10.0.3 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 2.0.0 + glob@7.1.4: dependencies: fs.realpath: 1.0.0 @@ -26028,6 +26075,10 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jackspeak@4.1.1: + dependencies: + '@isaacs/cliui': 8.0.2 + jake@10.9.2: dependencies: async: 3.2.6 @@ -26639,6 +26690,8 @@ snapshots: lru-cache@10.4.3: {} + lru-cache@11.1.0: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -27773,6 +27826,10 @@ snapshots: minimalistic-assert@1.0.1: {} + minimatch@10.0.3: + dependencies: + '@isaacs/brace-expansion': 5.0.0 + minimatch@3.0.5: dependencies: brace-expansion: 1.1.12 @@ -28686,6 +28743,11 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + path-scurry@2.0.0: + dependencies: + lru-cache: 11.1.0 + minipass: 7.1.2 + path-to-regexp@0.1.12: {} path-to-regexp@1.9.0: