From 4e43a0fb4e88dab0885147fe7a2199e8b3d24f71 Mon Sep 17 00:00:00 2001 From: martmull Date: Sun, 5 Jul 2026 00:24:12 +0200 Subject: [PATCH] refactor(server): regroup application resolvers by resource and unify install permission flag (#22532) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Part of the app settings architecture cleanup (twentyhq/core-team-issues#2456) — implements the API-surface regroup Charles asked for in #20825 ("in application resolvers we have uninstall, upgrade, findMany, etc. and for some reason install is part of the marketplace, and they are not protected by same guards"). ## Changes **Resolver regroup by resource** (GraphQL operation names and signatures unchanged): - `installApplication` + `installMarketplaceApp` (deprecation preserved) move from the marketplace resolver into `application-install.resolver.ts`, next to `findManyApplications`/`findOneApplication`/`uninstallApplication`. - `uninstallApplication` moves from the manifest resolver into `application-install.resolver.ts`. - `runWorkspaceMigration` is deleted outright (unused — no consumer anywhere in the repo, front/SDK/e2e/docs); the now-empty manifest resolver is deleted. Its `AllMetadataName` GraphQL enum registration moves to `collection-hash.dto.ts` (its remaining consumer). - `generateApplicationToken` moves from the development resolver into `application-oauth.resolver.ts` next to `renewApplicationToken`, keeping its effective guards (`WorkspaceAuthGuard` + `SettingsPermissionGuard(APPLICATIONS)`) and its token-bucket throttle verbatim. - `upgradeApplication` stays in the upgrade resolver (moving it into the install resolver would create a module cycle — the upgrade module imports the install module). - Marketplace resolver now only holds catalog concerns: `findManyMarketplaceApps`, `findMarketplaceAppDetail`, `syncMarketplaceCatalog`. **Permission unification** (the only behavior change): `installApplication`, `installMarketplaceApp` and `upgradeApplication` move from `MARKETPLACE_APPS` to `APPLICATIONS`, matching uninstall and the find queries. Front-end install/upgrade button gating updated accordingly (`SettingsApplicationDetails` / `SettingsAvailableApplicationDetails`). **Module wiring**: `MarketplaceModule` no longer imports `ApplicationInstallModule` (only the moved resolver needed it); `ApplicationInstallModule` now imports `MarketplaceModule` — no cycle. Exception filters follow the moved operations (`ApplicationRegistrationExceptionFilter` on the install resolver; `ApplicationExceptionFilter` on the oauth resolver, which also fixes `renewApplicationToken`'s previously unmapped FORBIDDEN). **Codegen**: `twenty-client-sdk` metadata client regenerated for the new schema ordering (pure reordering — no field changes); all front `graphql:generate` configurations produced zero diffs. ## Explicitly kept (per review discussion) `installMarketplaceApp` (deprecated) and `generateApplicationToken` are kept for SDK back-compat despite having no current consumers. `runWorkspaceMigration` was also consumer-less but, unlike those two, had no back-compat rationale (not a deprecated alias, not a token primitive), so it is removed rather than relocated. ## Deferred follow-ups (guard inconsistencies found in the audit, intentionally NOT changed here) - `findApplicationRegistrationByUniversalIdentifier` uses `NoPermissionGuard` and returns the full registration entity, bypassing the `API_KEYS_AND_WEBHOOKS` gate that `findOneApplicationRegistration` enforces on the same data (SDK CLI `ensure-app-registration` depends on it today). - `upgradeApplication` alone requires `UserAuthGuard` — an API key can install but not upgrade. - `uploadAppTarball` (`MARKETPLACE_APPS`) and `transferApplicationRegistrationOwnership` (`APPLICATIONS`) are flag-inconsistent with the rest of registration CRUD (`API_KEYS_AND_WEBHOOKS`). - `syncMarketplaceCatalog` triggers an instance-wide job but is gated only by a per-workspace settings flag. ## Verification - `npx nx typecheck twenty-server` / `twenty-front` ✓; `lint:diff-with-main` clean for both - `npx jest "application"` in twenty-server: 30 suites / 154 tests passed - Server boots with the new module graph (DI verified at runtime); codegen run against the live server - Repo-wide grep: no remaining imports of the deleted manifest resolver ``<img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg">`` --------- Co-authored-by: Charles Bochet --- .../src/metadata/generated/schema.graphql | 165 +-- .../src/metadata/generated/schema.ts | 428 +++--- .../src/metadata/generated/types.ts | 1261 ++++++++--------- .../src/generated-metadata/graphql.ts | 22 - .../SettingsApplicationDetails.tsx | 2 +- .../SettingsAvailableApplicationDetails.tsx | 2 +- .../application-development.module.ts | 2 - .../application-development.resolver.ts | 23 - .../application-install.module.ts | 2 + .../application-install.resolver.ts | 90 +- .../application-manifest.module.ts | 6 - .../application-manifest.resolver.ts | 82 -- .../dtos/run-workspace-migration.input.ts | 54 - .../marketplace.module.ts | 2 - .../marketplace.resolver.ts | 56 - .../application-oauth.resolver.ts | 36 +- .../application-upgrade.resolver.ts | 2 +- .../dtos/collection-hash.dto.ts | 6 +- 18 files changed, 1027 insertions(+), 1214 deletions(-) delete mode 100644 packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest.resolver.ts delete mode 100644 packages/twenty-server/src/engine/core-modules/application/application-manifest/dtos/run-workspace-migration.input.ts diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql index 1674a092d1..7ff190d3f3 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql @@ -2192,6 +2192,74 @@ type DeletedWorkspaceMember { userWorkspaceId: UUID } +type MarketplaceApp { + id: String! + name: String! + description: String! + author: String! + category: String! + logo: String + sourcePackage: String + isFeatured: Boolean! +} + +type MarketplaceAppRoleObjectPermission { + universalIdentifier: String! + objectUniversalIdentifier: String! + canReadObjectRecords: Boolean + canUpdateObjectRecords: Boolean + canSoftDeleteObjectRecords: Boolean + canDestroyObjectRecords: Boolean +} + +type MarketplaceAppRoleFieldPermission { + universalIdentifier: String! + objectUniversalIdentifier: String! + fieldUniversalIdentifier: String! + canReadFieldValue: Boolean + canUpdateFieldValue: Boolean +} + +type MarketplaceAppRole { + universalIdentifier: String! + label: String! + description: String + icon: String + canUpdateAllSettings: Boolean + canAccessAllTools: Boolean + canReadAllObjectRecords: Boolean + canUpdateAllObjectRecords: Boolean + canSoftDeleteAllObjectRecords: Boolean + canDestroyAllObjectRecords: Boolean + permissionFlagUniversalIdentifiers: [String!] + objectPermissions: [MarketplaceAppRoleObjectPermission!] + fieldPermissions: [MarketplaceAppRoleFieldPermission!] +} + +type MarketplaceAppDetail { + universalIdentifier: String! + id: String! + name: String! + sourceType: ApplicationRegistrationSourceType! + sourcePackage: String + latestAvailableVersion: String + isListed: Boolean! + isFeatured: Boolean! + description: String + author: String + category: String + logo: String + websiteUrl: String + aboutDescription: String + termsUrl: String + emailSupport: String + issueReportUrl: String + screenshots: [String!]! + defaultRoleUniversalIdentifier: String + roles: [MarketplaceAppRole!] + manifest: JSON @deprecated(reason: "Use the explicit MarketplaceAppDetail fields (description, author, roles, ...) instead") +} + type BillingEntitlement { key: BillingEntitlementKey! value: Boolean! @@ -2412,74 +2480,6 @@ type File { createdAt: DateTime! } -type MarketplaceApp { - id: String! - name: String! - description: String! - author: String! - category: String! - logo: String - sourcePackage: String - isFeatured: Boolean! -} - -type MarketplaceAppRoleObjectPermission { - universalIdentifier: String! - objectUniversalIdentifier: String! - canReadObjectRecords: Boolean - canUpdateObjectRecords: Boolean - canSoftDeleteObjectRecords: Boolean - canDestroyObjectRecords: Boolean -} - -type MarketplaceAppRoleFieldPermission { - universalIdentifier: String! - objectUniversalIdentifier: String! - fieldUniversalIdentifier: String! - canReadFieldValue: Boolean - canUpdateFieldValue: Boolean -} - -type MarketplaceAppRole { - universalIdentifier: String! - label: String! - description: String - icon: String - canUpdateAllSettings: Boolean - canAccessAllTools: Boolean - canReadAllObjectRecords: Boolean - canUpdateAllObjectRecords: Boolean - canSoftDeleteAllObjectRecords: Boolean - canDestroyAllObjectRecords: Boolean - permissionFlagUniversalIdentifiers: [String!] - objectPermissions: [MarketplaceAppRoleObjectPermission!] - fieldPermissions: [MarketplaceAppRoleFieldPermission!] -} - -type MarketplaceAppDetail { - universalIdentifier: String! - id: String! - name: String! - sourceType: ApplicationRegistrationSourceType! - sourcePackage: String - latestAvailableVersion: String - isListed: Boolean! - isFeatured: Boolean! - description: String - author: String - category: String - logo: String - websiteUrl: String - aboutDescription: String - termsUrl: String - emailSupport: String - issueReportUrl: String - screenshots: [String!]! - defaultRoleUniversalIdentifier: String - roles: [MarketplaceAppRole!] - manifest: JSON @deprecated(reason: "Use the explicit MarketplaceAppDetail fields (description, author, roles, ...) instead") -} - type PublicDomain { id: UUID! domain: String! @@ -3151,6 +3151,8 @@ type Query { getViewGroup(id: String!): ViewGroup findManyApplications: [Application!]! findOneApplication(id: UUID, universalIdentifier: UUID): Application! + findManyMarketplaceApps: [MarketplaceApp!]! + findMarketplaceAppDetail(universalIdentifier: String!): MarketplaceAppDetail! findApplicationRegistrationByClientId(clientId: String!): PublicApplicationRegistration findApplicationRegistrationByUniversalIdentifier(universalIdentifier: String!): ApplicationRegistration findManyApplicationRegistrations: [ApplicationRegistration!]! @@ -3200,8 +3202,6 @@ type Query { getAddressDetails(placeId: String!, token: String!): PlaceDetailsResult! getUsageAnalytics(input: UsageAnalyticsInput): UsageAnalytics! findManyPublicDomains: [PublicDomain!]! - findManyMarketplaceApps: [MarketplaceApp!]! - findMarketplaceAppDetail(universalIdentifier: String!): MarketplaceAppDetail! } input GetApiKeyInput { @@ -3406,8 +3406,10 @@ type Mutation { updateManyViewGroups(inputs: [UpdateViewGroupInput!]!): [ViewGroup!]! deleteViewGroup(input: DeleteViewGroupInput!): ViewGroup! destroyViewGroup(input: DestroyViewGroupInput!): ViewGroup! - runWorkspaceMigration(workspaceMigration: WorkspaceMigrationInput!): Boolean! + installMarketplaceApp(universalIdentifier: String!, version: String): Boolean! @deprecated(reason: "Use installApplication instead") + installApplication(universalIdentifier: String!, version: String): Application! uninstallApplication(universalIdentifier: String!): Boolean! + syncMarketplaceCatalog: Boolean! createApplicationRegistration(input: CreateApplicationRegistrationInput!): CreateApplicationRegistration! updateApplicationRegistration(input: UpdateApplicationRegistrationInput!): ApplicationRegistration! deleteApplicationRegistration(id: String!): Boolean! @@ -3507,14 +3509,11 @@ type Mutation { deletePublicDomain(domain: String!): Boolean! checkPublicDomainValidRecords(domain: String!): DomainValidRecords createOneAppToken(input: CreateOneAppTokenInput!): AppToken! - installMarketplaceApp(universalIdentifier: String!, version: String): Boolean! @deprecated(reason: "Use installApplication instead") - installApplication(universalIdentifier: String!, version: String): Application! - syncMarketplaceCatalog: Boolean! createDevelopmentApplication(universalIdentifier: String!, name: String!): DevelopmentApplication! - generateApplicationToken(applicationId: UUID!): ApplicationTokenPair! syncApplication(manifest: JSON!, dryRun: Boolean): WorkspaceMigration! uploadApplicationFile(file: Upload!, applicationUniversalIdentifier: String!, fileFolder: FileFolder!, filePath: String!): File! upgradeApplication(appRegistrationId: String!, targetVersion: String!): Boolean! + generateApplicationToken(applicationId: UUID!): ApplicationTokenPair! renewApplicationToken(applicationRefreshToken: String!): ApplicationTokenPair! } @@ -4308,22 +4307,6 @@ input DestroyViewGroupInput { id: UUID! } -input WorkspaceMigrationInput { - actions: [WorkspaceMigrationDeleteActionInput!]! -} - -input WorkspaceMigrationDeleteActionInput { - type: WorkspaceMigrationActionType! - metadataName: AllMetadataName! - universalIdentifier: String! -} - -enum WorkspaceMigrationActionType { - delete - create - update -} - input CreateApplicationRegistrationInput { name: String! universalIdentifier: String diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.ts b/packages/twenty-client-sdk/src/metadata/generated/schema.ts index 54eb587425..9a99374479 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/schema.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.ts @@ -1845,6 +1845,80 @@ export interface DeletedWorkspaceMember { __typename: 'DeletedWorkspaceMember' } +export interface MarketplaceApp { + id: Scalars['String'] + name: Scalars['String'] + description: Scalars['String'] + author: Scalars['String'] + category: Scalars['String'] + logo?: Scalars['String'] + sourcePackage?: Scalars['String'] + isFeatured: Scalars['Boolean'] + __typename: 'MarketplaceApp' +} + +export interface MarketplaceAppRoleObjectPermission { + universalIdentifier: Scalars['String'] + objectUniversalIdentifier: Scalars['String'] + canReadObjectRecords?: Scalars['Boolean'] + canUpdateObjectRecords?: Scalars['Boolean'] + canSoftDeleteObjectRecords?: Scalars['Boolean'] + canDestroyObjectRecords?: Scalars['Boolean'] + __typename: 'MarketplaceAppRoleObjectPermission' +} + +export interface MarketplaceAppRoleFieldPermission { + universalIdentifier: Scalars['String'] + objectUniversalIdentifier: Scalars['String'] + fieldUniversalIdentifier: Scalars['String'] + canReadFieldValue?: Scalars['Boolean'] + canUpdateFieldValue?: Scalars['Boolean'] + __typename: 'MarketplaceAppRoleFieldPermission' +} + +export interface MarketplaceAppRole { + universalIdentifier: Scalars['String'] + label: Scalars['String'] + description?: Scalars['String'] + icon?: Scalars['String'] + canUpdateAllSettings?: Scalars['Boolean'] + canAccessAllTools?: Scalars['Boolean'] + canReadAllObjectRecords?: Scalars['Boolean'] + canUpdateAllObjectRecords?: Scalars['Boolean'] + canSoftDeleteAllObjectRecords?: Scalars['Boolean'] + canDestroyAllObjectRecords?: Scalars['Boolean'] + permissionFlagUniversalIdentifiers?: Scalars['String'][] + objectPermissions?: MarketplaceAppRoleObjectPermission[] + fieldPermissions?: MarketplaceAppRoleFieldPermission[] + __typename: 'MarketplaceAppRole' +} + +export interface MarketplaceAppDetail { + universalIdentifier: Scalars['String'] + id: Scalars['String'] + name: Scalars['String'] + sourceType: ApplicationRegistrationSourceType + sourcePackage?: Scalars['String'] + latestAvailableVersion?: Scalars['String'] + isListed: Scalars['Boolean'] + isFeatured: Scalars['Boolean'] + description?: Scalars['String'] + author?: Scalars['String'] + category?: Scalars['String'] + logo?: Scalars['String'] + websiteUrl?: Scalars['String'] + aboutDescription?: Scalars['String'] + termsUrl?: Scalars['String'] + emailSupport?: Scalars['String'] + issueReportUrl?: Scalars['String'] + screenshots: Scalars['String'][] + defaultRoleUniversalIdentifier?: Scalars['String'] + roles?: MarketplaceAppRole[] + /** @deprecated Use the explicit MarketplaceAppDetail fields (description, author, roles, ...) instead */ + manifest?: Scalars['JSON'] + __typename: 'MarketplaceAppDetail' +} + export interface BillingEntitlement { key: BillingEntitlementKey value: Scalars['Boolean'] @@ -2092,80 +2166,6 @@ export interface File { __typename: 'File' } -export interface MarketplaceApp { - id: Scalars['String'] - name: Scalars['String'] - description: Scalars['String'] - author: Scalars['String'] - category: Scalars['String'] - logo?: Scalars['String'] - sourcePackage?: Scalars['String'] - isFeatured: Scalars['Boolean'] - __typename: 'MarketplaceApp' -} - -export interface MarketplaceAppRoleObjectPermission { - universalIdentifier: Scalars['String'] - objectUniversalIdentifier: Scalars['String'] - canReadObjectRecords?: Scalars['Boolean'] - canUpdateObjectRecords?: Scalars['Boolean'] - canSoftDeleteObjectRecords?: Scalars['Boolean'] - canDestroyObjectRecords?: Scalars['Boolean'] - __typename: 'MarketplaceAppRoleObjectPermission' -} - -export interface MarketplaceAppRoleFieldPermission { - universalIdentifier: Scalars['String'] - objectUniversalIdentifier: Scalars['String'] - fieldUniversalIdentifier: Scalars['String'] - canReadFieldValue?: Scalars['Boolean'] - canUpdateFieldValue?: Scalars['Boolean'] - __typename: 'MarketplaceAppRoleFieldPermission' -} - -export interface MarketplaceAppRole { - universalIdentifier: Scalars['String'] - label: Scalars['String'] - description?: Scalars['String'] - icon?: Scalars['String'] - canUpdateAllSettings?: Scalars['Boolean'] - canAccessAllTools?: Scalars['Boolean'] - canReadAllObjectRecords?: Scalars['Boolean'] - canUpdateAllObjectRecords?: Scalars['Boolean'] - canSoftDeleteAllObjectRecords?: Scalars['Boolean'] - canDestroyAllObjectRecords?: Scalars['Boolean'] - permissionFlagUniversalIdentifiers?: Scalars['String'][] - objectPermissions?: MarketplaceAppRoleObjectPermission[] - fieldPermissions?: MarketplaceAppRoleFieldPermission[] - __typename: 'MarketplaceAppRole' -} - -export interface MarketplaceAppDetail { - universalIdentifier: Scalars['String'] - id: Scalars['String'] - name: Scalars['String'] - sourceType: ApplicationRegistrationSourceType - sourcePackage?: Scalars['String'] - latestAvailableVersion?: Scalars['String'] - isListed: Scalars['Boolean'] - isFeatured: Scalars['Boolean'] - description?: Scalars['String'] - author?: Scalars['String'] - category?: Scalars['String'] - logo?: Scalars['String'] - websiteUrl?: Scalars['String'] - aboutDescription?: Scalars['String'] - termsUrl?: Scalars['String'] - emailSupport?: Scalars['String'] - issueReportUrl?: Scalars['String'] - screenshots: Scalars['String'][] - defaultRoleUniversalIdentifier?: Scalars['String'] - roles?: MarketplaceAppRole[] - /** @deprecated Use the explicit MarketplaceAppDetail fields (description, author, roles, ...) instead */ - manifest?: Scalars['JSON'] - __typename: 'MarketplaceAppDetail' -} - export interface PublicDomain { id: Scalars['UUID'] domain: Scalars['String'] @@ -2763,6 +2763,8 @@ export interface Query { getViewGroup?: ViewGroup findManyApplications: Application[] findOneApplication: Application + findManyMarketplaceApps: MarketplaceApp[] + findMarketplaceAppDetail: MarketplaceAppDetail findApplicationRegistrationByClientId?: PublicApplicationRegistration findApplicationRegistrationByUniversalIdentifier?: ApplicationRegistration findManyApplicationRegistrations: ApplicationRegistration[] @@ -2812,8 +2814,6 @@ export interface Query { getAddressDetails: PlaceDetailsResult getUsageAnalytics: UsageAnalytics findManyPublicDomains: PublicDomain[] - findManyMarketplaceApps: MarketplaceApp[] - findMarketplaceAppDetail: MarketplaceAppDetail __typename: 'Query' } @@ -2938,8 +2938,11 @@ export interface Mutation { updateManyViewGroups: ViewGroup[] deleteViewGroup: ViewGroup destroyViewGroup: ViewGroup - runWorkspaceMigration: Scalars['Boolean'] + /** @deprecated Use installApplication instead */ + installMarketplaceApp: Scalars['Boolean'] + installApplication: Application uninstallApplication: Scalars['Boolean'] + syncMarketplaceCatalog: Scalars['Boolean'] createApplicationRegistration: CreateApplicationRegistration updateApplicationRegistration: ApplicationRegistration deleteApplicationRegistration: Scalars['Boolean'] @@ -3039,23 +3042,17 @@ export interface Mutation { deletePublicDomain: Scalars['Boolean'] checkPublicDomainValidRecords?: DomainValidRecords createOneAppToken: AppToken - /** @deprecated Use installApplication instead */ - installMarketplaceApp: Scalars['Boolean'] - installApplication: Application - syncMarketplaceCatalog: Scalars['Boolean'] createDevelopmentApplication: DevelopmentApplication - generateApplicationToken: ApplicationTokenPair syncApplication: WorkspaceMigration uploadApplicationFile: File upgradeApplication: Scalars['Boolean'] + generateApplicationToken: ApplicationTokenPair renewApplicationToken: ApplicationTokenPair __typename: 'Mutation' } export type FileFolder = 'CorePicture' | 'AgentChat' | 'BuiltLogicFunction' | 'BuiltFrontComponent' | 'PublicAsset' | 'Source' | 'FilesField' | 'Dependencies' | 'Workflow' | 'EmailAttachment' | 'AppTarball' | 'GeneratedSdkClient' | 'Dpa' -export type WorkspaceMigrationActionType = 'delete' | 'create' | 'update' - export type AnalyticsType = 'PAGEVIEW' | 'TRACK' export interface Subscription { @@ -4989,6 +4986,85 @@ export interface DeletedWorkspaceMemberGenqlSelection{ __scalar?: boolean | number } +export interface MarketplaceAppGenqlSelection{ + id?: boolean | number + name?: boolean | number + description?: boolean | number + author?: boolean | number + category?: boolean | number + logo?: boolean | number + sourcePackage?: boolean | number + isFeatured?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface MarketplaceAppRoleObjectPermissionGenqlSelection{ + universalIdentifier?: boolean | number + objectUniversalIdentifier?: boolean | number + canReadObjectRecords?: boolean | number + canUpdateObjectRecords?: boolean | number + canSoftDeleteObjectRecords?: boolean | number + canDestroyObjectRecords?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface MarketplaceAppRoleFieldPermissionGenqlSelection{ + universalIdentifier?: boolean | number + objectUniversalIdentifier?: boolean | number + fieldUniversalIdentifier?: boolean | number + canReadFieldValue?: boolean | number + canUpdateFieldValue?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface MarketplaceAppRoleGenqlSelection{ + universalIdentifier?: boolean | number + label?: boolean | number + description?: boolean | number + icon?: boolean | number + canUpdateAllSettings?: boolean | number + canAccessAllTools?: boolean | number + canReadAllObjectRecords?: boolean | number + canUpdateAllObjectRecords?: boolean | number + canSoftDeleteAllObjectRecords?: boolean | number + canDestroyAllObjectRecords?: boolean | number + permissionFlagUniversalIdentifiers?: boolean | number + objectPermissions?: MarketplaceAppRoleObjectPermissionGenqlSelection + fieldPermissions?: MarketplaceAppRoleFieldPermissionGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface MarketplaceAppDetailGenqlSelection{ + universalIdentifier?: boolean | number + id?: boolean | number + name?: boolean | number + sourceType?: boolean | number + sourcePackage?: boolean | number + latestAvailableVersion?: boolean | number + isListed?: boolean | number + isFeatured?: boolean | number + description?: boolean | number + author?: boolean | number + category?: boolean | number + logo?: boolean | number + websiteUrl?: boolean | number + aboutDescription?: boolean | number + termsUrl?: boolean | number + emailSupport?: boolean | number + issueReportUrl?: boolean | number + screenshots?: boolean | number + defaultRoleUniversalIdentifier?: boolean | number + roles?: MarketplaceAppRoleGenqlSelection + /** @deprecated Use the explicit MarketplaceAppDetail fields (description, author, roles, ...) instead */ + manifest?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + export interface BillingEntitlementGenqlSelection{ key?: boolean | number value?: boolean | number @@ -5268,85 +5344,6 @@ export interface FileGenqlSelection{ __scalar?: boolean | number } -export interface MarketplaceAppGenqlSelection{ - id?: boolean | number - name?: boolean | number - description?: boolean | number - author?: boolean | number - category?: boolean | number - logo?: boolean | number - sourcePackage?: boolean | number - isFeatured?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface MarketplaceAppRoleObjectPermissionGenqlSelection{ - universalIdentifier?: boolean | number - objectUniversalIdentifier?: boolean | number - canReadObjectRecords?: boolean | number - canUpdateObjectRecords?: boolean | number - canSoftDeleteObjectRecords?: boolean | number - canDestroyObjectRecords?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface MarketplaceAppRoleFieldPermissionGenqlSelection{ - universalIdentifier?: boolean | number - objectUniversalIdentifier?: boolean | number - fieldUniversalIdentifier?: boolean | number - canReadFieldValue?: boolean | number - canUpdateFieldValue?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface MarketplaceAppRoleGenqlSelection{ - universalIdentifier?: boolean | number - label?: boolean | number - description?: boolean | number - icon?: boolean | number - canUpdateAllSettings?: boolean | number - canAccessAllTools?: boolean | number - canReadAllObjectRecords?: boolean | number - canUpdateAllObjectRecords?: boolean | number - canSoftDeleteAllObjectRecords?: boolean | number - canDestroyAllObjectRecords?: boolean | number - permissionFlagUniversalIdentifiers?: boolean | number - objectPermissions?: MarketplaceAppRoleObjectPermissionGenqlSelection - fieldPermissions?: MarketplaceAppRoleFieldPermissionGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface MarketplaceAppDetailGenqlSelection{ - universalIdentifier?: boolean | number - id?: boolean | number - name?: boolean | number - sourceType?: boolean | number - sourcePackage?: boolean | number - latestAvailableVersion?: boolean | number - isListed?: boolean | number - isFeatured?: boolean | number - description?: boolean | number - author?: boolean | number - category?: boolean | number - logo?: boolean | number - websiteUrl?: boolean | number - aboutDescription?: boolean | number - termsUrl?: boolean | number - emailSupport?: boolean | number - issueReportUrl?: boolean | number - screenshots?: boolean | number - defaultRoleUniversalIdentifier?: boolean | number - roles?: MarketplaceAppRoleGenqlSelection - /** @deprecated Use the explicit MarketplaceAppDetail fields (description, author, roles, ...) instead */ - manifest?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - export interface PublicDomainGenqlSelection{ id?: boolean | number domain?: boolean | number @@ -5986,6 +5983,8 @@ export interface QueryGenqlSelection{ getViewGroup?: (ViewGroupGenqlSelection & { __args: {id: Scalars['String']} }) findManyApplications?: ApplicationGenqlSelection findOneApplication?: (ApplicationGenqlSelection & { __args?: {id?: (Scalars['UUID'] | null), universalIdentifier?: (Scalars['UUID'] | null)} }) + findManyMarketplaceApps?: MarketplaceAppGenqlSelection + findMarketplaceAppDetail?: (MarketplaceAppDetailGenqlSelection & { __args: {universalIdentifier: Scalars['String']} }) findApplicationRegistrationByClientId?: (PublicApplicationRegistrationGenqlSelection & { __args: {clientId: Scalars['String']} }) findApplicationRegistrationByUniversalIdentifier?: (ApplicationRegistrationGenqlSelection & { __args: {universalIdentifier: Scalars['String']} }) findManyApplicationRegistrations?: ApplicationRegistrationGenqlSelection @@ -6035,8 +6034,6 @@ export interface QueryGenqlSelection{ getAddressDetails?: (PlaceDetailsResultGenqlSelection & { __args: {placeId: Scalars['String'], token: Scalars['String']} }) getUsageAnalytics?: (UsageAnalyticsGenqlSelection & { __args?: {input?: (UsageAnalyticsInput | null)} }) findManyPublicDomains?: PublicDomainGenqlSelection - findManyMarketplaceApps?: MarketplaceAppGenqlSelection - findMarketplaceAppDetail?: (MarketplaceAppDetailGenqlSelection & { __args: {universalIdentifier: Scalars['String']} }) __typename?: boolean | number __scalar?: boolean | number } @@ -6186,8 +6183,11 @@ export interface MutationGenqlSelection{ updateManyViewGroups?: (ViewGroupGenqlSelection & { __args: {inputs: UpdateViewGroupInput[]} }) deleteViewGroup?: (ViewGroupGenqlSelection & { __args: {input: DeleteViewGroupInput} }) destroyViewGroup?: (ViewGroupGenqlSelection & { __args: {input: DestroyViewGroupInput} }) - runWorkspaceMigration?: { __args: {workspaceMigration: WorkspaceMigrationInput} } + /** @deprecated Use installApplication instead */ + installMarketplaceApp?: { __args: {universalIdentifier: Scalars['String'], version?: (Scalars['String'] | null)} } + installApplication?: (ApplicationGenqlSelection & { __args: {universalIdentifier: Scalars['String'], version?: (Scalars['String'] | null)} }) uninstallApplication?: { __args: {universalIdentifier: Scalars['String']} } + syncMarketplaceCatalog?: boolean | number createApplicationRegistration?: (CreateApplicationRegistrationGenqlSelection & { __args: {input: CreateApplicationRegistrationInput} }) updateApplicationRegistration?: (ApplicationRegistrationGenqlSelection & { __args: {input: UpdateApplicationRegistrationInput} }) deleteApplicationRegistration?: { __args: {id: Scalars['String']} } @@ -6287,15 +6287,11 @@ export interface MutationGenqlSelection{ deletePublicDomain?: { __args: {domain: Scalars['String']} } checkPublicDomainValidRecords?: (DomainValidRecordsGenqlSelection & { __args: {domain: Scalars['String']} }) createOneAppToken?: (AppTokenGenqlSelection & { __args: {input: CreateOneAppTokenInput} }) - /** @deprecated Use installApplication instead */ - installMarketplaceApp?: { __args: {universalIdentifier: Scalars['String'], version?: (Scalars['String'] | null)} } - installApplication?: (ApplicationGenqlSelection & { __args: {universalIdentifier: Scalars['String'], version?: (Scalars['String'] | null)} }) - syncMarketplaceCatalog?: boolean | number createDevelopmentApplication?: (DevelopmentApplicationGenqlSelection & { __args: {universalIdentifier: Scalars['String'], name: Scalars['String']} }) - generateApplicationToken?: (ApplicationTokenPairGenqlSelection & { __args: {applicationId: Scalars['UUID']} }) syncApplication?: (WorkspaceMigrationGenqlSelection & { __args: {manifest: Scalars['JSON'], dryRun?: (Scalars['Boolean'] | null)} }) uploadApplicationFile?: (FileGenqlSelection & { __args: {file: Scalars['Upload'], applicationUniversalIdentifier: Scalars['String'], fileFolder: FileFolder, filePath: Scalars['String']} }) upgradeApplication?: { __args: {appRegistrationId: Scalars['String'], targetVersion: Scalars['String']} } + generateApplicationToken?: (ApplicationTokenPairGenqlSelection & { __args: {applicationId: Scalars['UUID']} }) renewApplicationToken?: (ApplicationTokenPairGenqlSelection & { __args: {applicationRefreshToken: Scalars['String']} }) __typename?: boolean | number __scalar?: boolean | number @@ -6571,10 +6567,6 @@ export interface DestroyViewGroupInput { /** The id of the view group to destroy. */ id: Scalars['UUID']} -export interface WorkspaceMigrationInput {actions: WorkspaceMigrationDeleteActionInput[]} - -export interface WorkspaceMigrationDeleteActionInput {type: WorkspaceMigrationActionType,metadataName: AllMetadataName,universalIdentifier: Scalars['String']} - export interface CreateApplicationRegistrationInput {name: Scalars['String'],universalIdentifier?: (Scalars['String'] | null),oAuthRedirectUris?: (Scalars['String'][] | null),oAuthScopes?: (Scalars['String'][] | null)} export interface UpdateApplicationRegistrationInput {id: Scalars['String'],update: UpdateApplicationRegistrationPayload} @@ -7989,6 +7981,46 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null + const MarketplaceApp_possibleTypes: string[] = ['MarketplaceApp'] + export const isMarketplaceApp = (obj?: { __typename?: any } | null): obj is MarketplaceApp => { + if (!obj?.__typename) throw new Error('__typename is missing in "isMarketplaceApp"') + return MarketplaceApp_possibleTypes.includes(obj.__typename) + } + + + + const MarketplaceAppRoleObjectPermission_possibleTypes: string[] = ['MarketplaceAppRoleObjectPermission'] + export const isMarketplaceAppRoleObjectPermission = (obj?: { __typename?: any } | null): obj is MarketplaceAppRoleObjectPermission => { + if (!obj?.__typename) throw new Error('__typename is missing in "isMarketplaceAppRoleObjectPermission"') + return MarketplaceAppRoleObjectPermission_possibleTypes.includes(obj.__typename) + } + + + + const MarketplaceAppRoleFieldPermission_possibleTypes: string[] = ['MarketplaceAppRoleFieldPermission'] + export const isMarketplaceAppRoleFieldPermission = (obj?: { __typename?: any } | null): obj is MarketplaceAppRoleFieldPermission => { + if (!obj?.__typename) throw new Error('__typename is missing in "isMarketplaceAppRoleFieldPermission"') + return MarketplaceAppRoleFieldPermission_possibleTypes.includes(obj.__typename) + } + + + + const MarketplaceAppRole_possibleTypes: string[] = ['MarketplaceAppRole'] + export const isMarketplaceAppRole = (obj?: { __typename?: any } | null): obj is MarketplaceAppRole => { + if (!obj?.__typename) throw new Error('__typename is missing in "isMarketplaceAppRole"') + return MarketplaceAppRole_possibleTypes.includes(obj.__typename) + } + + + + const MarketplaceAppDetail_possibleTypes: string[] = ['MarketplaceAppDetail'] + export const isMarketplaceAppDetail = (obj?: { __typename?: any } | null): obj is MarketplaceAppDetail => { + if (!obj?.__typename) throw new Error('__typename is missing in "isMarketplaceAppDetail"') + return MarketplaceAppDetail_possibleTypes.includes(obj.__typename) + } + + + const BillingEntitlement_possibleTypes: string[] = ['BillingEntitlement'] export const isBillingEntitlement = (obj?: { __typename?: any } | null): obj is BillingEntitlement => { if (!obj?.__typename) throw new Error('__typename is missing in "isBillingEntitlement"') @@ -8277,46 +8309,6 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null - const MarketplaceApp_possibleTypes: string[] = ['MarketplaceApp'] - export const isMarketplaceApp = (obj?: { __typename?: any } | null): obj is MarketplaceApp => { - if (!obj?.__typename) throw new Error('__typename is missing in "isMarketplaceApp"') - return MarketplaceApp_possibleTypes.includes(obj.__typename) - } - - - - const MarketplaceAppRoleObjectPermission_possibleTypes: string[] = ['MarketplaceAppRoleObjectPermission'] - export const isMarketplaceAppRoleObjectPermission = (obj?: { __typename?: any } | null): obj is MarketplaceAppRoleObjectPermission => { - if (!obj?.__typename) throw new Error('__typename is missing in "isMarketplaceAppRoleObjectPermission"') - return MarketplaceAppRoleObjectPermission_possibleTypes.includes(obj.__typename) - } - - - - const MarketplaceAppRoleFieldPermission_possibleTypes: string[] = ['MarketplaceAppRoleFieldPermission'] - export const isMarketplaceAppRoleFieldPermission = (obj?: { __typename?: any } | null): obj is MarketplaceAppRoleFieldPermission => { - if (!obj?.__typename) throw new Error('__typename is missing in "isMarketplaceAppRoleFieldPermission"') - return MarketplaceAppRoleFieldPermission_possibleTypes.includes(obj.__typename) - } - - - - const MarketplaceAppRole_possibleTypes: string[] = ['MarketplaceAppRole'] - export const isMarketplaceAppRole = (obj?: { __typename?: any } | null): obj is MarketplaceAppRole => { - if (!obj?.__typename) throw new Error('__typename is missing in "isMarketplaceAppRole"') - return MarketplaceAppRole_possibleTypes.includes(obj.__typename) - } - - - - const MarketplaceAppDetail_possibleTypes: string[] = ['MarketplaceAppDetail'] - export const isMarketplaceAppDetail = (obj?: { __typename?: any } | null): obj is MarketplaceAppDetail => { - if (!obj?.__typename) throw new Error('__typename is missing in "isMarketplaceAppDetail"') - return MarketplaceAppDetail_possibleTypes.includes(obj.__typename) - } - - - const PublicDomain_possibleTypes: string[] = ['PublicDomain'] export const isPublicDomain = (obj?: { __typename?: any } | null): obj is PublicDomain => { if (!obj?.__typename) throw new Error('__typename is missing in "isPublicDomain"') @@ -9464,12 +9456,6 @@ export const enumFileFolder = { Dpa: 'Dpa' as const } -export const enumWorkspaceMigrationActionType = { - delete: 'delete' as const, - create: 'create' as const, - update: 'update' as const -} - export const enumAnalyticsType = { PAGEVIEW: 'PAGEVIEW' as const, TRACK: 'TRACK' as const diff --git a/packages/twenty-client-sdk/src/metadata/generated/types.ts b/packages/twenty-client-sdk/src/metadata/generated/types.ts index 49cf8b63c9..4696143775 100644 --- a/packages/twenty-client-sdk/src/metadata/generated/types.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/types.ts @@ -61,8 +61,8 @@ export default { 191, 202, 217, - 229, - 235, + 234, + 240, 274, 276, 277, @@ -82,8 +82,7 @@ export default { 354, 361, 362, - 445, - 491 + 488 ], "types": { "BillingProductDTO": { @@ -1838,7 +1837,7 @@ export default { 144 ], "billingEntitlements": [ - 228 + 233 ], "hasValidSignedEnterpriseKey": [ 6 @@ -4279,473 +4278,6 @@ export default { 1 ] }, - "BillingEntitlement": { - "key": [ - 229 - ], - "value": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "BillingEntitlementKey": {}, - "DomainRecord": { - "validationType": [ - 1 - ], - "type": [ - 1 - ], - "status": [ - 1 - ], - "key": [ - 1 - ], - "value": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "DomainValidRecords": { - "id": [ - 3 - ], - "domain": [ - 1 - ], - "records": [ - 230 - ], - "isCustomDomainEnabled": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "UpsertRowLevelPermissionPredicatesResult": { - "predicates": [ - 14 - ], - "predicateGroups": [ - 11 - ], - "__typename": [ - 1 - ] - }, - "LogicFunctionLogs": { - "logs": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "PublicConnectionParametersOutput": { - "host": [ - 1 - ], - "port": [ - 12 - ], - "username": [ - 1 - ], - "connectionSecurity": [ - 235 - ], - "__typename": [ - 1 - ] - }, - "EmailConnectionSecurity": {}, - "PublicImapSmtpCaldavConnectionParameters": { - "IMAP": [ - 234 - ], - "SMTP": [ - 234 - ], - "CALDAV": [ - 234 - ], - "__typename": [ - 1 - ] - }, - "ConnectedAccountPublicDTO": { - "id": [ - 3 - ], - "handle": [ - 1 - ], - "provider": [ - 1 - ], - "lastCredentialsRefreshedAt": [ - 4 - ], - "authFailedAt": [ - 4 - ], - "archivedAt": [ - 4 - ], - "handleAliases": [ - 1 - ], - "scopes": [ - 1 - ], - "lastSignedInAt": [ - 4 - ], - "userWorkspaceId": [ - 3 - ], - "connectionProviderId": [ - 3 - ], - "applicationId": [ - 3 - ], - "name": [ - 1 - ], - "visibility": [ - 1 - ], - "createdAt": [ - 4 - ], - "updatedAt": [ - 4 - ], - "connectionParameters": [ - 236 - ], - "__typename": [ - 1 - ] - }, - "DeleteTwoFactorAuthenticationMethod": { - "success": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "InitiateTwoFactorAuthenticationProvisioning": { - "uri": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "VerifyTwoFactorAuthenticationMethod": { - "success": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "AuthorizeApp": { - "redirectUrl": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "AuthTokenPair": { - "accessOrWorkspaceAgnosticToken": [ - 32 - ], - "refreshToken": [ - 32 - ], - "__typename": [ - 1 - ] - }, - "AvailableWorkspacesAndAccessTokens": { - "tokens": [ - 242 - ], - "availableWorkspaces": [ - 226 - ], - "__typename": [ - 1 - ] - }, - "EmailPasswordResetLink": { - "success": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "GetAuthorizationUrlForSSO": { - "authorizationURL": [ - 1 - ], - "type": [ - 1 - ], - "id": [ - 3 - ], - "__typename": [ - 1 - ] - }, - "InvalidatePassword": { - "success": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "WorkspaceUrlsAndId": { - "workspaceUrls": [ - 171 - ], - "id": [ - 3 - ], - "__typename": [ - 1 - ] - }, - "SignUp": { - "loginToken": [ - 32 - ], - "workspace": [ - 247 - ], - "__typename": [ - 1 - ] - }, - "TransientToken": { - "transientToken": [ - 32 - ], - "__typename": [ - 1 - ] - }, - "ValidatePasswordResetToken": { - "id": [ - 3 - ], - "email": [ - 1 - ], - "hasPassword": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "VerifyEmailAndGetLoginToken": { - "loginToken": [ - 32 - ], - "workspaceUrls": [ - 171 - ], - "__typename": [ - 1 - ] - }, - "SubdomainAvailabilityDTO": { - "isValid": [ - 6 - ], - "available": [ - 6 - ], - "suggestedSubdomain": [ - 1 - ], - "suggestedSubdomains": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "WorkspaceCreationDefaultsDTO": { - "displayName": [ - 1 - ], - "subdomain": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "ApiKeyToken": { - "token": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "AuthTokens": { - "tokens": [ - 242 - ], - "__typename": [ - 1 - ] - }, - "LoginToken": { - "loginToken": [ - 32 - ], - "__typename": [ - 1 - ] - }, - "CheckUserExist": { - "exists": [ - 6 - ], - "availableWorkspacesCount": [ - 12 - ], - "isEmailVerified": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "WorkspaceInviteHashValid": { - "isValid": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "Impersonate": { - "loginToken": [ - 32 - ], - "workspace": [ - 247 - ], - "__typename": [ - 1 - ] - }, - "UsageTimeSeries": { - "date": [ - 1 - ], - "creditsUsed": [ - 12 - ], - "__typename": [ - 1 - ] - }, - "UsageUserDaily": { - "userWorkspaceId": [ - 1 - ], - "dailyUsage": [ - 260 - ], - "__typename": [ - 1 - ] - }, - "UsageAnalytics": { - "usageByUser": [ - 197 - ], - "usageByOperationType": [ - 197 - ], - "usageByModel": [ - 197 - ], - "timeSeries": [ - 260 - ], - "periodStart": [ - 4 - ], - "periodEnd": [ - 4 - ], - "userDailyUsage": [ - 261 - ], - "__typename": [ - 1 - ] - }, - "DevelopmentApplication": { - "id": [ - 1 - ], - "universalIdentifier": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "WorkspaceMigration": { - "applicationUniversalIdentifier": [ - 1 - ], - "actions": [ - 7 - ], - "__typename": [ - 1 - ] - }, - "File": { - "id": [ - 3 - ], - "path": [ - 1 - ], - "size": [ - 12 - ], - "createdAt": [ - 4 - ], - "__typename": [ - 1 - ] - }, "MarketplaceApp": { "id": [ 1 @@ -4853,10 +4385,10 @@ export default { 1 ], "objectPermissions": [ - 267 + 229 ], "fieldPermissions": [ - 268 + 230 ], "__typename": [ 1 @@ -4921,7 +4453,7 @@ export default { 1 ], "roles": [ - 269 + 231 ], "manifest": [ 7 @@ -4930,6 +4462,473 @@ export default { 1 ] }, + "BillingEntitlement": { + "key": [ + 234 + ], + "value": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "BillingEntitlementKey": {}, + "DomainRecord": { + "validationType": [ + 1 + ], + "type": [ + 1 + ], + "status": [ + 1 + ], + "key": [ + 1 + ], + "value": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "DomainValidRecords": { + "id": [ + 3 + ], + "domain": [ + 1 + ], + "records": [ + 235 + ], + "isCustomDomainEnabled": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "UpsertRowLevelPermissionPredicatesResult": { + "predicates": [ + 14 + ], + "predicateGroups": [ + 11 + ], + "__typename": [ + 1 + ] + }, + "LogicFunctionLogs": { + "logs": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "PublicConnectionParametersOutput": { + "host": [ + 1 + ], + "port": [ + 12 + ], + "username": [ + 1 + ], + "connectionSecurity": [ + 240 + ], + "__typename": [ + 1 + ] + }, + "EmailConnectionSecurity": {}, + "PublicImapSmtpCaldavConnectionParameters": { + "IMAP": [ + 239 + ], + "SMTP": [ + 239 + ], + "CALDAV": [ + 239 + ], + "__typename": [ + 1 + ] + }, + "ConnectedAccountPublicDTO": { + "id": [ + 3 + ], + "handle": [ + 1 + ], + "provider": [ + 1 + ], + "lastCredentialsRefreshedAt": [ + 4 + ], + "authFailedAt": [ + 4 + ], + "archivedAt": [ + 4 + ], + "handleAliases": [ + 1 + ], + "scopes": [ + 1 + ], + "lastSignedInAt": [ + 4 + ], + "userWorkspaceId": [ + 3 + ], + "connectionProviderId": [ + 3 + ], + "applicationId": [ + 3 + ], + "name": [ + 1 + ], + "visibility": [ + 1 + ], + "createdAt": [ + 4 + ], + "updatedAt": [ + 4 + ], + "connectionParameters": [ + 241 + ], + "__typename": [ + 1 + ] + }, + "DeleteTwoFactorAuthenticationMethod": { + "success": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "InitiateTwoFactorAuthenticationProvisioning": { + "uri": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "VerifyTwoFactorAuthenticationMethod": { + "success": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "AuthorizeApp": { + "redirectUrl": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "AuthTokenPair": { + "accessOrWorkspaceAgnosticToken": [ + 32 + ], + "refreshToken": [ + 32 + ], + "__typename": [ + 1 + ] + }, + "AvailableWorkspacesAndAccessTokens": { + "tokens": [ + 247 + ], + "availableWorkspaces": [ + 226 + ], + "__typename": [ + 1 + ] + }, + "EmailPasswordResetLink": { + "success": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "GetAuthorizationUrlForSSO": { + "authorizationURL": [ + 1 + ], + "type": [ + 1 + ], + "id": [ + 3 + ], + "__typename": [ + 1 + ] + }, + "InvalidatePassword": { + "success": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "WorkspaceUrlsAndId": { + "workspaceUrls": [ + 171 + ], + "id": [ + 3 + ], + "__typename": [ + 1 + ] + }, + "SignUp": { + "loginToken": [ + 32 + ], + "workspace": [ + 252 + ], + "__typename": [ + 1 + ] + }, + "TransientToken": { + "transientToken": [ + 32 + ], + "__typename": [ + 1 + ] + }, + "ValidatePasswordResetToken": { + "id": [ + 3 + ], + "email": [ + 1 + ], + "hasPassword": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "VerifyEmailAndGetLoginToken": { + "loginToken": [ + 32 + ], + "workspaceUrls": [ + 171 + ], + "__typename": [ + 1 + ] + }, + "SubdomainAvailabilityDTO": { + "isValid": [ + 6 + ], + "available": [ + 6 + ], + "suggestedSubdomain": [ + 1 + ], + "suggestedSubdomains": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "WorkspaceCreationDefaultsDTO": { + "displayName": [ + 1 + ], + "subdomain": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "ApiKeyToken": { + "token": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "AuthTokens": { + "tokens": [ + 247 + ], + "__typename": [ + 1 + ] + }, + "LoginToken": { + "loginToken": [ + 32 + ], + "__typename": [ + 1 + ] + }, + "CheckUserExist": { + "exists": [ + 6 + ], + "availableWorkspacesCount": [ + 12 + ], + "isEmailVerified": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "WorkspaceInviteHashValid": { + "isValid": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "Impersonate": { + "loginToken": [ + 32 + ], + "workspace": [ + 252 + ], + "__typename": [ + 1 + ] + }, + "UsageTimeSeries": { + "date": [ + 1 + ], + "creditsUsed": [ + 12 + ], + "__typename": [ + 1 + ] + }, + "UsageUserDaily": { + "userWorkspaceId": [ + 1 + ], + "dailyUsage": [ + 265 + ], + "__typename": [ + 1 + ] + }, + "UsageAnalytics": { + "usageByUser": [ + 197 + ], + "usageByOperationType": [ + 197 + ], + "usageByModel": [ + 197 + ], + "timeSeries": [ + 265 + ], + "periodStart": [ + 4 + ], + "periodEnd": [ + 4 + ], + "userDailyUsage": [ + 266 + ], + "__typename": [ + 1 + ] + }, + "DevelopmentApplication": { + "id": [ + 1 + ], + "universalIdentifier": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "WorkspaceMigration": { + "applicationUniversalIdentifier": [ + 1 + ], + "actions": [ + 7 + ], + "__typename": [ + 1 + ] + }, + "File": { + "id": [ + 3 + ], + "path": [ + 1 + ], + "size": [ + 12 + ], + "createdAt": [ + 4 + ], + "__typename": [ + 1 + ] + }, "PublicDomain": { "id": [ 3 @@ -5056,7 +5055,7 @@ export default { 4 ], "connectedAccount": [ - 237 + 242 ], "__typename": [ 1 @@ -5219,7 +5218,7 @@ export default { 1 ], "connectionSecurity": [ - 235 + 240 ], "__typename": [ 1 @@ -6523,6 +6522,18 @@ export default { ] } ], + "findManyMarketplaceApps": [ + 228 + ], + "findMarketplaceAppDetail": [ + 232, + { + "universalIdentifier": [ + 1, + "String!" + ] + } + ], "findApplicationRegistrationByClientId": [ 199, { @@ -6610,7 +6621,7 @@ export default { 273 ], "myConnectedAccounts": [ - 237 + 242 ], "getToolIndex": [ 298 @@ -6730,7 +6741,7 @@ export default { } ], "checkUserExists": [ - 257, + 262, { "email": [ 1, @@ -6742,7 +6753,7 @@ export default { } ], "checkWorkspaceInviteHashIsValid": [ - 258, + 263, { "inviteHash": [ 1, @@ -6760,7 +6771,7 @@ export default { } ], "checkWorkspaceSubdomainAvailability": [ - 252, + 257, { "subdomain": [ 1, @@ -6769,10 +6780,10 @@ export default { } ], "getWorkspaceCreationDefaults": [ - 253 + 258 ], "validatePasswordResetToken": [ - 250, + 255, { "passwordResetToken": [ 1, @@ -6864,7 +6875,7 @@ export default { } ], "getUsageAnalytics": [ - 262, + 267, { "input": [ 353 @@ -6874,18 +6885,6 @@ export default { "findManyPublicDomains": [ 271 ], - "findManyMarketplaceApps": [ - 266 - ], - "findMarketplaceAppDetail": [ - 270, - { - "universalIdentifier": [ - 1, - "String!" - ] - } - ], "__typename": [ 1 ] @@ -8016,7 +8015,7 @@ export default { 72 ], "checkCustomDomainValidRecords": [ - 231 + 236 ], "createOneField": [ 43, @@ -8099,12 +8098,27 @@ export default { ] } ], - "runWorkspaceMigration": [ + "installMarketplaceApp": [ 6, { - "workspaceMigration": [ - 443, - "WorkspaceMigrationInput!" + "universalIdentifier": [ + 1, + "String!" + ], + "version": [ + 1 + ] + } + ], + "installApplication": [ + 55, + { + "universalIdentifier": [ + 1, + "String!" + ], + "version": [ + 1 ] } ], @@ -8117,11 +8131,14 @@ export default { ] } ], + "syncMarketplaceCatalog": [ + 6 + ], "createApplicationRegistration": [ 198, { "input": [ - 446, + 443, "CreateApplicationRegistrationInput!" ] } @@ -8130,7 +8147,7 @@ export default { 8, { "input": [ - 447, + 444, "UpdateApplicationRegistrationInput!" ] } @@ -8157,7 +8174,7 @@ export default { 5, { "input": [ - 449, + 446, "CreateApplicationRegistrationVariableInput!" ] } @@ -8166,7 +8183,7 @@ export default { 5, { "input": [ - 450, + 447, "UpdateApplicationRegistrationVariableInput!" ] } @@ -8222,7 +8239,7 @@ export default { 29, { "createRoleInput": [ - 452, + 449, "CreateRoleInput!" ] } @@ -8231,7 +8248,7 @@ export default { 29, { "updateRoleInput": [ - 453, + 450, "UpdateRoleInput!" ] } @@ -8249,7 +8266,7 @@ export default { 16, { "upsertObjectPermissionsInput": [ - 455, + 452, "UpsertObjectPermissionsInput!" ] } @@ -8258,7 +8275,7 @@ export default { 27, { "upsertPermissionFlagsInput": [ - 457, + 454, "UpsertPermissionFlagsInput!" ] } @@ -8267,16 +8284,16 @@ export default { 26, { "upsertFieldPermissionsInput": [ - 458, + 455, "UpsertFieldPermissionsInput!" ] } ], "upsertRowLevelPermissionPredicates": [ - 232, + 237, { "input": [ - 460, + 457, "UpsertRowLevelPermissionPredicatesInput!" ] } @@ -8307,7 +8324,7 @@ export default { 285, { "input": [ - 463, + 460, "SendEmailViaDomainInput!" ] } @@ -8316,7 +8333,7 @@ export default { 287, { "input": [ - 464, + 461, "SendMessageCampaignInput!" ] } @@ -8325,7 +8342,7 @@ export default { 288, { "input": [ - 465, + 462, "CreateUnsubscribeTopicInput!" ] } @@ -8334,7 +8351,7 @@ export default { 288, { "input": [ - 466, + 463, "UpdateUnsubscribeTopicInput!" ] } @@ -8352,7 +8369,7 @@ export default { 275, { "input": [ - 467, + 464, "UpdateMessageChannelInput!" ] } @@ -8361,7 +8378,7 @@ export default { 283, { "input": [ - 469, + 466, "CreateEmailGroupChannelInput!" ] } @@ -8379,7 +8396,7 @@ export default { 273, { "input": [ - 470, + 467, "CreateEmailingDomainInput!" ] } @@ -8403,7 +8420,7 @@ export default { } ], "deleteConnectedAccount": [ - 237, + 242, { "id": [ 3, @@ -8415,7 +8432,7 @@ export default { 300, { "input": [ - 471, + 468, "RunAgentInput!" ] } @@ -8424,7 +8441,7 @@ export default { 297, { "input": [ - 472, + 469, "CreateWebhookInput!" ] } @@ -8433,7 +8450,7 @@ export default { 297, { "input": [ - 473, + 470, "UpdateWebhookInput!" ] } @@ -8451,7 +8468,7 @@ export default { 333, { "input": [ - 475, + 472, "UpdateMessageFolderInput!" ] } @@ -8460,7 +8477,7 @@ export default { 333, { "input": [ - 477, + 474, "UpdateMessageFoldersInput!" ] } @@ -8469,7 +8486,7 @@ export default { 328, { "input": [ - 478, + 475, "UpdateCalendarChannelInput!" ] } @@ -8499,7 +8516,7 @@ export default { 1 ], "fileAttachments": [ - 480, + 477, "[FileAttachmentInput!]" ] } @@ -8528,7 +8545,7 @@ export default { "UUID!" ], "answers": [ - 481, + 478, "[AgentChatQuestionAnswerInput!]!" ], "modelId": [ @@ -8598,7 +8615,7 @@ export default { 316, { "input": [ - 482, + 479, "CreateSkillInput!" ] } @@ -8607,7 +8624,7 @@ export default { 316, { "input": [ - 483, + 480, "UpdateSkillInput!" ] } @@ -8662,16 +8679,16 @@ export default { } ], "getAuthorizationUrlForSSO": [ - 245, + 250, { "input": [ - 484, + 481, "GetAuthorizationUrlForSSOInput!" ] } ], "getLoginTokenFromCredentials": [ - 256, + 261, { "email": [ 1, @@ -8697,7 +8714,7 @@ export default { } ], "signIn": [ - 243, + 248, { "email": [ 1, @@ -8719,7 +8736,7 @@ export default { } ], "verifyEmailAndGetLoginToken": [ - 251, + 256, { "emailVerificationToken": [ 1, @@ -8739,7 +8756,7 @@ export default { } ], "verifyEmailAndGetWorkspaceAgnosticToken": [ - 243, + 248, { "emailVerificationToken": [ 1, @@ -8755,7 +8772,7 @@ export default { } ], "getAuthTokensFromOTP": [ - 255, + 260, { "otp": [ 1, @@ -8775,7 +8792,7 @@ export default { } ], "signUp": [ - 243, + 248, { "email": [ 1, @@ -8797,7 +8814,7 @@ export default { } ], "signUpInWorkspace": [ - 248, + 253, { "email": [ 1, @@ -8828,10 +8845,10 @@ export default { } ], "signUpInNewWorkspace": [ - 248, + 253, { "input": [ - 485 + 482 ] } ], @@ -8849,10 +8866,10 @@ export default { } ], "generateTransientToken": [ - 249 + 254 ], "getAuthTokensFromLoginToken": [ - 255, + 260, { "loginToken": [ 1, @@ -8865,7 +8882,7 @@ export default { } ], "authorizeApp": [ - 241, + 246, { "clientId": [ 1, @@ -8887,7 +8904,7 @@ export default { } ], "renewToken": [ - 255, + 260, { "appToken": [ 1, @@ -8896,7 +8913,7 @@ export default { } ], "generateApiKeyToken": [ - 254, + 259, { "apiKeyId": [ 3, @@ -8912,7 +8929,7 @@ export default { 32 ], "emailPasswordResetLink": [ - 244, + 249, { "email": [ 1, @@ -8924,7 +8941,7 @@ export default { } ], "updatePasswordViaResetToken": [ - 246, + 251, { "passwordResetToken": [ 1, @@ -8937,7 +8954,7 @@ export default { } ], "initiateOTPProvisioning": [ - 239, + 244, { "loginToken": [ 1, @@ -8950,10 +8967,10 @@ export default { } ], "initiateOTPProvisioningForAuthenticatedUser": [ - 239 + 244 ], "deleteTwoFactorAuthenticationMethod": [ - 238, + 243, { "twoFactorAuthenticationMethodId": [ 3, @@ -8962,7 +8979,7 @@ export default { } ], "verifyTwoFactorAuthenticationMethodForAuthenticatedUser": [ - 240, + 245, { "otp": [ 1, @@ -8986,7 +9003,7 @@ export default { 6, { "input": [ - 486, + 483, "UpdateWorkspaceMemberSettingsInput!" ] } @@ -9020,7 +9037,7 @@ export default { 223, { "input": [ - 487, + 484, "SetupOIDCSsoInput!" ] } @@ -9029,7 +9046,7 @@ export default { 223, { "input": [ - 488, + 485, "SetupSAMLSsoInput!" ] } @@ -9038,7 +9055,7 @@ export default { 219, { "input": [ - 489, + 486, "DeleteSsoInput!" ] } @@ -9047,7 +9064,7 @@ export default { 220, { "input": [ - 490, + 487, "EditSsoInput!" ] } @@ -9076,7 +9093,7 @@ export default { 312, { "type": [ - 491, + 488, "AnalyticsType!" ], "name": [ @@ -9100,7 +9117,7 @@ export default { } ], "impersonate": [ - 259, + 264, { "userId": [ 3, @@ -9116,7 +9133,7 @@ export default { 302, { "input": [ - 492, + 489, "CreateCalendarEventInput!" ] } @@ -9125,7 +9142,7 @@ export default { 311, { "input": [ - 493, + 490, "SendEmailInput!" ] } @@ -9147,7 +9164,7 @@ export default { "String!" ], "connectionParameters": [ - 495, + 492, "EmailAccountConnectionParameters!" ], "id": [ @@ -9159,7 +9176,7 @@ export default { 169, { "input": [ - 497, + 494, "UpdateLabPublicFeatureFlagInput!" ] } @@ -9187,7 +9204,7 @@ export default { } ], "checkPublicDomainValidRecords": [ - 231, + 236, { "domain": [ 1, @@ -9199,40 +9216,13 @@ export default { 75, { "input": [ - 498, + 495, "CreateOneAppTokenInput!" ] } ], - "installMarketplaceApp": [ - 6, - { - "universalIdentifier": [ - 1, - "String!" - ], - "version": [ - 1 - ] - } - ], - "installApplication": [ - 55, - { - "universalIdentifier": [ - 1, - "String!" - ], - "version": [ - 1 - ] - } - ], - "syncMarketplaceCatalog": [ - 6 - ], "createDevelopmentApplication": [ - 263, + 268, { "universalIdentifier": [ 1, @@ -9244,17 +9234,8 @@ export default { ] } ], - "generateApplicationToken": [ - 33, - { - "applicationId": [ - 3, - "UUID!" - ] - } - ], "syncApplication": [ - 264, + 269, { "manifest": [ 7, @@ -9266,7 +9247,7 @@ export default { } ], "uploadApplicationFile": [ - 265, + 270, { "file": [ 362, @@ -9299,6 +9280,15 @@ export default { ] } ], + "generateApplicationToken": [ + 33, + { + "applicationId": [ + 3, + "UUID!" + ] + } + ], "renewApplicationToken": [ 33, { @@ -11050,29 +11040,6 @@ export default { 1 ] }, - "WorkspaceMigrationInput": { - "actions": [ - 444 - ], - "__typename": [ - 1 - ] - }, - "WorkspaceMigrationDeleteActionInput": { - "type": [ - 445 - ], - "metadataName": [ - 336 - ], - "universalIdentifier": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "WorkspaceMigrationActionType": {}, "CreateApplicationRegistrationInput": { "name": [ 1 @@ -11095,7 +11062,7 @@ export default { 1 ], "update": [ - 448 + 445 ], "__typename": [ 1 @@ -11146,7 +11113,7 @@ export default { 1 ], "update": [ - 451 + 448 ], "__typename": [ 1 @@ -11212,7 +11179,7 @@ export default { }, "UpdateRoleInput": { "update": [ - 454 + 451 ], "id": [ 3 @@ -11267,7 +11234,7 @@ export default { 3 ], "objectPermissions": [ - 456 + 453 ], "__typename": [ 1 @@ -11309,7 +11276,7 @@ export default { 3 ], "fieldPermissions": [ - 459 + 456 ], "__typename": [ 1 @@ -11340,10 +11307,10 @@ export default { 3 ], "predicates": [ - 461 + 458 ], "predicateGroups": [ - 462 + 459 ], "__typename": [ 1 @@ -11489,7 +11456,7 @@ export default { 3 ], "update": [ - 468 + 465 ], "__typename": [ 1 @@ -11573,7 +11540,7 @@ export default { 3 ], "update": [ - 474 + 471 ], "__typename": [ 1 @@ -11601,7 +11568,7 @@ export default { 3 ], "update": [ - 476 + 473 ], "__typename": [ 1 @@ -11620,7 +11587,7 @@ export default { 3 ], "update": [ - 476 + 473 ], "__typename": [ 1 @@ -11631,7 +11598,7 @@ export default { 3 ], "update": [ - 479 + 476 ], "__typename": [ 1 @@ -11885,7 +11852,7 @@ export default { 1 ], "files": [ - 494 + 491 ], "__typename": [ 1 @@ -11904,13 +11871,13 @@ export default { }, "EmailAccountConnectionParameters": { "IMAP": [ - 496 + 493 ], "SMTP": [ - 496 + 493 ], "CALDAV": [ - 496 + 493 ], "__typename": [ 1 @@ -11930,7 +11897,7 @@ export default { 1 ], "connectionSecurity": [ - 235 + 240 ], "__typename": [ 1 @@ -11949,7 +11916,7 @@ export default { }, "CreateOneAppTokenInput": { "appToken": [ - 499 + 496 ], "__typename": [ 1 @@ -11974,10 +11941,10 @@ export default { } ], "logicFunctionLogs": [ - 233, + 238, { "input": [ - 501, + 498, "LogicFunctionLogsInput!" ] } diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index b9e8442f00..a8ba1d5b1b 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -2657,7 +2657,6 @@ export type Mutation = { rotateApplicationRegistrationClientSecret: RotateClientSecret; runAgent: RunAgentResult; runEvaluationInput: AgentTurn; - runWorkspaceMigration: Scalars['Boolean']['output']; saveImapSmtpCaldavAccount: ImapSmtpCaldavConnectionSuccess; sendChatMessage: SendChatMessageResult; sendEmail: SendEmailOutput; @@ -3425,11 +3424,6 @@ export type MutationRunEvaluationInputArgs = { }; -export type MutationRunWorkspaceMigrationArgs = { - workspaceMigration: WorkspaceMigrationInput; -}; - - export type MutationSaveImapSmtpCaldavAccountArgs = { connectionParameters: EmailAccountConnectionParameters; handle: Scalars['String']['input']; @@ -6401,22 +6395,6 @@ export type WorkspaceMigration = { applicationUniversalIdentifier: Scalars['String']['output']; }; -export enum WorkspaceMigrationActionType { - create = 'create', - delete = 'delete', - update = 'update' -} - -export type WorkspaceMigrationDeleteActionInput = { - metadataName: AllMetadataName; - type: WorkspaceMigrationActionType; - universalIdentifier: Scalars['String']['input']; -}; - -export type WorkspaceMigrationInput = { - actions: Array; -}; - export type WorkspaceNameAndId = { __typename?: 'WorkspaceNameAndId'; displayName?: Maybe; diff --git a/packages/twenty-front/src/pages/settings/applications/SettingsApplicationDetails.tsx b/packages/twenty-front/src/pages/settings/applications/SettingsApplicationDetails.tsx index 2bd512d158..03f01b5d4c 100644 --- a/packages/twenty-front/src/pages/settings/applications/SettingsApplicationDetails.tsx +++ b/packages/twenty-front/src/pages/settings/applications/SettingsApplicationDetails.tsx @@ -111,7 +111,7 @@ export const SettingsApplicationDetails = () => { const { upgrade, isUpgrading } = useUpgradeApplication(); const canInstallMarketplaceApps = useHasPermissionFlag( - PermissionFlagType.MARKETPLACE_APPS, + PermissionFlagType.APPLICATIONS, ); const sourceType = application?.applicationRegistration?.sourceType; diff --git a/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx b/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx index 97584a0182..6e6966ac1a 100644 --- a/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx +++ b/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx @@ -55,7 +55,7 @@ export const SettingsAvailableApplicationDetails = () => { const { upgrade, isUpgrading } = useUpgradeApplication(); const canInstallMarketplaceApps = useHasPermissionFlag( - PermissionFlagType.MARKETPLACE_APPS, + PermissionFlagType.APPLICATIONS, ); const { data: applicationData } = useQuery( diff --git a/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.module.ts b/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.module.ts index 3837a4e24a..a76456ecc3 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.module.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.module.ts @@ -4,7 +4,6 @@ import { ApplicationRegistrationModule } from 'src/engine/core-modules/applicati import { ApplicationManifestModule } from 'src/engine/core-modules/application/application-manifest/application-manifest.module'; import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; import { ApplicationDevelopmentResolver } from 'src/engine/core-modules/application/application-development/application-development.resolver'; -import { TokenModule } from 'src/engine/core-modules/auth/token/token.module'; import { CacheLockModule } from 'src/engine/core-modules/cache-lock/cache-lock.module'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; import { FileStorageModule } from 'src/engine/core-modules/file-storage/file-storage.module'; @@ -21,7 +20,6 @@ import { WorkspaceMigrationGraphqlApiExceptionInterceptor } from 'src/engine/wor CacheLockModule, FeatureFlagModule, SdkClientModule, - TokenModule, FileStorageModule, PermissionsModule, ThrottlerModule, diff --git a/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.resolver.ts index 60b3b57080..7c5186a344 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.resolver.ts @@ -17,13 +17,11 @@ import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorato import { ApplicationInput } from 'src/engine/core-modules/application/application-development/dtos/application.input'; import { CreateDevelopmentApplicationInput } from 'src/engine/core-modules/application/application-development/dtos/create-development-application.input'; import { DevelopmentApplicationDTO } from 'src/engine/core-modules/application/application-development/dtos/development-application.dto'; -import { GenerateApplicationTokenInput } from 'src/engine/core-modules/application/application-development/dtos/generate-application-token.input'; import { UploadApplicationFileInput } from 'src/engine/core-modules/application/application-development/dtos/upload-application-file.input'; import { WorkspaceMigrationDTO } from 'src/engine/core-modules/application/application-development/dtos/workspace-migration.dto'; import { ApplicationExceptionFilter } from 'src/engine/core-modules/application/application-exception-filter'; import { ApplicationSyncService } from 'src/engine/core-modules/application/application-manifest/application-sync.service'; import { resolveManifestAssetUrls } from 'src/engine/core-modules/application/application-marketplace/utils/resolve-manifest-asset-urls.util'; -import { ApplicationTokenPairDTO } from 'src/engine/core-modules/application/application-oauth/dtos/application-token-pair.dto'; import { ApplicationRegistrationVariableService } from 'src/engine/core-modules/application/application-registration-variable/application-registration-variable.service'; import { ApplicationRegistrationService } from 'src/engine/core-modules/application/application-registration/application-registration.service'; import { ApplicationRegistrationSourceType } from 'src/engine/core-modules/application/application-registration/enums/application-registration-source-type.enum'; @@ -32,7 +30,6 @@ import { ApplicationExceptionCode, } from 'src/engine/core-modules/application/application.exception'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; -import { ApplicationTokenService } from 'src/engine/core-modules/auth/token/services/application-token.service'; import { CacheLockService } from 'src/engine/core-modules/cache-lock/cache-lock.service'; import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service'; import { validateFilePath } from 'src/engine/core-modules/file-storage/utils/validate-file-path.util'; @@ -42,8 +39,6 @@ import { SdkClientGenerationService } from 'src/engine/core-modules/sdk-client/s import { ThrottlerService } from 'src/engine/core-modules/throttler/throttler.service'; import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; import { type WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { AuthUserWorkspaceId } from 'src/engine/decorators/auth/auth-user-workspace-id.decorator'; -import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; @@ -65,7 +60,6 @@ const APP_SYNC_LOCK_OPTIONS = { ttl: 60_000, ms: 500, maxRetries: 120 }; ) export class ApplicationDevelopmentResolver { constructor( - private readonly applicationTokenService: ApplicationTokenService, private readonly applicationService: ApplicationService, private readonly applicationSyncService: ApplicationSyncService, private readonly applicationRegistrationService: ApplicationRegistrationService, @@ -114,23 +108,6 @@ export class ApplicationDevelopmentResolver { }; } - @Mutation(() => ApplicationTokenPairDTO) - async generateApplicationToken( - @Args() { applicationId }: GenerateApplicationTokenInput, - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - @AuthUser({ allowUndefined: true }) user?: { id: string }, - @AuthUserWorkspaceId({ allowUndefined: true }) userWorkspaceId?: string, - ): Promise { - await this.throttlePerApplication(applicationId, workspaceId); - - return this.applicationTokenService.generateApplicationTokenPair({ - workspaceId, - applicationId, - userId: user?.id, - userWorkspaceId, - }); - } - @Mutation(() => WorkspaceMigrationDTO) async syncApplication( @Args() { manifest, dryRun }: ApplicationInput, diff --git a/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.module.ts b/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.module.ts index 7cdd031f01..8d8d818621 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.module.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.module.ts @@ -8,6 +8,7 @@ import { ApplicationRegistrationModule } from 'src/engine/core-modules/applicati import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; import { ApplicationManifestModule } from 'src/engine/core-modules/application/application-manifest/application-manifest.module'; import { ApplicationPackageModule } from 'src/engine/core-modules/application/application-package/application-package.module'; +import { MarketplaceModule } from 'src/engine/core-modules/application/application-marketplace/marketplace.module'; import { ApplicationInstallResolver } from 'src/engine/core-modules/application/application-install/application-install.resolver'; import { ApplicationInstallService } from 'src/engine/core-modules/application/application-install/application-install.service'; import { FileStorageModule } from 'src/engine/core-modules/file-storage/file-storage.module'; @@ -23,6 +24,7 @@ import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache ApplicationRegistrationModule, ApplicationManifestModule, ApplicationPackageModule, + MarketplaceModule, CacheLockModule, FeatureFlagModule, LogicFunctionModule, diff --git a/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.resolver.ts index ebacfa62e8..c8a55fa297 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.resolver.ts @@ -4,12 +4,17 @@ import { UseInterceptors, UsePipes, } from '@nestjs/common'; -import { Args, Query } from '@nestjs/graphql'; +import { Args, Mutation, Query } from '@nestjs/graphql'; import { PermissionFlagType } from 'twenty-shared/constants'; import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator'; import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars'; import { ApplicationExceptionFilter } from 'src/engine/core-modules/application/application-exception-filter'; +import { ApplicationInstallService } from 'src/engine/core-modules/application/application-install/application-install.service'; +import { ApplicationSyncService } from 'src/engine/core-modules/application/application-manifest/application-sync.service'; +import { UninstallApplicationInput } from 'src/engine/core-modules/application/application-manifest/dtos/uninstall-application.input'; +import { MarketplaceQueryService } from 'src/engine/core-modules/application/application-marketplace/marketplace-query.service'; +import { ApplicationRegistrationExceptionFilter } from 'src/engine/core-modules/application/application-registration/application-registration-exception-filter'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import { ApplicationDTO } from 'src/engine/core-modules/application/dtos/application.dto'; import { AuthGraphqlApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-graphql-api-exception.filter'; @@ -22,11 +27,20 @@ import { WorkspaceMigrationGraphqlApiExceptionInterceptor } from 'src/engine/wor @UsePipes(ResolverValidationPipe) @MetadataResolver() -@UseFilters(ApplicationExceptionFilter, AuthGraphqlApiExceptionFilter) +@UseFilters( + ApplicationExceptionFilter, + ApplicationRegistrationExceptionFilter, + AuthGraphqlApiExceptionFilter, +) @UseInterceptors(WorkspaceMigrationGraphqlApiExceptionInterceptor) @UseGuards(WorkspaceAuthGuard) export class ApplicationInstallResolver { - constructor(private readonly applicationService: ApplicationService) {} + constructor( + private readonly applicationService: ApplicationService, + private readonly applicationInstallService: ApplicationInstallService, + private readonly applicationSyncService: ApplicationSyncService, + private readonly marketplaceQueryService: MarketplaceQueryService, + ) {} @Query(() => [ApplicationDTO]) @UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS)) @@ -53,4 +67,74 @@ export class ApplicationInstallResolver { workspaceId, }); } + + @Mutation(() => Boolean, { + deprecationReason: 'Use installApplication instead', + }) + @UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS)) + async installMarketplaceApp( + @Args('universalIdentifier') universalIdentifier: string, + @Args('version', { type: () => String, nullable: true }) + version: string | undefined, + @AuthWorkspace() workspace: WorkspaceEntity, + ): Promise { + await this.installRegisteredApplication({ + universalIdentifier, + version, + workspaceId: workspace.id, + }); + + return true; + } + + @Mutation(() => ApplicationDTO) + @UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS)) + async installApplication( + @Args('universalIdentifier') universalIdentifier: string, + @Args('version', { type: () => String, nullable: true }) + version: string | undefined, + @AuthWorkspace() workspace: WorkspaceEntity, + ) { + await this.installRegisteredApplication({ + universalIdentifier, + version, + workspaceId: workspace.id, + }); + + return this.applicationService.findOneApplicationOrThrow({ + universalIdentifier, + workspaceId: workspace.id, + }); + } + + private async installRegisteredApplication(params: { + universalIdentifier: string; + version: string | undefined; + workspaceId: string; + }): Promise { + const registration = + await this.marketplaceQueryService.findRegistrationByUniversalIdentifier( + params.universalIdentifier, + ); + + await this.applicationInstallService.installApplication({ + appRegistrationId: registration.id, + version: params.version, + workspaceId: params.workspaceId, + }); + } + + @Mutation(() => Boolean) + @UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS)) + async uninstallApplication( + @Args() { universalIdentifier }: UninstallApplicationInput, + @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, + ) { + await this.applicationSyncService.uninstallApplication({ + applicationUniversalIdentifier: universalIdentifier, + workspaceId, + }); + + return true; + } } diff --git a/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest.module.ts b/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest.module.ts index 7b26ae71b5..d0919dc6d0 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest.module.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest.module.ts @@ -2,7 +2,6 @@ import { Module } from '@nestjs/common'; import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; import { ApplicationManifestMigrationService } from 'src/engine/core-modules/application/application-manifest/application-manifest-migration.service'; -import { ApplicationManifestResolver } from 'src/engine/core-modules/application/application-manifest/application-manifest.resolver'; import { ComputeApplicationManifestAllUniversalFlatEntityMapsService } from 'src/engine/core-modules/application/application-manifest/services/compute-application-manifest-all-universal-flat-entity-maps.service'; import { ApplicationSyncService } from 'src/engine/core-modules/application/application-manifest/application-sync.service'; import { ApplicationTranslationModule } from 'src/engine/core-modules/application/application-translation/application-translation.module'; @@ -12,8 +11,6 @@ import { FileStorageModule } from 'src/engine/core-modules/file-storage/file-sto import { SecretEncryptionModule } from 'src/engine/core-modules/secret-encryption/secret-encryption.module'; import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module'; import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module'; -import { WorkspaceMigrationGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-graphql-api-exception.interceptor'; -import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/workspace-migration-runner.module'; import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module'; @Module({ @@ -27,14 +24,11 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace SecretEncryptionModule, WorkspaceCacheModule, WorkspaceMigrationModule, - WorkspaceMigrationRunnerModule, ], providers: [ ApplicationManifestMigrationService, - ApplicationManifestResolver, ApplicationSyncService, ComputeApplicationManifestAllUniversalFlatEntityMapsService, - WorkspaceMigrationGraphqlApiExceptionInterceptor, ], exports: [ApplicationManifestMigrationService, ApplicationSyncService], }) diff --git a/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest.resolver.ts deleted file mode 100644 index b771387128..0000000000 --- a/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest.resolver.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { - UseFilters, - UseGuards, - UseInterceptors, - UsePipes, -} from '@nestjs/common'; -import { Args, Mutation } from '@nestjs/graphql'; - -import { PermissionFlagType } from 'twenty-shared/constants'; -import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator'; -import { ApplicationExceptionFilter } from 'src/engine/core-modules/application/application-exception-filter'; -import { ApplicationSyncService } from 'src/engine/core-modules/application/application-manifest/application-sync.service'; -import { RunWorkspaceMigrationInput } from 'src/engine/core-modules/application/application-manifest/dtos/run-workspace-migration.input'; -import { UninstallApplicationInput } from 'src/engine/core-modules/application/application-manifest/dtos/uninstall-application.input'; -import { ApplicationService } from 'src/engine/core-modules/application/application.service'; -import { AuthGraphqlApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-graphql-api-exception.filter'; -import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; -import { type WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; -import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; -import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; -import { enrichCreateWorkspaceMigrationActionsWithIds } from 'src/engine/workspace-manager/workspace-migration/services/utils/enrich-create-workspace-migration-action-with-ids.util'; -import { AllUniversalWorkspaceMigrationAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-action-common'; -import { WorkspaceMigrationGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-graphql-api-exception.interceptor'; -import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/services/workspace-migration-runner.service'; - -@UsePipes(ResolverValidationPipe) -@MetadataResolver() -@UseInterceptors(WorkspaceMigrationGraphqlApiExceptionInterceptor) -@UseFilters(ApplicationExceptionFilter, AuthGraphqlApiExceptionFilter) -@UseGuards(WorkspaceAuthGuard) -export class ApplicationManifestResolver { - constructor( - private readonly applicationService: ApplicationService, - private readonly applicationSyncService: ApplicationSyncService, - private readonly workspaceMigrationRunnerService: WorkspaceMigrationRunnerService, - ) {} - - @Mutation(() => Boolean) - @UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS)) - async runWorkspaceMigration( - @Args() { workspaceMigration: { actions } }: RunWorkspaceMigrationInput, - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ) { - const { workspaceCustomFlatApplication } = - await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow( - { - workspaceId, - }, - ); - - const workspaceMigration = enrichCreateWorkspaceMigrationActionsWithIds({ - workspaceMigration: { - actions: actions as AllUniversalWorkspaceMigrationAction[], - applicationUniversalIdentifier: - workspaceCustomFlatApplication.universalIdentifier, - }, - idByUniversalIdentifierByMetadataName: {}, - }); - - await this.workspaceMigrationRunnerService.run({ - workspaceMigration, - workspaceId, - }); - - return true; - } - - @Mutation(() => Boolean) - @UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS)) - async uninstallApplication( - @Args() { universalIdentifier }: UninstallApplicationInput, - @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, - ) { - await this.applicationSyncService.uninstallApplication({ - applicationUniversalIdentifier: universalIdentifier, - workspaceId, - }); - - return true; - } -} diff --git a/packages/twenty-server/src/engine/core-modules/application/application-manifest/dtos/run-workspace-migration.input.ts b/packages/twenty-server/src/engine/core-modules/application/application-manifest/dtos/run-workspace-migration.input.ts deleted file mode 100644 index 5d8bd305f0..0000000000 --- a/packages/twenty-server/src/engine/core-modules/application/application-manifest/dtos/run-workspace-migration.input.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { ArgsType, Field, InputType, registerEnumType } from '@nestjs/graphql'; - -import { Type } from 'class-transformer'; -import { - ArrayNotEmpty, - IsArray, - IsEnum, - IsUUID, - ValidateNested, -} from 'class-validator'; -import { ALL_METADATA_NAME, AllMetadataName } from 'twenty-shared/metadata'; - -import { WORKSPACE_MIGRATION_ACTION_TYPE } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/constants/workspace-migration-action-type.constant'; - -registerEnumType(ALL_METADATA_NAME, { - name: 'AllMetadataName', -}); - -registerEnumType(WORKSPACE_MIGRATION_ACTION_TYPE, { - name: 'WorkspaceMigrationActionType', -}); - -@InputType() -export class WorkspaceMigrationDeleteActionInput { - @Field(() => WORKSPACE_MIGRATION_ACTION_TYPE) - @IsEnum(WORKSPACE_MIGRATION_ACTION_TYPE) - type: 'delete'; - - @Field(() => ALL_METADATA_NAME) - @IsEnum(ALL_METADATA_NAME) - metadataName: AllMetadataName; - - @Field(() => String) - @IsUUID() - universalIdentifier: string; -} - -@InputType() -export class WorkspaceMigrationInput { - @Field(() => [WorkspaceMigrationDeleteActionInput]) - @IsArray() - @ArrayNotEmpty() - @ValidateNested({ each: true }) - @Type(() => WorkspaceMigrationDeleteActionInput) - actions: WorkspaceMigrationDeleteActionInput[]; -} - -@ArgsType() -export class RunWorkspaceMigrationInput { - @Field(() => WorkspaceMigrationInput) - @ValidateNested() - @Type(() => WorkspaceMigrationInput) - workspaceMigration: WorkspaceMigrationInput; -} diff --git a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.module.ts b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.module.ts index 9b1b03d9d0..e47cde26c5 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.module.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.module.ts @@ -2,7 +2,6 @@ import { Module } from '@nestjs/common'; import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; import { ApplicationRegistrationModule } from 'src/engine/core-modules/application/application-registration/application-registration.module'; -import { ApplicationInstallModule } from 'src/engine/core-modules/application/application-install/application-install.module'; import { MarketplaceCatalogSyncCronCommand } from 'src/engine/core-modules/application/application-marketplace/crons/commands/marketplace-catalog-sync.cron.command'; import { MarketplaceCatalogSyncCronJob } from 'src/engine/core-modules/application/application-marketplace/crons/marketplace-catalog-sync.cron.job'; import { MarketplaceCatalogSyncService } from 'src/engine/core-modules/application/application-marketplace/marketplace-catalog-sync.service'; @@ -18,7 +17,6 @@ import { MarketplaceCatalogSyncCommand } from 'src/engine/core-modules/applicati imports: [ ApplicationModule, ApplicationRegistrationModule, - ApplicationInstallModule, FeatureFlagModule, PermissionsModule, TwentyConfigModule, diff --git a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.resolver.ts index b1082977fb..287d626109 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace.resolver.ts @@ -4,14 +4,9 @@ import { Args, Mutation, Query } from '@nestjs/graphql'; import { PermissionFlagType } from 'twenty-shared/constants'; import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator'; import { ApplicationRegistrationExceptionFilter } from 'src/engine/core-modules/application/application-registration/application-registration-exception-filter'; -import { ApplicationInstallService } from 'src/engine/core-modules/application/application-install/application-install.service'; -import { ApplicationService } from 'src/engine/core-modules/application/application.service'; -import { ApplicationDTO } from 'src/engine/core-modules/application/dtos/application.dto'; import { MarketplaceAppDTO } from 'src/engine/core-modules/application/application-marketplace/dtos/marketplace-app.dto'; import { MarketplaceAppDetailDTO } from 'src/engine/core-modules/application/application-marketplace/dtos/marketplace-app-detail.dto'; import { MarketplaceQueryService } from 'src/engine/core-modules/application/application-marketplace/marketplace-query.service'; -import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard'; import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; @@ -28,8 +23,6 @@ import { MessageQueueService } from 'src/engine/core-modules/message-queue/servi export class MarketplaceResolver { constructor( private readonly marketplaceQueryService: MarketplaceQueryService, - private readonly applicationInstallService: ApplicationInstallService, - private readonly applicationService: ApplicationService, @InjectMessageQueue(MessageQueue.cronQueue) private readonly messageQueueService: MessageQueueService, ) {} @@ -48,55 +41,6 @@ export class MarketplaceResolver { ); } - @Mutation(() => Boolean, { - deprecationReason: 'Use installApplication instead', - }) - @UseGuards(SettingsPermissionGuard(PermissionFlagType.MARKETPLACE_APPS)) - async installMarketplaceApp( - @Args('universalIdentifier') universalIdentifier: string, - @Args('version', { type: () => String, nullable: true }) - version: string | undefined, - @AuthWorkspace() workspace: WorkspaceEntity, - ): Promise { - const registration = - await this.marketplaceQueryService.findRegistrationByUniversalIdentifier( - universalIdentifier, - ); - - await this.applicationInstallService.installApplication({ - appRegistrationId: registration.id, - version, - workspaceId: workspace.id, - }); - - return true; - } - - @Mutation(() => ApplicationDTO) - @UseGuards(SettingsPermissionGuard(PermissionFlagType.MARKETPLACE_APPS)) - async installApplication( - @Args('universalIdentifier') universalIdentifier: string, - @Args('version', { type: () => String, nullable: true }) - version: string | undefined, - @AuthWorkspace() workspace: WorkspaceEntity, - ) { - const registration = - await this.marketplaceQueryService.findRegistrationByUniversalIdentifier( - universalIdentifier, - ); - - await this.applicationInstallService.installApplication({ - appRegistrationId: registration.id, - version, - workspaceId: workspace.id, - }); - - return this.applicationService.findOneApplicationOrThrow({ - universalIdentifier, - workspaceId: workspace.id, - }); - } - @Mutation(() => Boolean) @UseGuards(SettingsPermissionGuard(PermissionFlagType.MARKETPLACE_APPS)) async syncMarketplaceCatalog(): Promise { diff --git a/packages/twenty-server/src/engine/core-modules/application/application-oauth/application-oauth.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application-oauth/application-oauth.resolver.ts index 3e94c06ca6..bf2cc13135 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-oauth/application-oauth.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-oauth/application-oauth.resolver.ts @@ -1,29 +1,63 @@ import { UseFilters, UseGuards, UsePipes } from '@nestjs/common'; import { Args, Mutation } from '@nestjs/graphql'; +import { PermissionFlagType } from 'twenty-shared/constants'; import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator'; import { ApplicationException, ApplicationExceptionCode, } from 'src/engine/core-modules/application/application.exception'; +import { ApplicationExceptionFilter } from 'src/engine/core-modules/application/application-exception-filter'; +import { GenerateApplicationTokenInput } from 'src/engine/core-modules/application/application-development/dtos/generate-application-token.input'; import { ApplicationTokenPairDTO } from 'src/engine/core-modules/application/application-oauth/dtos/application-token-pair.dto'; import { AuthGraphqlApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-graphql-api-exception.filter'; import { ApplicationTokenService } from 'src/engine/core-modules/auth/token/services/application-token.service'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; +import { ThrottlerService } from 'src/engine/core-modules/throttler/throttler.service'; import { type WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; +import { AuthUserWorkspaceId } from 'src/engine/decorators/auth/auth-user-workspace-id.decorator'; +import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator'; import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard'; +import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard'; import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard'; +const APP_TOKEN_RATE_LIMIT_MAX = 30; +const APP_TOKEN_RATE_LIMIT_WINDOW_MS = 30_000; + @UsePipes(ResolverValidationPipe) @MetadataResolver() -@UseFilters(AuthGraphqlApiExceptionFilter) +@UseFilters(ApplicationExceptionFilter, AuthGraphqlApiExceptionFilter) @UseGuards(WorkspaceAuthGuard) export class ApplicationOAuthResolver { constructor( private readonly applicationTokenService: ApplicationTokenService, + private readonly throttlerService: ThrottlerService, ) {} + @Mutation(() => ApplicationTokenPairDTO) + @UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS)) + async generateApplicationToken( + @Args() { applicationId }: GenerateApplicationTokenInput, + @AuthWorkspace() { id: workspaceId }: WorkspaceEntity, + @AuthUser({ allowUndefined: true }) user?: { id: string }, + @AuthUserWorkspaceId({ allowUndefined: true }) userWorkspaceId?: string, + ): Promise { + await this.throttlerService.tokenBucketThrottleOrThrow( + `app-dev:${workspaceId}:${applicationId}`, + 1, + APP_TOKEN_RATE_LIMIT_MAX, + APP_TOKEN_RATE_LIMIT_WINDOW_MS, + ); + + return this.applicationTokenService.generateApplicationTokenPair({ + workspaceId, + applicationId, + userId: user?.id, + userWorkspaceId, + }); + } + @Mutation(() => ApplicationTokenPairDTO) @UseGuards(NoPermissionGuard) async renewApplicationToken( diff --git a/packages/twenty-server/src/engine/core-modules/application/application-upgrade/application-upgrade.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application-upgrade/application-upgrade.resolver.ts index 91a79d7a34..4c31abc6e5 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-upgrade/application-upgrade.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-upgrade/application-upgrade.resolver.ts @@ -21,7 +21,7 @@ export class ApplicationUpgradeResolver { ) {} @Mutation(() => Boolean) - @UseGuards(SettingsPermissionGuard(PermissionFlagType.MARKETPLACE_APPS)) + @UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS)) async upgradeApplication( @Args('appRegistrationId') appRegistrationId: string, @Args('targetVersion') targetVersion: string, diff --git a/packages/twenty-server/src/engine/metadata-modules/minimal-metadata/dtos/collection-hash.dto.ts b/packages/twenty-server/src/engine/metadata-modules/minimal-metadata/dtos/collection-hash.dto.ts index b90a0dc539..0f253cc0af 100644 --- a/packages/twenty-server/src/engine/metadata-modules/minimal-metadata/dtos/collection-hash.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/minimal-metadata/dtos/collection-hash.dto.ts @@ -1,10 +1,14 @@ -import { Field, ObjectType } from '@nestjs/graphql'; +import { Field, ObjectType, registerEnumType } from '@nestjs/graphql'; import { ALL_METADATA_NAME, type AllMetadataName, } from 'twenty-shared/metadata'; +registerEnumType(ALL_METADATA_NAME, { + name: 'AllMetadataName', +}); + @ObjectType('CollectionHash') export class CollectionHashDTO { @Field(() => ALL_METADATA_NAME)