mirror of
https://github.com/twentyhq/twenty
synced 2026-04-21 13:37:22 +00:00
chore: remove draft email feature flag (#19842)
This commit is contained in:
parent
c28c20143b
commit
be9616db60
15 changed files with 18 additions and 95 deletions
|
|
@ -1596,7 +1596,6 @@ enum FeatureFlagKey {
|
|||
IS_PUBLIC_DOMAIN_ENABLED
|
||||
IS_EMAILING_DOMAIN_ENABLED
|
||||
IS_JUNCTION_RELATIONS_ENABLED
|
||||
IS_DRAFT_EMAIL_ENABLED
|
||||
IS_CONNECTED_ACCOUNT_MIGRATED
|
||||
IS_RICH_TEXT_V1_MIGRATED
|
||||
IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED
|
||||
|
|
|
|||
|
|
@ -1294,7 +1294,7 @@ export interface FeatureFlag {
|
|||
__typename: 'FeatureFlag'
|
||||
}
|
||||
|
||||
export type FeatureFlagKey = 'IS_UNIQUE_INDEXES_ENABLED' | 'IS_JSON_FILTER_ENABLED' | 'IS_AI_ENABLED' | 'IS_COMMAND_MENU_ITEM_ENABLED' | 'IS_MARKETPLACE_SETTING_TAB_VISIBLE' | 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' | 'IS_PUBLIC_DOMAIN_ENABLED' | 'IS_EMAILING_DOMAIN_ENABLED' | 'IS_JUNCTION_RELATIONS_ENABLED' | 'IS_DRAFT_EMAIL_ENABLED' | 'IS_CONNECTED_ACCOUNT_MIGRATED' | 'IS_RICH_TEXT_V1_MIGRATED' | 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED' | 'IS_DATASOURCE_MIGRATED'
|
||||
export type FeatureFlagKey = 'IS_UNIQUE_INDEXES_ENABLED' | 'IS_JSON_FILTER_ENABLED' | 'IS_AI_ENABLED' | 'IS_COMMAND_MENU_ITEM_ENABLED' | 'IS_MARKETPLACE_SETTING_TAB_VISIBLE' | 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' | 'IS_PUBLIC_DOMAIN_ENABLED' | 'IS_EMAILING_DOMAIN_ENABLED' | 'IS_JUNCTION_RELATIONS_ENABLED' | 'IS_CONNECTED_ACCOUNT_MIGRATED' | 'IS_RICH_TEXT_V1_MIGRATED' | 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED' | 'IS_DATASOURCE_MIGRATED'
|
||||
|
||||
export interface WorkspaceUrls {
|
||||
customUrl?: Scalars['String']
|
||||
|
|
@ -9516,7 +9516,6 @@ export const enumFeatureFlagKey = {
|
|||
IS_PUBLIC_DOMAIN_ENABLED: 'IS_PUBLIC_DOMAIN_ENABLED' as const,
|
||||
IS_EMAILING_DOMAIN_ENABLED: 'IS_EMAILING_DOMAIN_ENABLED' as const,
|
||||
IS_JUNCTION_RELATIONS_ENABLED: 'IS_JUNCTION_RELATIONS_ENABLED' as const,
|
||||
IS_DRAFT_EMAIL_ENABLED: 'IS_DRAFT_EMAIL_ENABLED' as const,
|
||||
IS_CONNECTED_ACCOUNT_MIGRATED: 'IS_CONNECTED_ACCOUNT_MIGRATED' as const,
|
||||
IS_RICH_TEXT_V1_MIGRATED: 'IS_RICH_TEXT_V1_MIGRATED' as const,
|
||||
IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED: 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED' as const,
|
||||
|
|
|
|||
|
|
@ -1819,7 +1819,6 @@ export enum FeatureFlagKey {
|
|||
IS_COMMAND_MENU_ITEM_ENABLED = 'IS_COMMAND_MENU_ITEM_ENABLED',
|
||||
IS_CONNECTED_ACCOUNT_MIGRATED = 'IS_CONNECTED_ACCOUNT_MIGRATED',
|
||||
IS_DATASOURCE_MIGRATED = 'IS_DATASOURCE_MIGRATED',
|
||||
IS_DRAFT_EMAIL_ENABLED = 'IS_DRAFT_EMAIL_ENABLED',
|
||||
IS_EMAILING_DOMAIN_ENABLED = 'IS_EMAILING_DOMAIN_ENABLED',
|
||||
IS_JSON_FILTER_ENABLED = 'IS_JSON_FILTER_ENABLED',
|
||||
IS_JUNCTION_RELATIONS_ENABLED = 'IS_JUNCTION_RELATIONS_ENABLED',
|
||||
|
|
|
|||
|
|
@ -27,9 +27,6 @@ export const SidePanelWorkflowSelectAction = ({
|
|||
onActionSelected: (selection: WorkflowActionSelection) => void;
|
||||
}) => {
|
||||
const isAiEnabled = useIsFeatureEnabled(FeatureFlagKey.IS_AI_ENABLED);
|
||||
const isDraftEmailEnabled = useIsFeatureEnabled(
|
||||
FeatureFlagKey.IS_DRAFT_EMAIL_ENABLED,
|
||||
);
|
||||
|
||||
const { t } = useLingui();
|
||||
|
||||
|
|
@ -37,10 +34,6 @@ export const SidePanelWorkflowSelectAction = ({
|
|||
|
||||
const toolFunctions = logicFunctions.filter((fn) => fn.isTool === true);
|
||||
|
||||
const coreActions = isDraftEmailEnabled
|
||||
? CORE_ACTIONS
|
||||
: CORE_ACTIONS.filter((action) => action.type !== 'DRAFT_EMAIL');
|
||||
|
||||
const handleActionClick = (actionType: WorkflowActionType) => {
|
||||
onActionSelected({ type: actionType });
|
||||
};
|
||||
|
|
@ -88,7 +81,7 @@ export const SidePanelWorkflowSelectAction = ({
|
|||
{t`Core`}
|
||||
</SidePanelWorkflowSelectStepTitle>
|
||||
<WorkflowActionMenuItems
|
||||
actions={coreActions}
|
||||
actions={CORE_ACTIONS}
|
||||
onClick={handleActionClick}
|
||||
/>
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ import { AuthGuard } from '@nestjs/passport';
|
|||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
import { FeatureFlagKey } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
AuthException,
|
||||
AuthExceptionCode,
|
||||
|
|
@ -13,7 +11,6 @@ import { GoogleAPIsOauthExchangeCodeForTokenStrategy } from 'src/engine/core-mod
|
|||
import { TransientTokenService } from 'src/engine/core-modules/auth/token/services/transient-token.service';
|
||||
import { setRequestExtraParams } from 'src/engine/core-modules/auth/utils/google-apis-set-request-extra-params.util';
|
||||
import { WorkspaceDomainsService } from 'src/engine/core-modules/domain/workspace-domains/services/workspace-domains.service';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { GuardRedirectService } from 'src/engine/core-modules/guard-redirect/services/guard-redirect.service';
|
||||
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
|
@ -29,7 +26,6 @@ export class GoogleAPIsOauthExchangeCodeForTokenGuard extends AuthGuard(
|
|||
@InjectRepository(WorkspaceEntity)
|
||||
private readonly workspaceRepository: Repository<WorkspaceEntity>,
|
||||
private readonly workspaceDomainsService: WorkspaceDomainsService,
|
||||
private readonly featureFlagService: FeatureFlagService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
|
@ -49,22 +45,12 @@ export class GoogleAPIsOauthExchangeCodeForTokenGuard extends AuthGuard(
|
|||
);
|
||||
}
|
||||
|
||||
const { workspaceId } =
|
||||
await this.transientTokenService.verifyTransientToken(
|
||||
state.transientToken,
|
||||
);
|
||||
|
||||
const isDraftEmailEnabled =
|
||||
await this.featureFlagService.isFeatureEnabled(
|
||||
FeatureFlagKey.IS_DRAFT_EMAIL_ENABLED,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
new GoogleAPIsOauthExchangeCodeForTokenStrategy(
|
||||
this.twentyConfigService,
|
||||
isDraftEmailEnabled,
|
||||
await this.transientTokenService.verifyTransientToken(
|
||||
state.transientToken,
|
||||
);
|
||||
|
||||
new GoogleAPIsOauthExchangeCodeForTokenStrategy(this.twentyConfigService);
|
||||
|
||||
setRequestExtraParams(request, {
|
||||
transientToken: state.transientToken,
|
||||
redirectLocation: state.redirectLocation,
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@ import { AuthGuard } from '@nestjs/passport';
|
|||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
import { FeatureFlagKey } from 'twenty-shared/types';
|
||||
|
||||
import {
|
||||
AuthException,
|
||||
AuthExceptionCode,
|
||||
|
|
@ -13,7 +11,6 @@ import { GoogleAPIsOauthRequestCodeStrategy } from 'src/engine/core-modules/auth
|
|||
import { TransientTokenService } from 'src/engine/core-modules/auth/token/services/transient-token.service';
|
||||
import { setRequestExtraParams } from 'src/engine/core-modules/auth/utils/google-apis-set-request-extra-params.util';
|
||||
import { WorkspaceDomainsService } from 'src/engine/core-modules/domain/workspace-domains/services/workspace-domains.service';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { GuardRedirectService } from 'src/engine/core-modules/guard-redirect/services/guard-redirect.service';
|
||||
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
|
@ -27,7 +24,6 @@ export class GoogleAPIsOauthRequestCodeGuard extends AuthGuard('google-apis') {
|
|||
@InjectRepository(WorkspaceEntity)
|
||||
private readonly workspaceRepository: Repository<WorkspaceEntity>,
|
||||
private readonly workspaceDomainsService: WorkspaceDomainsService,
|
||||
private readonly featureFlagService: FeatureFlagService,
|
||||
) {
|
||||
super({
|
||||
prompt: 'select_account',
|
||||
|
|
@ -71,16 +67,7 @@ export class GoogleAPIsOauthRequestCodeGuard extends AuthGuard('google-apis') {
|
|||
);
|
||||
}
|
||||
|
||||
const isDraftEmailEnabled =
|
||||
await this.featureFlagService.isFeatureEnabled(
|
||||
FeatureFlagKey.IS_DRAFT_EMAIL_ENABLED,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
new GoogleAPIsOauthRequestCodeStrategy(
|
||||
this.twentyConfigService,
|
||||
isDraftEmailEnabled,
|
||||
);
|
||||
new GoogleAPIsOauthRequestCodeStrategy(this.twentyConfigService);
|
||||
|
||||
return (await super.canActivate(context)) as boolean;
|
||||
} catch (err) {
|
||||
|
|
|
|||
|
|
@ -92,24 +92,7 @@ describe('GoogleAPIScopesService', () => {
|
|||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should work with the current Google API scopes when draft email is disabled', () => {
|
||||
const actualGoogleScopes = [
|
||||
'https://www.googleapis.com/auth/calendar.events',
|
||||
'https://www.googleapis.com/auth/gmail.readonly',
|
||||
'https://www.googleapis.com/auth/gmail.send',
|
||||
'https://www.googleapis.com/auth/profile.emails.read',
|
||||
'https://www.googleapis.com/auth/userinfo.email',
|
||||
'https://www.googleapis.com/auth/userinfo.profile',
|
||||
'openid',
|
||||
];
|
||||
const expectedScopes = getGoogleApisOauthScopes(false);
|
||||
|
||||
const result = includesExpectedScopes(actualGoogleScopes, expectedScopes);
|
||||
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should work with the current Google API scopes when draft email is enabled', () => {
|
||||
it('should work with the current Google API scopes', () => {
|
||||
const actualGoogleScopes = [
|
||||
'https://www.googleapis.com/auth/calendar.events',
|
||||
'https://www.googleapis.com/auth/gmail.readonly',
|
||||
|
|
@ -120,7 +103,7 @@ describe('GoogleAPIScopesService', () => {
|
|||
'https://www.googleapis.com/auth/userinfo.profile',
|
||||
'openid',
|
||||
];
|
||||
const expectedScopes = getGoogleApisOauthScopes(true);
|
||||
const expectedScopes = getGoogleApisOauthScopes();
|
||||
|
||||
const result = includesExpectedScopes(actualGoogleScopes, expectedScopes);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ export class GoogleAPIScopesService {
|
|||
|
||||
public async getScopesFromGoogleAccessTokenAndCheckIfExpectedScopesArePresent(
|
||||
accessToken: string,
|
||||
isDraftEmailEnabled = false,
|
||||
): Promise<{ scopes: string[]; isValid: boolean }> {
|
||||
try {
|
||||
const httpClient = this.secureHttpClientService.getHttpClient();
|
||||
|
|
@ -41,7 +40,7 @@ export class GoogleAPIScopesService {
|
|||
);
|
||||
|
||||
const scopes = response.data.scope.split(' ');
|
||||
const expectedScopes = getGoogleApisOauthScopes(isDraftEmailEnabled);
|
||||
const expectedScopes = getGoogleApisOauthScopes();
|
||||
|
||||
return {
|
||||
scopes,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import {
|
|||
CalendarChannelSyncStage,
|
||||
type CalendarChannelVisibility,
|
||||
ConnectedAccountProvider,
|
||||
FeatureFlagKey,
|
||||
MessageChannelSyncStage,
|
||||
MessageChannelSyncStatus,
|
||||
type MessageChannelVisibility,
|
||||
|
|
@ -23,7 +22,6 @@ import { CreateMessageChannelService } from 'src/engine/core-modules/auth/servic
|
|||
import { GoogleAPIScopesService } from 'src/engine/core-modules/auth/services/google-apis-scopes';
|
||||
import { GoogleApisServiceAvailabilityService } from 'src/engine/core-modules/auth/services/google-apis-service-availability.service';
|
||||
import { UpdateConnectedAccountOnReconnectService } from 'src/engine/core-modules/auth/services/update-connected-account-on-reconnect.service';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { SyncMessageFoldersService } from 'src/modules/messaging/message-folder-manager/services/sync-message-folders.service';
|
||||
import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decorators/message-queue.decorator';
|
||||
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
|
||||
|
|
@ -67,7 +65,6 @@ export class GoogleAPIsService {
|
|||
private readonly updateConnectedAccountOnReconnectService: UpdateConnectedAccountOnReconnectService,
|
||||
private readonly googleAPIScopesService: GoogleAPIScopesService,
|
||||
private readonly googleApisServiceAvailabilityService: GoogleApisServiceAvailabilityService,
|
||||
private readonly featureFlagService: FeatureFlagService,
|
||||
private readonly syncMessageFoldersService: SyncMessageFoldersService,
|
||||
@InjectRepository(ConnectedAccountEntity)
|
||||
private readonly connectedAccountRepository: Repository<ConnectedAccountEntity>,
|
||||
|
|
@ -108,15 +105,9 @@ export class GoogleAPIsService {
|
|||
'MESSAGING_PROVIDER_GMAIL_ENABLED',
|
||||
);
|
||||
|
||||
const isDraftEmailEnabled = await this.featureFlagService.isFeatureEnabled(
|
||||
FeatureFlagKey.IS_DRAFT_EMAIL_ENABLED,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
const { scopes, isValid } =
|
||||
await this.googleAPIScopesService.getScopesFromGoogleAccessTokenAndCheckIfExpectedScopesArePresent(
|
||||
input.accessToken,
|
||||
isDraftEmailEnabled,
|
||||
);
|
||||
|
||||
if (!isValid) {
|
||||
|
|
|
|||
|
|
@ -14,11 +14,8 @@ export abstract class GoogleAPIsOauthCommonStrategy extends PassportStrategy(
|
|||
Strategy,
|
||||
'google-apis',
|
||||
) {
|
||||
constructor(
|
||||
twentyConfigService: TwentyConfigService,
|
||||
isDraftEmailEnabled = false,
|
||||
) {
|
||||
const scopes = getGoogleApisOauthScopes(isDraftEmailEnabled);
|
||||
constructor(twentyConfigService: TwentyConfigService) {
|
||||
const scopes = getGoogleApisOauthScopes();
|
||||
|
||||
super({
|
||||
clientID: twentyConfigService.get('AUTH_GOOGLE_CLIENT_ID'),
|
||||
|
|
|
|||
|
|
@ -13,11 +13,8 @@ import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twent
|
|||
|
||||
@Injectable()
|
||||
export class GoogleAPIsOauthExchangeCodeForTokenStrategy extends GoogleAPIsOauthCommonStrategy {
|
||||
constructor(
|
||||
twentyConfigService: TwentyConfigService,
|
||||
isDraftEmailEnabled = false,
|
||||
) {
|
||||
super(twentyConfigService, isDraftEmailEnabled);
|
||||
constructor(twentyConfigService: TwentyConfigService) {
|
||||
super(twentyConfigService);
|
||||
}
|
||||
|
||||
async validate(
|
||||
|
|
|
|||
|
|
@ -12,11 +12,8 @@ export type GoogleAPIScopeConfig = {
|
|||
|
||||
@Injectable()
|
||||
export class GoogleAPIsOauthRequestCodeStrategy extends GoogleAPIsOauthCommonStrategy {
|
||||
constructor(
|
||||
twentyConfigService: TwentyConfigService,
|
||||
isDraftEmailEnabled = false,
|
||||
) {
|
||||
super(twentyConfigService, isDraftEmailEnabled);
|
||||
constructor(twentyConfigService: TwentyConfigService) {
|
||||
super(twentyConfigService);
|
||||
}
|
||||
|
||||
// oxlint-disable-next-line @typescripttypescript/no-explicit-any
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/** email, profile and openid permission can be called without the https://www.googleapis.com/auth/ prefix
|
||||
* see https://developers.google.com/identity/protocols/oauth2/scopes
|
||||
*/
|
||||
export const getGoogleApisOauthScopes = (isDraftEmailEnabled = false) => {
|
||||
export const getGoogleApisOauthScopes = () => {
|
||||
return [
|
||||
'email',
|
||||
'profile',
|
||||
|
|
@ -9,8 +9,6 @@ export const getGoogleApisOauthScopes = (isDraftEmailEnabled = false) => {
|
|||
'https://www.googleapis.com/auth/calendar.events',
|
||||
'https://www.googleapis.com/auth/profile.emails.read',
|
||||
'https://www.googleapis.com/auth/gmail.send',
|
||||
...(isDraftEmailEnabled
|
||||
? ['https://www.googleapis.com/auth/gmail.compose']
|
||||
: []),
|
||||
'https://www.googleapis.com/auth/gmail.compose',
|
||||
];
|
||||
};
|
||||
|
|
|
|||
|
|
@ -238,7 +238,6 @@ describe('WorkspaceEntityManager', () => {
|
|||
IS_PUBLIC_DOMAIN_ENABLED: false,
|
||||
IS_EMAILING_DOMAIN_ENABLED: false,
|
||||
IS_JUNCTION_RELATIONS_ENABLED: false,
|
||||
IS_DRAFT_EMAIL_ENABLED: false,
|
||||
IS_CONNECTED_ACCOUNT_MIGRATED: false,
|
||||
IS_RICH_TEXT_V1_MIGRATED: false,
|
||||
IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED: false,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ export enum FeatureFlagKey {
|
|||
IS_PUBLIC_DOMAIN_ENABLED = 'IS_PUBLIC_DOMAIN_ENABLED',
|
||||
IS_EMAILING_DOMAIN_ENABLED = 'IS_EMAILING_DOMAIN_ENABLED',
|
||||
IS_JUNCTION_RELATIONS_ENABLED = 'IS_JUNCTION_RELATIONS_ENABLED',
|
||||
IS_DRAFT_EMAIL_ENABLED = 'IS_DRAFT_EMAIL_ENABLED',
|
||||
IS_CONNECTED_ACCOUNT_MIGRATED = 'IS_CONNECTED_ACCOUNT_MIGRATED',
|
||||
IS_RICH_TEXT_V1_MIGRATED = 'IS_RICH_TEXT_V1_MIGRATED',
|
||||
IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED = 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED',
|
||||
|
|
|
|||
Loading…
Reference in a new issue