diff --git a/packages/twenty-front/src/modules/accounts/constants/MicrosoftSendScope.ts b/packages/twenty-front/src/modules/accounts/constants/MicrosoftSendScope.ts new file mode 100644 index 000000000..0d11833b6 --- /dev/null +++ b/packages/twenty-front/src/modules/accounts/constants/MicrosoftSendScope.ts @@ -0,0 +1 @@ +export const MICROSOFT_SEND_SCOPE = 'Mail.Send'; diff --git a/packages/twenty-front/src/modules/accounts/types/ConnectedAccount.ts b/packages/twenty-front/src/modules/accounts/types/ConnectedAccount.ts index f0ba4f489..34c4d7f2e 100644 --- a/packages/twenty-front/src/modules/accounts/types/ConnectedAccount.ts +++ b/packages/twenty-front/src/modules/accounts/types/ConnectedAccount.ts @@ -1,11 +1,12 @@ import { CalendarChannel } from '@/accounts/types/CalendarChannel'; +import { ConnectedAccountProvider } from 'twenty-shared'; import { MessageChannel } from './MessageChannel'; export type ConnectedAccount = { id: string; handle: string; - provider: string; + provider: ConnectedAccountProvider; accessToken: string; refreshToken: string; accountOwnerId: string; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx index 7364dbe0e..6cba9210c 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx @@ -6,6 +6,7 @@ import { useTriggerApisOAuth } from '@/settings/accounts/hooks/useTriggerApiOAut import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; import { useRecoilValue } from 'recoil'; +import { ConnectedAccountProvider } from 'twenty-shared'; import { Button, Card, @@ -60,7 +61,7 @@ export const SettingsAccountsListEmptyStateCard = ({ Icon={IconGoogle} title={t`Connect with Google`} variant="secondary" - onClick={() => triggerApisOAuth('google')} + onClick={() => triggerApisOAuth(ConnectedAccountProvider.GOOGLE)} /> )} @@ -69,7 +70,7 @@ export const SettingsAccountsListEmptyStateCard = ({ Icon={IconMicrosoft} title={t`Connect with Microsoft`} variant="secondary" - onClick={() => triggerApisOAuth('microsoft')} + onClick={() => triggerApisOAuth(ConnectedAccountProvider.MICROSOFT)} /> )} diff --git a/packages/twenty-front/src/modules/settings/accounts/hooks/useTriggerApiOAuth.ts b/packages/twenty-front/src/modules/settings/accounts/hooks/useTriggerApiOAuth.ts index cdd8046e5..1fe2f31b9 100644 --- a/packages/twenty-front/src/modules/settings/accounts/hooks/useTriggerApiOAuth.ts +++ b/packages/twenty-front/src/modules/settings/accounts/hooks/useTriggerApiOAuth.ts @@ -1,19 +1,20 @@ import { AppPath } from '@/types/AppPath'; import { useCallback } from 'react'; +import { useRedirect } from '@/domain-manager/hooks/useRedirect'; +import { ConnectedAccountProvider } from 'twenty-shared'; import { REACT_APP_SERVER_BASE_URL } from '~/config'; import { CalendarChannelVisibility, MessageChannelVisibility, useGenerateTransientTokenMutation, } from '~/generated/graphql'; -import { useRedirect } from '@/domain-manager/hooks/useRedirect'; -const getProviderUrl = (provider: string) => { +const getProviderUrl = (provider: ConnectedAccountProvider) => { switch (provider) { - case 'google': + case ConnectedAccountProvider.GOOGLE: return 'google-apis'; - case 'microsoft': + case ConnectedAccountProvider.MICROSOFT: return 'microsoft-apis'; default: throw new Error(`Provider ${provider} is not supported`); @@ -26,7 +27,7 @@ export const useTriggerApisOAuth = () => { const triggerApisOAuth = useCallback( async ( - provider: string, + provider: ConnectedAccountProvider, { redirectLocation, messageVisibility, diff --git a/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityAuthProvidersOptionsList.tsx b/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityAuthProvidersOptionsList.tsx index 5684e0810..ddaf43cf0 100644 --- a/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityAuthProvidersOptionsList.tsx +++ b/packages/twenty-front/src/modules/settings/security/components/SettingsSecurityAuthProvidersOptionsList.tsx @@ -7,7 +7,7 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import styled from '@emotion/styled'; import { useLingui } from '@lingui/react/macro'; import { useRecoilState, useRecoilValue } from 'recoil'; -import { capitalize } from 'twenty-shared'; +import { capitalize, ConnectedAccountProvider } from 'twenty-shared'; import { Card, IconGoogle, @@ -136,7 +136,9 @@ export const SettingsSecurityAuthProvidersOptionsList = () => { checked={currentWorkspace.isGoogleAuthEnabled} advancedMode divider - onChange={() => toggleAuthMethod('google')} + onChange={() => + toggleAuthMethod(ConnectedAccountProvider.GOOGLE) + } /> )} {authProviders.microsoft === true && ( @@ -147,7 +149,9 @@ export const SettingsSecurityAuthProvidersOptionsList = () => { checked={currentWorkspace.isMicrosoftAuthEnabled} advancedMode divider - onChange={() => toggleAuthMethod('microsoft')} + onChange={() => + toggleAuthMethod(ConnectedAccountProvider.MICROSOFT) + } /> )} {authProviders.password === true && ( diff --git a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionFormSendEmail.tsx b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionFormSendEmail.tsx index a55552f1f..5e672a74e 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionFormSendEmail.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionFormSendEmail.tsx @@ -14,7 +14,7 @@ import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components import { useTheme } from '@emotion/react'; import { useEffect, useState } from 'react'; import { useRecoilValue } from 'recoil'; -import { isDefined } from 'twenty-shared'; +import { ConnectedAccountProvider, isDefined } from 'twenty-shared'; import { IconPlus, useIcons } from 'twenty-ui'; import { JsonValue } from 'type-fest'; import { useDebouncedCallback } from 'use-debounce'; @@ -71,7 +71,7 @@ export const WorkflowEditActionFormSendEmail = ({ !isDefined(scopes) || !isDefined(scopes.find((scope) => scope === GMAIL_SEND_SCOPE)) ) { - await triggerApisOAuth('google', { + await triggerApisOAuth(ConnectedAccountProvider.GOOGLE, { redirectLocation: redirectUrl, loginHint: connectedAccount.handle, }); @@ -200,7 +200,7 @@ export const WorkflowEditActionFormSendEmail = ({ options={connectedAccountOptions} callToActionButton={{ onClick: () => - triggerApisOAuth('google', { + triggerApisOAuth(ConnectedAccountProvider.GOOGLE, { redirectLocation: redirectUrl, }), Icon: IconPlus, diff --git a/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/services/calendar-get-events.service.ts b/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/services/calendar-get-events.service.ts index 6704fa355..e504d598e 100644 --- a/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/services/calendar-get-events.service.ts +++ b/packages/twenty-server/src/modules/calendar/calendar-event-import-manager/services/calendar-get-events.service.ts @@ -1,5 +1,7 @@ import { Injectable } from '@nestjs/common'; +import { ConnectedAccountProvider } from 'twenty-shared'; + import { GoogleCalendarGetEventsService } from 'src/modules/calendar/calendar-event-import-manager/drivers/google-calendar/services/google-calendar-get-events.service'; import { MicrosoftCalendarGetEventsService } from 'src/modules/calendar/calendar-event-import-manager/drivers/microsoft-calendar/services/microsoft-calendar-get-events.service'; import { @@ -31,12 +33,12 @@ export class CalendarGetCalendarEventsService { syncCursor?: string, ): Promise { switch (connectedAccount.provider) { - case 'google': + case ConnectedAccountProvider.GOOGLE: return this.googleCalendarGetEventsService.getCalendarEvents( connectedAccount, syncCursor, ); - case 'microsoft': + case ConnectedAccountProvider.MICROSOFT: return this.microsoftCalendarGetEventsService.getCalendarEvents( connectedAccount, syncCursor, diff --git a/packages/twenty-server/src/modules/connected-account/email-alias-manager/services/email-alias-manager.service.ts b/packages/twenty-server/src/modules/connected-account/email-alias-manager/services/email-alias-manager.service.ts index 64882284a..979875c36 100644 --- a/packages/twenty-server/src/modules/connected-account/email-alias-manager/services/email-alias-manager.service.ts +++ b/packages/twenty-server/src/modules/connected-account/email-alias-manager/services/email-alias-manager.service.ts @@ -1,5 +1,7 @@ import { Injectable } from '@nestjs/common'; +import { assertUnreachable, ConnectedAccountProvider } from 'twenty-shared'; + import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager'; import { GoogleEmailAliasManagerService } from 'src/modules/connected-account/email-alias-manager/drivers/google/google-email-alias-manager.service'; import { MicrosoftEmailAliasManagerService } from 'src/modules/connected-account/email-alias-manager/drivers/microsoft/microsoft-email-alias-manager.service'; @@ -19,20 +21,21 @@ export class EmailAliasManagerService { let handleAliases: string[]; switch (connectedAccount.provider) { - case 'microsoft': + case ConnectedAccountProvider.MICROSOFT: handleAliases = await this.microsoftEmailAliasManagerService.getHandleAliases( connectedAccount, ); break; - case 'google': + case ConnectedAccountProvider.GOOGLE: handleAliases = await this.googleEmailAliasManagerService.getHandleAliases( connectedAccount, ); break; default: - throw new Error( + assertUnreachable( + connectedAccount.provider, `Email alias manager for provider ${connectedAccount.provider} is not implemented`, ); } diff --git a/packages/twenty-server/src/modules/connected-account/oauth2-client-manager/services/oauth2-client-manager.service.ts b/packages/twenty-server/src/modules/connected-account/oauth2-client-manager/services/oauth2-client-manager.service.ts index 9585ce5a8..942fdc436 100644 --- a/packages/twenty-server/src/modules/connected-account/oauth2-client-manager/services/oauth2-client-manager.service.ts +++ b/packages/twenty-server/src/modules/connected-account/oauth2-client-manager/services/oauth2-client-manager.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@nestjs/common'; import { OAuth2Client } from 'google-auth-library'; +import { ConnectedAccountProvider } from 'twenty-shared'; import { GoogleOAuth2ClientManagerService } from 'src/modules/connected-account/oauth2-client-manager/drivers/google/google-oauth2-client-manager.service'; import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity'; @@ -20,7 +21,7 @@ export class OAuth2ClientManagerService { const { refreshToken } = connectedAccount; switch (connectedAccount.provider) { - case 'google': + case ConnectedAccountProvider.GOOGLE: return this.googleOAuth2ClientManagerService.getOAuth2Client( refreshToken, ); diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-cursor.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-cursor.service.ts index 300a7ec45..3f65f365c 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-cursor.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-cursor.service.ts @@ -1,5 +1,7 @@ import { Injectable } from '@nestjs/common'; +import { ConnectedAccountProvider } from 'twenty-shared'; + import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager'; import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity'; import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity'; @@ -24,9 +26,9 @@ export class MessagingCursorService { ); switch (connectedAccount.provider) { - case 'google': + case ConnectedAccountProvider.GOOGLE: return messageChannel.syncCursor; - case 'microsoft': { + case ConnectedAccountProvider.MICROSOFT: { const folder = await folderRepository.findOne({ where: { id: folderId, diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-get-message-list.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-get-message-list.service.ts index 2e5cab1d3..9a3b0a9e6 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-get-message-list.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-get-message-list.service.ts @@ -1,5 +1,7 @@ import { Injectable } from '@nestjs/common'; +import { ConnectedAccountProvider } from 'twenty-shared'; + import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager'; import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity'; import { MessageFolderWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-folder.workspace-entity'; @@ -46,7 +48,7 @@ export class MessagingGetMessageListService { messageChannel: MessageChannelWorkspaceEntity, ): Promise { switch (messageChannel.connectedAccount.provider) { - case 'google': + case ConnectedAccountProvider.GOOGLE: return [ { ...(await this.gmailGetMessageListService.getFullMessageList( @@ -55,7 +57,7 @@ export class MessagingGetMessageListService { folderId: undefined, }, ]; - case 'microsoft': { + case ConnectedAccountProvider.MICROSOFT: { const folderRepository = await this.twentyORMManager.getRepository( 'messageFolder', @@ -84,7 +86,7 @@ export class MessagingGetMessageListService { messageChannel: MessageChannelWorkspaceEntity, ): Promise { switch (messageChannel.connectedAccount.provider) { - case 'google': + case ConnectedAccountProvider.GOOGLE: return [ { ...(await this.gmailGetMessageListService.getPartialMessageList( @@ -94,7 +96,7 @@ export class MessagingGetMessageListService { folderId: undefined, }, ]; - case 'microsoft': + case ConnectedAccountProvider.MICROSOFT: return this.microsoftGetMessageListService.getPartialMessageListForFolders( messageChannel.connectedAccount, messageChannel, diff --git a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-get-messages.service.ts b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-get-messages.service.ts index 1542a69dd..a2a207b0a 100644 --- a/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-get-messages.service.ts +++ b/packages/twenty-server/src/modules/messaging/message-import-manager/services/messaging-get-messages.service.ts @@ -1,5 +1,7 @@ import { Injectable } from '@nestjs/common'; +import { ConnectedAccountProvider } from 'twenty-shared'; + import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/standard-objects/connected-account.workspace-entity'; import { GmailGetMessagesService } from 'src/modules/messaging/message-import-manager/drivers/gmail/services/gmail-get-messages.service'; import { MicrosoftGetMessagesService } from 'src/modules/messaging/message-import-manager/drivers/microsoft/services/microsoft-get-messages.service'; @@ -32,13 +34,13 @@ export class MessagingGetMessagesService { workspaceId: string, ): Promise { switch (connectedAccount.provider) { - case 'google': + case ConnectedAccountProvider.GOOGLE: return this.gmailGetMessagesService.getMessages( messageIds, connectedAccount, workspaceId, ); - case 'microsoft': + case ConnectedAccountProvider.MICROSOFT: return this.microsoftGetMessagesService.getMessages( messageIds, connectedAccount,