feat(emailing-domain): add LOG driver for local development (#21286)
## What Adds a `LOG` driver to the emailing-domain feature, selected via a new `EMAILING_DOMAIN_DRIVER` config variable (defaults to `AWS_SES`, so production behavior is unchanged). The LOG driver: - resolves domains to `VERIFIED` instantly (no DNS / SES setup) - logs each `sendEmail` and returns a synthetic `messageId` instead of calling SES It also dev-seeds a pre-verified domain per workspace (`<workspaceId>.dev.twenty.local`) so the feature works out of the box. ## Why The emailing-domain feature currently ships only the AWS SES driver, so the verify → send flow can't be exercised locally (or in CI) without real AWS credentials. This unblocks local development and review of anything built on emailing domains. ## Usage ``` EMAILING_DOMAIN_DRIVER=LOG ``` The seeded `*.dev.twenty.local` domain is already verified; sends are logged (`[log-driver] sendEmail ...`). --------- Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
This commit is contained in:
@@ -1446,16 +1446,11 @@ type EmailingDomain {
|
||||
createdAt: DateTime!
|
||||
updatedAt: DateTime!
|
||||
domain: String!
|
||||
driver: EmailingDomainDriver!
|
||||
status: EmailingDomainStatus!
|
||||
verificationRecords: [VerificationRecord!]
|
||||
verifiedAt: DateTime
|
||||
}
|
||||
|
||||
enum EmailingDomainDriver {
|
||||
AWS_SES
|
||||
}
|
||||
|
||||
enum EmailingDomainStatus {
|
||||
PENDING
|
||||
VERIFIED
|
||||
@@ -3226,7 +3221,7 @@ type Mutation {
|
||||
resetPageLayoutToDefault(id: String!): PageLayout!
|
||||
resetPageLayoutWidgetToDefault(id: String!): PageLayoutWidget!
|
||||
resetPageLayoutTabToDefault(id: String!): PageLayoutTab!
|
||||
createEmailingDomain(domain: String!, driver: EmailingDomainDriver!): EmailingDomain!
|
||||
createEmailingDomain(domain: String!): EmailingDomain!
|
||||
deleteEmailingDomain(id: String!): Boolean!
|
||||
verifyEmailingDomain(id: String!): EmailingDomain!
|
||||
sendEmailViaEmailingDomain(input: SendEmailViaDomainInput!): SendEmailViaDomainOutput!
|
||||
|
||||
@@ -1104,15 +1104,12 @@ export interface EmailingDomain {
|
||||
createdAt: Scalars['DateTime']
|
||||
updatedAt: Scalars['DateTime']
|
||||
domain: Scalars['String']
|
||||
driver: EmailingDomainDriver
|
||||
status: EmailingDomainStatus
|
||||
verificationRecords?: VerificationRecord[]
|
||||
verifiedAt?: Scalars['DateTime']
|
||||
__typename: 'EmailingDomain'
|
||||
}
|
||||
|
||||
export type EmailingDomainDriver = 'AWS_SES'
|
||||
|
||||
export type EmailingDomainStatus = 'PENDING' | 'VERIFIED' | 'FAILED' | 'TEMPORARY_FAILURE'
|
||||
|
||||
export interface SendEmailViaDomainOutput {
|
||||
@@ -4064,7 +4061,6 @@ export interface EmailingDomainGenqlSelection{
|
||||
createdAt?: boolean | number
|
||||
updatedAt?: boolean | number
|
||||
domain?: boolean | number
|
||||
driver?: boolean | number
|
||||
status?: boolean | number
|
||||
verificationRecords?: VerificationRecordGenqlSelection
|
||||
verifiedAt?: boolean | number
|
||||
@@ -5838,7 +5834,7 @@ export interface MutationGenqlSelection{
|
||||
resetPageLayoutToDefault?: (PageLayoutGenqlSelection & { __args: {id: Scalars['String']} })
|
||||
resetPageLayoutWidgetToDefault?: (PageLayoutWidgetGenqlSelection & { __args: {id: Scalars['String']} })
|
||||
resetPageLayoutTabToDefault?: (PageLayoutTabGenqlSelection & { __args: {id: Scalars['String']} })
|
||||
createEmailingDomain?: (EmailingDomainGenqlSelection & { __args: {domain: Scalars['String'], driver: EmailingDomainDriver} })
|
||||
createEmailingDomain?: (EmailingDomainGenqlSelection & { __args: {domain: Scalars['String']} })
|
||||
deleteEmailingDomain?: { __args: {id: Scalars['String']} }
|
||||
verifyEmailingDomain?: (EmailingDomainGenqlSelection & { __args: {id: Scalars['String']} })
|
||||
sendEmailViaEmailingDomain?: (SendEmailViaDomainOutputGenqlSelection & { __args: {input: SendEmailViaDomainInput} })
|
||||
@@ -8732,10 +8728,6 @@ export const enumPageLayoutType = {
|
||||
STANDALONE_PAGE: 'STANDALONE_PAGE' as const
|
||||
}
|
||||
|
||||
export const enumEmailingDomainDriver = {
|
||||
AWS_SES: 'AWS_SES' as const
|
||||
}
|
||||
|
||||
export const enumEmailingDomainStatus = {
|
||||
PENDING: 'PENDING' as const,
|
||||
VERIFIED: 'VERIFIED' as const,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1464,7 +1464,6 @@ export type EmailingDomain = {
|
||||
__typename?: 'EmailingDomain';
|
||||
createdAt: Scalars['DateTime'];
|
||||
domain: Scalars['String'];
|
||||
driver: EmailingDomainDriver;
|
||||
id: Scalars['UUID'];
|
||||
status: EmailingDomainStatus;
|
||||
updatedAt: Scalars['DateTime'];
|
||||
@@ -1472,10 +1471,6 @@ export type EmailingDomain = {
|
||||
verifiedAt?: Maybe<Scalars['DateTime']>;
|
||||
};
|
||||
|
||||
export enum EmailingDomainDriver {
|
||||
AWS_SES = 'AWS_SES'
|
||||
}
|
||||
|
||||
export enum EmailingDomainStatus {
|
||||
FAILED = 'FAILED',
|
||||
PENDING = 'PENDING',
|
||||
@@ -2695,7 +2690,6 @@ export type MutationCreateEmailGroupChannelArgs = {
|
||||
|
||||
export type MutationCreateEmailingDomainArgs = {
|
||||
domain: Scalars['String'];
|
||||
driver: EmailingDomainDriver;
|
||||
};
|
||||
|
||||
|
||||
@@ -7349,11 +7343,10 @@ export type FindManyPublicDomainsQuery = { __typename?: 'Query', findManyPublicD
|
||||
|
||||
export type CreateEmailingDomainMutationVariables = Exact<{
|
||||
domain: Scalars['String'];
|
||||
driver: EmailingDomainDriver;
|
||||
}>;
|
||||
|
||||
|
||||
export type CreateEmailingDomainMutation = { __typename?: 'Mutation', createEmailingDomain: { __typename?: 'EmailingDomain', id: string, domain: string, driver: EmailingDomainDriver, status: EmailingDomainStatus, verifiedAt?: string | null, createdAt: string, updatedAt: string, verificationRecords?: Array<{ __typename?: 'VerificationRecord', type: string, key: string, value: string, priority?: number | null }> | null } };
|
||||
export type CreateEmailingDomainMutation = { __typename?: 'Mutation', createEmailingDomain: { __typename?: 'EmailingDomain', id: string, domain: string, status: EmailingDomainStatus, verifiedAt?: string | null, createdAt: string, updatedAt: string, verificationRecords?: Array<{ __typename?: 'VerificationRecord', type: string, key: string, value: string, priority?: number | null }> | null } };
|
||||
|
||||
export type DeleteEmailingDomainMutationVariables = Exact<{
|
||||
id: Scalars['String'];
|
||||
@@ -7367,12 +7360,12 @@ export type VerifyEmailingDomainMutationVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type VerifyEmailingDomainMutation = { __typename?: 'Mutation', verifyEmailingDomain: { __typename?: 'EmailingDomain', id: string, domain: string, driver: EmailingDomainDriver, status: EmailingDomainStatus, verifiedAt?: string | null, createdAt: string, updatedAt: string } };
|
||||
export type VerifyEmailingDomainMutation = { __typename?: 'Mutation', verifyEmailingDomain: { __typename?: 'EmailingDomain', id: string, domain: string, status: EmailingDomainStatus, verifiedAt?: string | null, createdAt: string, updatedAt: string } };
|
||||
|
||||
export type GetEmailingDomainsQueryVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
|
||||
export type GetEmailingDomainsQuery = { __typename?: 'Query', getEmailingDomains: Array<{ __typename?: 'EmailingDomain', id: string, domain: string, driver: EmailingDomainDriver, status: EmailingDomainStatus, verifiedAt?: string | null, createdAt: string, updatedAt: string, verificationRecords?: Array<{ __typename?: 'VerificationRecord', type: string, key: string, value: string, priority?: number | null }> | null }> };
|
||||
export type GetEmailingDomainsQuery = { __typename?: 'Query', getEmailingDomains: Array<{ __typename?: 'EmailingDomain', id: string, domain: string, status: EmailingDomainStatus, verifiedAt?: string | null, createdAt: string, updatedAt: string, verificationRecords?: Array<{ __typename?: 'VerificationRecord', type: string, key: string, value: string, priority?: number | null }> | null }> };
|
||||
|
||||
export type RefreshEnterpriseValidityTokenMutationVariables = Exact<{ [key: string]: never; }>;
|
||||
|
||||
@@ -8259,10 +8252,10 @@ export const CreatePublicDomainDocument = {"kind":"Document","definitions":[{"ki
|
||||
export const DeletePublicDomainDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeletePublicDomain"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"domain"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deletePublicDomain"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"domain"},"value":{"kind":"Variable","name":{"kind":"Name","value":"domain"}}}]}]}}]} as unknown as DocumentNode<DeletePublicDomainMutation, DeletePublicDomainMutationVariables>;
|
||||
export const UpdatePublicDomainDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdatePublicDomain"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"domain"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"applicationId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updatePublicDomain"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"domain"},"value":{"kind":"Variable","name":{"kind":"Name","value":"domain"}}},{"kind":"Argument","name":{"kind":"Name","value":"applicationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"applicationId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"isValidated"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]}}]} as unknown as DocumentNode<UpdatePublicDomainMutation, UpdatePublicDomainMutationVariables>;
|
||||
export const FindManyPublicDomainsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindManyPublicDomains"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findManyPublicDomains"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"isValidated"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}}]}}]}}]} as unknown as DocumentNode<FindManyPublicDomainsQuery, FindManyPublicDomainsQueryVariables>;
|
||||
export const CreateEmailingDomainDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateEmailingDomain"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"domain"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"driver"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"EmailingDomainDriver"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createEmailingDomain"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"domain"},"value":{"kind":"Variable","name":{"kind":"Name","value":"domain"}}},{"kind":"Argument","name":{"kind":"Name","value":"driver"},"value":{"kind":"Variable","name":{"kind":"Name","value":"driver"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"driver"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"verifiedAt"}},{"kind":"Field","name":{"kind":"Name","value":"verificationRecords"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"priority"}}]}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<CreateEmailingDomainMutation, CreateEmailingDomainMutationVariables>;
|
||||
export const CreateEmailingDomainDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateEmailingDomain"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"domain"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createEmailingDomain"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"domain"},"value":{"kind":"Variable","name":{"kind":"Name","value":"domain"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"verifiedAt"}},{"kind":"Field","name":{"kind":"Name","value":"verificationRecords"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"priority"}}]}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<CreateEmailingDomainMutation, CreateEmailingDomainMutationVariables>;
|
||||
export const DeleteEmailingDomainDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteEmailingDomain"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteEmailingDomain"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}]}]}}]} as unknown as DocumentNode<DeleteEmailingDomainMutation, DeleteEmailingDomainMutationVariables>;
|
||||
export const VerifyEmailingDomainDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"VerifyEmailingDomain"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"verifyEmailingDomain"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"driver"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"verifiedAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<VerifyEmailingDomainMutation, VerifyEmailingDomainMutationVariables>;
|
||||
export const GetEmailingDomainsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetEmailingDomains"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getEmailingDomains"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"driver"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"verifiedAt"}},{"kind":"Field","name":{"kind":"Name","value":"verificationRecords"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"priority"}}]}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<GetEmailingDomainsQuery, GetEmailingDomainsQueryVariables>;
|
||||
export const VerifyEmailingDomainDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"VerifyEmailingDomain"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"verifyEmailingDomain"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"verifiedAt"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<VerifyEmailingDomainMutation, VerifyEmailingDomainMutationVariables>;
|
||||
export const GetEmailingDomainsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetEmailingDomains"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getEmailingDomains"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"verifiedAt"}},{"kind":"Field","name":{"kind":"Name","value":"verificationRecords"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}},{"kind":"Field","name":{"kind":"Name","value":"priority"}}]}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]}}]} as unknown as DocumentNode<GetEmailingDomainsQuery, GetEmailingDomainsQueryVariables>;
|
||||
export const RefreshEnterpriseValidityTokenDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RefreshEnterpriseValidityToken"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"refreshEnterpriseValidityToken"}}]}}]} as unknown as DocumentNode<RefreshEnterpriseValidityTokenMutation, RefreshEnterpriseValidityTokenMutationVariables>;
|
||||
export const SetEnterpriseKeyDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SetEnterpriseKey"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"enterpriseKey"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"setEnterpriseKey"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"enterpriseKey"},"value":{"kind":"Variable","name":{"kind":"Name","value":"enterpriseKey"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"isValid"}},{"kind":"Field","name":{"kind":"Name","value":"licensee"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}},{"kind":"Field","name":{"kind":"Name","value":"subscriptionId"}}]}}]}}]} as unknown as DocumentNode<SetEnterpriseKeyMutation, SetEnterpriseKeyMutationVariables>;
|
||||
export const EnterpriseCheckoutSessionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"EnterpriseCheckoutSession"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"billingInterval"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"enterpriseCheckoutSession"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"billingInterval"},"value":{"kind":"Variable","name":{"kind":"Name","value":"billingInterval"}}}]}]}}]} as unknown as DocumentNode<EnterpriseCheckoutSessionQuery, EnterpriseCheckoutSessionQueryVariables>;
|
||||
|
||||
+2
-6
@@ -1,14 +1,10 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const CREATE_EMAILING_DOMAIN = gql`
|
||||
mutation CreateEmailingDomain(
|
||||
$domain: String!
|
||||
$driver: EmailingDomainDriver!
|
||||
) {
|
||||
createEmailingDomain(domain: $domain, driver: $driver) {
|
||||
mutation CreateEmailingDomain($domain: String!) {
|
||||
createEmailingDomain(domain: $domain) {
|
||||
id
|
||||
domain
|
||||
driver
|
||||
status
|
||||
verifiedAt
|
||||
verificationRecords {
|
||||
|
||||
-1
@@ -5,7 +5,6 @@ export const VERIFY_EMAILING_DOMAIN = gql`
|
||||
verifyEmailingDomain(id: $id) {
|
||||
id
|
||||
domain
|
||||
driver
|
||||
status
|
||||
verifiedAt
|
||||
createdAt
|
||||
|
||||
-1
@@ -5,7 +5,6 @@ export const GET_ALL_EMAILING_DOMAINS = gql`
|
||||
getEmailingDomains {
|
||||
id
|
||||
domain
|
||||
driver
|
||||
status
|
||||
verifiedAt
|
||||
verificationRecords {
|
||||
|
||||
+2
-7
@@ -11,10 +11,7 @@ import { getSettingsPath, isDefined } from 'twenty-shared/utils';
|
||||
import { H2Title } from 'twenty-ui/display';
|
||||
import { Section } from 'twenty-ui/layout';
|
||||
import { useMutation } from '@apollo/client/react';
|
||||
import {
|
||||
EmailingDomainDriver,
|
||||
CreateEmailingDomainDocument,
|
||||
} from '~/generated-metadata/graphql';
|
||||
import { CreateEmailingDomainDocument } from '~/generated-metadata/graphql';
|
||||
import { useNavigateSettings } from '~/hooks/useNavigateSettings';
|
||||
import {
|
||||
settingsEmailingDomainFormSchema,
|
||||
@@ -31,7 +28,6 @@ export const SettingsNewEmailingDomain = () => {
|
||||
|
||||
const [formValues, setFormValues] =
|
||||
useState<SettingsEmailingDomainFormValues>({
|
||||
driver: EmailingDomainDriver.AWS_SES,
|
||||
domain: '',
|
||||
});
|
||||
|
||||
@@ -54,7 +50,7 @@ export const SettingsNewEmailingDomain = () => {
|
||||
|
||||
const handleFieldChange = (
|
||||
field: keyof SettingsEmailingDomainFormValues,
|
||||
value: string | EmailingDomainDriver,
|
||||
value: string,
|
||||
) => {
|
||||
setFormValues((prev) => ({
|
||||
...prev,
|
||||
@@ -82,7 +78,6 @@ export const SettingsNewEmailingDomain = () => {
|
||||
await createEmailingDomain({
|
||||
variables: {
|
||||
domain: formValues.domain,
|
||||
driver: formValues.driver,
|
||||
},
|
||||
onCompleted: (data) => {
|
||||
enqueueSuccessSnackBar({
|
||||
|
||||
-2
@@ -1,5 +1,4 @@
|
||||
import { z } from 'zod';
|
||||
import { EmailingDomainDriver } from '~/generated-metadata/graphql';
|
||||
|
||||
export const settingsEmailingDomainFormSchema = z.object({
|
||||
domain: z
|
||||
@@ -10,7 +9,6 @@ export const settingsEmailingDomainFormSchema = z.object({
|
||||
'Invalid domain format. Please enter a valid domain name.',
|
||||
)
|
||||
.max(256, 'Domain must be less than 256 characters.'),
|
||||
driver: z.nativeEnum(EmailingDomainDriver),
|
||||
});
|
||||
|
||||
export type SettingsEmailingDomainFormValues = z.infer<
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
import { type QueryRunner } from 'typeorm';
|
||||
|
||||
import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator';
|
||||
import { type FastInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/fast-instance-command.interface';
|
||||
|
||||
// The emailing domain driver is selected globally via the EMAILING_DOMAIN_DRIVER
|
||||
// config variable; the per-row column was never read and is redundant.
|
||||
@RegisteredInstanceCommand('2.11.0', 1780926908000)
|
||||
export class DropEmailingDomainDriverColumnFastInstanceCommand implements FastInstanceCommand {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."emailingDomain" DROP COLUMN IF EXISTS "driver"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP TYPE IF EXISTS "core"."emailingDomain_driver_enum"`,
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`CREATE TYPE "core"."emailingDomain_driver_enum" AS ENUM('AWS_SES')`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."emailingDomain" ADD COLUMN IF NOT EXISTS "driver" "core"."emailingDomain_driver_enum" NOT NULL DEFAULT 'AWS_SES'`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."emailingDomain" ALTER COLUMN "driver" DROP DEFAULT`,
|
||||
);
|
||||
}
|
||||
}
|
||||
+2
@@ -59,6 +59,7 @@ import { EmailingDomainTenantStatusAndGlobalUniquenessFastInstanceCommand } from
|
||||
import { AddLogicFunctionExecutionModeFastInstanceCommand } from 'src/database/commands/upgrade-version-command/2-9/2-9-instance-command-fast-1799000030000-add-logic-function-execution-mode';
|
||||
import { EncryptNonSecretApplicationVariableSlowInstanceCommand } from 'src/database/commands/upgrade-version-command/2-9/2-9-instance-command-slow-1798400000000-encrypt-non-secret-application-variable';
|
||||
import { MigrateAiModelPreferencesSlowInstanceCommand } from 'src/database/commands/upgrade-version-command/2-9/2-9-instance-command-slow-1799000010000-migrate-ai-model-preferences';
|
||||
import { DropEmailingDomainDriverColumnFastInstanceCommand } from 'src/database/commands/upgrade-version-command/2-11/2-11-instance-command-fast-1780926908000-drop-emailing-domain-driver-column';
|
||||
|
||||
export const INSTANCE_COMMANDS = [
|
||||
AddViewFieldGroupIdIndexOnViewFieldFastInstanceCommand,
|
||||
@@ -120,4 +121,5 @@ export const INSTANCE_COMMANDS = [
|
||||
AddLogicFunctionExecutionModeFastInstanceCommand,
|
||||
MigrateAiModelPreferencesSlowInstanceCommand,
|
||||
EncryptNonSecretApplicationVariableSlowInstanceCommand,
|
||||
DropEmailingDomainDriverColumnFastInstanceCommand,
|
||||
];
|
||||
|
||||
+18
-9
@@ -8,6 +8,7 @@ import { AwsSesRegisterDomainService } from 'src/engine/core-modules/emailing-do
|
||||
import { AwsSesDriver } from 'src/engine/core-modules/emailing-domain/drivers/aws-ses/services/aws-ses-driver.service';
|
||||
import { AwsSesHandleErrorService } from 'src/engine/core-modules/emailing-domain/drivers/aws-ses/services/aws-ses-handle-error.service';
|
||||
import { AwsSesSendEmailService } from 'src/engine/core-modules/emailing-domain/drivers/aws-ses/services/aws-ses-send-email.service';
|
||||
import { LogEmailingDomainDriver } from 'src/engine/core-modules/emailing-domain/drivers/log/services/log-emailing-domain-driver.service';
|
||||
import { EmailingDomainDriver } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain-driver.type';
|
||||
import { DriverFactoryBase } from 'src/engine/core-modules/twenty-config/dynamic-factory.base';
|
||||
import { ConfigVariablesGroup } from 'src/engine/core-modules/twenty-config/enums/config-variables-group.enum';
|
||||
@@ -23,26 +24,31 @@ export class EmailingDomainDriverFactory extends DriverFactoryBase<EmailingDomai
|
||||
private readonly awsSesHandleErrorService: AwsSesHandleErrorService,
|
||||
private readonly awsSesRegisterDomainService: AwsSesRegisterDomainService,
|
||||
private readonly awsSesSendEmailService: AwsSesSendEmailService,
|
||||
private readonly logEmailingDomainDriver: LogEmailingDomainDriver,
|
||||
) {
|
||||
super(twentyConfigService, configGroupHashService);
|
||||
}
|
||||
|
||||
protected buildConfigKey(): string {
|
||||
const driver = EmailingDomainDriver.AWS_SES;
|
||||
const driver = this.twentyConfigService.get('EMAILING_DOMAIN_DRIVER');
|
||||
|
||||
if (driver === EmailingDomainDriver.AWS_SES) {
|
||||
const awsConfigHash = this.configGroupHashService.computeHash(
|
||||
ConfigVariablesGroup.AWS_SES_SETTINGS,
|
||||
);
|
||||
switch (driver) {
|
||||
case EmailingDomainDriver.AWS_SES: {
|
||||
const awsConfigHash = this.configGroupHashService.computeHash(
|
||||
ConfigVariablesGroup.AWS_SES_SETTINGS,
|
||||
);
|
||||
|
||||
return `aws-ses|${awsConfigHash}`;
|
||||
return `aws-ses|${awsConfigHash}`;
|
||||
}
|
||||
case EmailingDomainDriver.LOG:
|
||||
return 'log';
|
||||
default:
|
||||
throw new Error(`Unsupported emailing domain driver: ${driver}`);
|
||||
}
|
||||
|
||||
throw new Error(`Unsupported emailing domain driver: ${driver}`);
|
||||
}
|
||||
|
||||
protected createDriver(): EmailingDomainDriverInterface {
|
||||
const driver = EmailingDomainDriver.AWS_SES;
|
||||
const driver = this.twentyConfigService.get('EMAILING_DOMAIN_DRIVER');
|
||||
|
||||
switch (driver) {
|
||||
case EmailingDomainDriver.AWS_SES: {
|
||||
@@ -76,6 +82,9 @@ export class EmailingDomainDriverFactory extends DriverFactoryBase<EmailingDomai
|
||||
);
|
||||
}
|
||||
|
||||
case EmailingDomainDriver.LOG:
|
||||
return this.logEmailingDomainDriver;
|
||||
|
||||
default:
|
||||
throw new Error(`Invalid emailing domain driver: ${driver}`);
|
||||
}
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import {
|
||||
type EmailingDomainDriverInterface,
|
||||
type EmailingDomainResourceInput,
|
||||
type EmailingDomainVerificationResult,
|
||||
} from 'src/engine/core-modules/emailing-domain/drivers/interfaces/emailing-domain-driver.interface';
|
||||
import { EmailingDomainStatus } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain-status.type';
|
||||
import {
|
||||
type EmailingDomainSendEmailInput,
|
||||
type EmailingDomainSendEmailResult,
|
||||
} from 'src/engine/core-modules/emailing-domain/drivers/types/send-email';
|
||||
|
||||
@Injectable()
|
||||
export class LogEmailingDomainDriver implements EmailingDomainDriverInterface {
|
||||
private readonly logger = new Logger(LogEmailingDomainDriver.name);
|
||||
|
||||
async provisionWorkspace(workspaceId: string): Promise<void> {
|
||||
this.logger.log(`[log-driver] provisionWorkspace(${workspaceId})`);
|
||||
}
|
||||
|
||||
async deprovisionWorkspace(workspaceId: string): Promise<void> {
|
||||
this.logger.log(`[log-driver] deprovisionWorkspace(${workspaceId})`);
|
||||
}
|
||||
|
||||
async verifyDomain(
|
||||
input: EmailingDomainResourceInput,
|
||||
): Promise<EmailingDomainVerificationResult> {
|
||||
this.logger.log(
|
||||
`[log-driver] verifyDomain(${input.domain}) → VERIFIED (instant)`,
|
||||
);
|
||||
|
||||
return {
|
||||
status: EmailingDomainStatus.VERIFIED,
|
||||
verificationRecords: [],
|
||||
};
|
||||
}
|
||||
|
||||
async getDomainStatus(
|
||||
input: EmailingDomainResourceInput,
|
||||
): Promise<EmailingDomainVerificationResult> {
|
||||
this.logger.log(`[log-driver] getDomainStatus(${input.domain}) → VERIFIED`);
|
||||
|
||||
return {
|
||||
status: EmailingDomainStatus.VERIFIED,
|
||||
verificationRecords: [],
|
||||
};
|
||||
}
|
||||
|
||||
async registerDomain(input: EmailingDomainResourceInput): Promise<void> {
|
||||
this.logger.log(`[log-driver] registerDomain(${input.domain})`);
|
||||
}
|
||||
|
||||
async cleanupDomain(input: EmailingDomainResourceInput): Promise<void> {
|
||||
this.logger.log(`[log-driver] cleanupDomain(${input.domain})`);
|
||||
}
|
||||
|
||||
async sendEmail(
|
||||
input: EmailingDomainSendEmailInput,
|
||||
): Promise<EmailingDomainSendEmailResult> {
|
||||
const messageId = `log-${v4()}`;
|
||||
|
||||
this.logger.log(
|
||||
`[log-driver] sendEmail from=${input.from} to=${input.to.join(',')} subject="${input.subject}" → fake messageId=${messageId}`,
|
||||
);
|
||||
|
||||
return { messageId };
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
export enum EmailingDomainDriver {
|
||||
AWS_SES = 'AWS_SES',
|
||||
LOG = 'LOG',
|
||||
}
|
||||
|
||||
-8
@@ -3,14 +3,9 @@ import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
|
||||
import { IDField } from '@ptc-org/nestjs-query-graphql';
|
||||
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { EmailingDomainDriver } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain-driver.type';
|
||||
import { EmailingDomainStatus } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain-status.type';
|
||||
import { VerificationRecordDTO } from 'src/engine/core-modules/emailing-domain/dtos/verification-record.dto';
|
||||
|
||||
registerEnumType(EmailingDomainDriver, {
|
||||
name: 'EmailingDomainDriver',
|
||||
});
|
||||
|
||||
registerEnumType(EmailingDomainStatus, {
|
||||
name: 'EmailingDomainStatus',
|
||||
});
|
||||
@@ -29,9 +24,6 @@ export class EmailingDomainDTO {
|
||||
@Field(() => String)
|
||||
domain: string;
|
||||
|
||||
@Field(() => EmailingDomainDriver)
|
||||
driver: EmailingDomainDriver;
|
||||
|
||||
@Field(() => EmailingDomainStatus)
|
||||
status: EmailingDomainStatus;
|
||||
|
||||
|
||||
-8
@@ -9,7 +9,6 @@ import {
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import { EmailingDomainDriver } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain-driver.type';
|
||||
import { EmailingDomainStatus } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain-status.type';
|
||||
import { EmailingDomainTenantStatus } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain-tenant-status.type';
|
||||
import { VerificationRecord } from 'src/engine/core-modules/emailing-domain/drivers/types/verifications-record';
|
||||
@@ -31,13 +30,6 @@ export class EmailingDomainEntity extends WorkspaceRelatedEntity {
|
||||
@Column({ type: 'varchar', nullable: false })
|
||||
domain: string;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: Object.values(EmailingDomainDriver),
|
||||
nullable: false,
|
||||
})
|
||||
driver: EmailingDomainDriver;
|
||||
|
||||
@Column({
|
||||
type: 'enum',
|
||||
enum: Object.values(EmailingDomainStatus),
|
||||
|
||||
+2
@@ -8,6 +8,7 @@ import { AwsSesRegisterDomainService } from 'src/engine/core-modules/emailing-do
|
||||
import { AwsSesHandleErrorService } from 'src/engine/core-modules/emailing-domain/drivers/aws-ses/services/aws-ses-handle-error.service';
|
||||
import { AwsSesSendEmailService } from 'src/engine/core-modules/emailing-domain/drivers/aws-ses/services/aws-ses-send-email.service';
|
||||
import { EmailingDomainDriverFactory } from 'src/engine/core-modules/emailing-domain/drivers/emailing-domain-driver.factory';
|
||||
import { LogEmailingDomainDriver } from 'src/engine/core-modules/emailing-domain/drivers/log/services/log-emailing-domain-driver.service';
|
||||
import { EmailingDomainEntity } from 'src/engine/core-modules/emailing-domain/emailing-domain.entity';
|
||||
import { EmailingDomainResolver } from 'src/engine/core-modules/emailing-domain/emailing-domain.resolver';
|
||||
import { EmailingDomainWorkspaceCleanupJob } from 'src/engine/core-modules/emailing-domain/jobs/emailing-domain-workspace-cleanup.job';
|
||||
@@ -34,6 +35,7 @@ import { provideWorkspaceScopedRepository } from 'src/engine/twenty-orm/workspac
|
||||
AwsSesHandleErrorService,
|
||||
AwsSesRegisterDomainService,
|
||||
AwsSesSendEmailService,
|
||||
LogEmailingDomainDriver,
|
||||
provideWorkspaceScopedRepository(EmailingDomainEntity),
|
||||
],
|
||||
})
|
||||
|
||||
-3
@@ -5,7 +5,6 @@ import { PermissionFlagType } from 'twenty-shared/constants';
|
||||
import { FeatureFlagKey } from 'twenty-shared/types';
|
||||
|
||||
import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator';
|
||||
import { EmailingDomainDriver } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain-driver.type';
|
||||
import { EmailingDomainDTO } from 'src/engine/core-modules/emailing-domain/dtos/emailing-domain.dto';
|
||||
import { SendEmailViaDomainOutputDTO } from 'src/engine/core-modules/emailing-domain/dtos/send-email-via-domain-output.dto';
|
||||
import { SendEmailViaDomainInput } from 'src/engine/core-modules/emailing-domain/dtos/send-email-via-domain.input';
|
||||
@@ -34,13 +33,11 @@ export class EmailingDomainResolver {
|
||||
@RequireFeatureFlag(FeatureFlagKey.IS_EMAIL_GROUP_ENABLED)
|
||||
async createEmailingDomain(
|
||||
@Args('domain') domain: string,
|
||||
@Args('driver') driver: EmailingDomainDriver,
|
||||
@AuthWorkspace() currentWorkspace: WorkspaceEntity,
|
||||
): Promise<EmailingDomainDTO> {
|
||||
const emailingDomain =
|
||||
await this.emailingDomainService.createEmailingDomain(
|
||||
domain,
|
||||
driver,
|
||||
currentWorkspace,
|
||||
);
|
||||
|
||||
|
||||
-3
@@ -5,7 +5,6 @@ import {
|
||||
EmailingDomainDriverExceptionCode,
|
||||
} from 'src/engine/core-modules/emailing-domain/drivers/exceptions/emailing-domain-driver.exception';
|
||||
import { EmailingDomainDriverFactory } from 'src/engine/core-modules/emailing-domain/drivers/emailing-domain-driver.factory';
|
||||
import { EmailingDomainDriver } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain-driver.type';
|
||||
import { EmailingDomainStatus } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain-status.type';
|
||||
import { EmailingDomainTenantStatus } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain-tenant-status.type';
|
||||
import {
|
||||
@@ -28,7 +27,6 @@ export class EmailingDomainService {
|
||||
|
||||
async createEmailingDomain(
|
||||
domain: string,
|
||||
driverType: EmailingDomainDriver,
|
||||
workspace: WorkspaceEntity,
|
||||
): Promise<EmailingDomainEntity> {
|
||||
const existingEmailingDomain = await this.emailingDomainRepository.findOne(
|
||||
@@ -65,7 +63,6 @@ export class EmailingDomainService {
|
||||
|
||||
return this.emailingDomainRepository.save(workspace.id, {
|
||||
domain,
|
||||
driver: driverType,
|
||||
status: verificationResult.status,
|
||||
verificationRecords: verificationResult.verificationRecords,
|
||||
verifiedAt: isVerifiedOnCreation ? new Date() : null,
|
||||
|
||||
@@ -20,6 +20,7 @@ import { SupportDriver } from 'src/engine/core-modules/twenty-config/interfaces/
|
||||
import { CaptchaDriverType } from 'src/engine/core-modules/captcha/interfaces';
|
||||
import { CodeInterpreterDriverType } from 'src/engine/core-modules/code-interpreter/code-interpreter.interface';
|
||||
import { EmailDriver } from 'src/engine/core-modules/email/enums/email-driver.enum';
|
||||
import { EmailingDomainDriver } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain-driver.type';
|
||||
import { ExceptionHandlerDriver } from 'src/engine/core-modules/exception-handler/interfaces';
|
||||
import { StorageDriverType } from 'src/engine/core-modules/file-storage/interfaces';
|
||||
import { LoggerDriverType } from 'src/engine/core-modules/logger/interfaces';
|
||||
@@ -1697,6 +1698,16 @@ export class ConfigVariables {
|
||||
@IsOptional()
|
||||
MINTLIFY_SUBDOMAIN: string;
|
||||
|
||||
@ConfigVariablesMetadata({
|
||||
group: ConfigVariablesGroup.AWS_SES_SETTINGS,
|
||||
description:
|
||||
'Driver used for the emailing domain feature — AWS_SES for production, LOG for local development (no AWS credentials needed)',
|
||||
type: ConfigVariableType.ENUM,
|
||||
options: Object.values(EmailingDomainDriver),
|
||||
})
|
||||
@CastToUpperSnakeCase()
|
||||
EMAILING_DOMAIN_DRIVER: EmailingDomainDriver = EmailingDomainDriver.AWS_SES;
|
||||
|
||||
@ConfigVariablesMetadata({
|
||||
group: ConfigVariablesGroup.AWS_SES_SETTINGS,
|
||||
description: 'AWS region',
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
import { type QueryRunner } from 'typeorm';
|
||||
|
||||
import { EmailingDomainStatus } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain-status.type';
|
||||
import { EmailingDomainTenantStatus } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain-tenant-status.type';
|
||||
|
||||
const tableName = 'emailingDomain';
|
||||
|
||||
const DEV_EMAILING_DOMAIN = 'dev.twenty.local';
|
||||
|
||||
type SeedEmailingDomainsArgs = {
|
||||
queryRunner: QueryRunner;
|
||||
schemaName: string;
|
||||
workspaceId: string;
|
||||
};
|
||||
|
||||
export const seedEmailingDomains = async ({
|
||||
queryRunner,
|
||||
schemaName,
|
||||
workspaceId,
|
||||
}: SeedEmailingDomainsArgs) => {
|
||||
const domain = `${workspaceId.slice(0, 8)}.${DEV_EMAILING_DOMAIN}`;
|
||||
|
||||
await queryRunner.manager
|
||||
.createQueryBuilder()
|
||||
.insert()
|
||||
.into(`${schemaName}.${tableName}`, [
|
||||
'workspaceId',
|
||||
'domain',
|
||||
'status',
|
||||
'verificationRecords',
|
||||
'verifiedAt',
|
||||
'tenantStatus',
|
||||
])
|
||||
.orIgnore()
|
||||
.values([
|
||||
{
|
||||
workspaceId,
|
||||
domain,
|
||||
status: EmailingDomainStatus.VERIFIED,
|
||||
verificationRecords: JSON.stringify([]),
|
||||
verifiedAt: new Date(),
|
||||
tenantStatus: EmailingDomainTenantStatus.ACTIVE,
|
||||
},
|
||||
])
|
||||
.execute();
|
||||
};
|
||||
+8
@@ -6,6 +6,7 @@ import { v4 } from 'uuid';
|
||||
|
||||
import { ApplicationRegistrationService } from 'src/engine/core-modules/application/application-registration/application-registration.service';
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { EmailingDomainDriver } from 'src/engine/core-modules/emailing-domain/drivers/types/emailing-domain-driver.type';
|
||||
import { SdkClientGenerationService } from 'src/engine/core-modules/sdk-client/sdk-client-generation.service';
|
||||
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
||||
import { UpgradeMigrationService } from 'src/engine/core-modules/upgrade/services/upgrade-migration.service';
|
||||
@@ -27,6 +28,7 @@ import {
|
||||
import { DevSeederPermissionsService } from 'src/engine/workspace-manager/dev-seeder/core/services/dev-seeder-permissions.service';
|
||||
import { seedAgents } from 'src/engine/workspace-manager/dev-seeder/core/utils/seed-agents.util';
|
||||
import { seedApiKeys } from 'src/engine/workspace-manager/dev-seeder/core/utils/seed-api-keys.util';
|
||||
import { seedEmailingDomains } from 'src/engine/workspace-manager/dev-seeder/core/utils/seed-emailing-domains.util';
|
||||
import { seedFeatureFlags } from 'src/engine/workspace-manager/dev-seeder/core/utils/seed-feature-flags.util';
|
||||
import { seedMetadataEntities } from 'src/engine/workspace-manager/dev-seeder/core/utils/seed-metadata-entities.util';
|
||||
import { seedPageLayouts } from 'src/engine/workspace-manager/dev-seeder/core/utils/seed-page-layouts.util';
|
||||
@@ -319,6 +321,12 @@ export class DevSeederService {
|
||||
|
||||
await seedAgents({ queryRunner, schemaName, workspaceId });
|
||||
await seedApiKeys({ queryRunner, schemaName, workspaceId });
|
||||
if (
|
||||
this.twentyConfigService.get('EMAILING_DOMAIN_DRIVER') ===
|
||||
EmailingDomainDriver.LOG
|
||||
) {
|
||||
await seedEmailingDomains({ queryRunner, schemaName, workspaceId });
|
||||
}
|
||||
await seedFeatureFlags({ queryRunner, schemaName, workspaceId });
|
||||
|
||||
if (seedBilling) {
|
||||
|
||||
Reference in New Issue
Block a user