Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2e23b774b2 | |||
| 814b1f2d24 | |||
| 8f2dc7817f | |||
| 80d0721e68 | |||
| 43e92f7257 | |||
| 5b80432b9b | |||
| 153942c1c6 | |||
| 3a8a048342 | |||
| 4ce2d6827c |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-e2e-testing",
|
||||
"version": "0.52.0-canary",
|
||||
"version": "0.51.5",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-emails",
|
||||
"version": "0.52.0-canary",
|
||||
"version": "0.51.5",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-front",
|
||||
"version": "0.52.0-canary",
|
||||
"version": "0.51.5",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
|
||||
import { useVerifyLogin } from '@/auth/hooks/useVerifyLogin';
|
||||
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
|
||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
@@ -70,7 +71,11 @@ export const VerifyEmailEffect = () => {
|
||||
}, []);
|
||||
|
||||
if (isError) {
|
||||
return <EmailVerificationSent email={email} isError={true} />;
|
||||
return (
|
||||
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||
<EmailVerificationSent email={email} isError={true} />
|
||||
</Modal.Content>
|
||||
);
|
||||
}
|
||||
|
||||
return <></>;
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import { VerifyEmailEffect } from '../VerifyEmailEffect';
|
||||
|
||||
// Mock component that just renders the error state of VerifyEmailEffect directly
|
||||
// (since normal VerifyEmailEffect has async logic that's hard to test in Storybook)
|
||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||
import { EmailVerificationSent } from '../../sign-in-up/components/EmailVerificationSent';
|
||||
|
||||
const VerifyEmailEffectErrorState = ({ email = 'user@example.com' }) => {
|
||||
return (
|
||||
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||
<EmailVerificationSent email={email} isError={true} />
|
||||
</Modal.Content>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta<typeof VerifyEmailEffectErrorState> = {
|
||||
title: 'Pages/Auth/VerifyEmailEffect',
|
||||
component: VerifyEmailEffectErrorState,
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<div style={{ padding: '24px' }}>
|
||||
<RecoilRoot>
|
||||
<Story />
|
||||
</RecoilRoot>
|
||||
</div>
|
||||
),
|
||||
SnackBarDecorator,
|
||||
],
|
||||
parameters: {
|
||||
codeSection: {
|
||||
docs: 'IMPORTANT: When rendering EmailVerificationSent from VerifyEmailEffect, always wrap it with Modal.Content to maintain consistent styling.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof VerifyEmailEffect>;
|
||||
|
||||
export const ErrorState: Story = {
|
||||
args: {
|
||||
email: 'user@example.com',
|
||||
},
|
||||
};
|
||||
|
||||
export const IntegratedExample: StoryObj<typeof VerifyEmailEffect> = {
|
||||
render: () => (
|
||||
<RecoilRoot>
|
||||
<MemoryRouter
|
||||
initialEntries={[
|
||||
'/verify-email?email=user@example.com&emailVerificationToken=invalid-token',
|
||||
]}
|
||||
>
|
||||
<Routes>
|
||||
<Route
|
||||
path="/verify-email"
|
||||
element={<VerifyEmailEffectErrorState email="user@example.com" />}
|
||||
/>
|
||||
</Routes>
|
||||
</MemoryRouter>
|
||||
</RecoilRoot>
|
||||
),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
'This demonstrates how the component should look when rendered in the app with proper Modal.Content wrapping.',
|
||||
},
|
||||
},
|
||||
},
|
||||
decorators: [SnackBarDecorator],
|
||||
};
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||
import { EmailVerificationSent } from '../EmailVerificationSent';
|
||||
|
||||
// Wrap the component in Modal.Content to reflect how it's used in the app
|
||||
const RenderWithModal = (
|
||||
args: React.ComponentProps<typeof EmailVerificationSent>,
|
||||
) => {
|
||||
return (
|
||||
<Modal padding="none" modalVariant="primary">
|
||||
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||
<EmailVerificationSent email={args.email} isError={args.isError} />
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta<typeof EmailVerificationSent> = {
|
||||
title: 'Pages/Auth/EmailVerificationSent',
|
||||
component: EmailVerificationSent,
|
||||
decorators: [ComponentDecorator, SnackBarDecorator],
|
||||
parameters: {
|
||||
codeSection: {
|
||||
docs: 'This component should always be wrapped with Modal.Content in the app.\n\nCorrect usage:\n```tsx\n<Modal.Content isVerticalCentered isHorizontalCentered>\n <EmailVerificationSent email={email} />\n</Modal.Content>\n```\n',
|
||||
},
|
||||
},
|
||||
render: RenderWithModal,
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof EmailVerificationSent>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
email: 'user@example.com',
|
||||
isError: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const Error: Story = {
|
||||
args: {
|
||||
email: 'user@example.com',
|
||||
isError: true,
|
||||
},
|
||||
};
|
||||
+1
-1
@@ -59,7 +59,7 @@ export const PlaygroundSetupForm = () => {
|
||||
try {
|
||||
// Validate by fetching the schema (but not storing it)
|
||||
const response = await fetch(
|
||||
`${REACT_APP_SERVER_BASE_URL}/open-api/${values.schema}`,
|
||||
`${REACT_APP_SERVER_BASE_URL}/rest/open-api/${values.schema}`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${values.apiKeyForPlayground}` },
|
||||
},
|
||||
|
||||
@@ -68,7 +68,7 @@ export const RestPlayground = ({ onError, schema }: RestPlaygroundProps) => {
|
||||
<ApiReferenceReact
|
||||
configuration={{
|
||||
spec: {
|
||||
url: `${REACT_APP_SERVER_BASE_URL}/open-api/${schema}?token=${playgroundApiKey}`,
|
||||
url: `${REACT_APP_SERVER_BASE_URL}/rest/open-api/${schema}?token=${playgroundApiKey}`,
|
||||
},
|
||||
authentication: {
|
||||
http: {
|
||||
|
||||
@@ -2,7 +2,6 @@ import { useFieldMetadataItemById } from '@/object-metadata/hooks/useFieldMetada
|
||||
import { getOperandLabelShort } from '@/object-record/object-filter-dropdown/utils/getOperandLabel';
|
||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
|
||||
type EditableFilterChipProps = {
|
||||
@@ -24,13 +23,11 @@ export const EditableFilterChip = ({
|
||||
|
||||
const operandLabelShort = getOperandLabelShort(viewFilter.operand);
|
||||
|
||||
const labelKey = `${viewFilter.label}${isNonEmptyString(viewFilter.value) ? operandLabelShort : ''}`;
|
||||
|
||||
return (
|
||||
<SortOrFilterChip
|
||||
key={viewFilter.id}
|
||||
testId={viewFilter.id}
|
||||
labelKey={labelKey}
|
||||
labelKey={`${viewFilter.label}${getOperandLabelShort(viewFilter.operand)}`}
|
||||
labelValue={viewFilter.displayValue}
|
||||
Icon={FieldMetadataItemIcon}
|
||||
onRemove={onRemove}
|
||||
|
||||
@@ -120,7 +120,11 @@ export const SignInUp = () => {
|
||||
]);
|
||||
|
||||
if (signInUpStep === SignInUpStep.EmailVerification) {
|
||||
return <EmailVerificationSent email={searchParams.get('email')} />;
|
||||
return (
|
||||
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||
<EmailVerificationSent email={searchParams.get('email')} />
|
||||
</Modal.Content>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-server",
|
||||
"version": "0.52.0-canary",
|
||||
"version": "0.51.5",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
@@ -12,6 +12,7 @@
|
||||
"worker:prod": "node dist/src/queue-worker/queue-worker",
|
||||
"database:init:prod": "npx ts-node ./scripts/setup-db.ts && yarn database:migrate:prod",
|
||||
"database:migrate:prod": "npx -y typeorm migration:run -d dist/src/database/typeorm/metadata/metadata.datasource && npx -y typeorm migration:run -d dist/src/database/typeorm/core/core.datasource",
|
||||
"clickhouse:migrate:prod": "node dist/src/database/clickhouse/migrations/run-migrations.js",
|
||||
"typeorm": "../../node_modules/typeorm/.bin/typeorm"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ export class RestApiCoreController {
|
||||
private readonly restApiCoreServiceV2: RestApiCoreServiceV2,
|
||||
) {}
|
||||
|
||||
@Post('/duplicates')
|
||||
@Post('duplicates')
|
||||
@UseFilters(RestApiExceptionFilter)
|
||||
async handleApiFindDuplicates(@Req() request: Request, @Res() res: Response) {
|
||||
const result = await this.restApiCoreService.findDuplicates(request);
|
||||
|
||||
@@ -29,7 +29,7 @@ import { BillingWebhookInvoiceService } from 'src/engine/core-modules/billing/we
|
||||
import { BillingWebhookPriceService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-price.service';
|
||||
import { BillingWebhookProductService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-product.service';
|
||||
import { BillingWebhookSubscriptionService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-subscription.service';
|
||||
@Controller('billing')
|
||||
@Controller()
|
||||
@UseFilters(BillingRestApiExceptionFilter)
|
||||
export class BillingController {
|
||||
protected readonly logger = new Logger(BillingController.name);
|
||||
@@ -46,7 +46,7 @@ export class BillingController {
|
||||
private readonly billingWebhookCustomerService: BillingWebhookCustomerService,
|
||||
) {}
|
||||
|
||||
@Post('/webhooks')
|
||||
@Post(['billing/webhooks', 'webhooks/stripe'])
|
||||
async handleWebhooks(
|
||||
@Headers('stripe-signature') signature: string,
|
||||
@Req() req: RawBodyRequest<Request>,
|
||||
|
||||
+2
-2
@@ -4,9 +4,9 @@ import { BillingPlanKey } from 'src/engine/core-modules/billing/enums/billing-pl
|
||||
export const getPlanKeyFromSubscription = (
|
||||
subscription: BillingSubscription,
|
||||
): BillingPlanKey => {
|
||||
const planKey = subscription.metadata?.planKey;
|
||||
const plan = subscription.metadata?.plan; //To do : #867 Naming issue decide if we should rename stripe product metadata planKey to plan (+ productKey to product) OR at session checkout creating subscription with metadata planKey (and not plan)
|
||||
|
||||
switch (planKey) {
|
||||
switch (plan) {
|
||||
case 'PRO':
|
||||
return BillingPlanKey.PRO;
|
||||
case 'ENTERPRISE':
|
||||
|
||||
+9
-9
@@ -10,24 +10,24 @@ import {
|
||||
} from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Response, Request } from 'express';
|
||||
import { Request, Response } from 'express';
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { AnalyticsService } from 'src/engine/core-modules/analytics/services/analytics.service';
|
||||
import { CUSTOM_DOMAIN_ACTIVATED_EVENT } from 'src/engine/core-modules/analytics/utils/events/track/custom-domain/custom-domain-activated';
|
||||
import { AuthRestApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-rest-api-exception.filter';
|
||||
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import {
|
||||
DomainManagerException,
|
||||
DomainManagerExceptionCode,
|
||||
} from 'src/engine/core-modules/domain-manager/domain-manager.exception';
|
||||
import { handleException } from 'src/engine/core-modules/exception-handler/http-exception-handler.service';
|
||||
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
|
||||
import { CloudflareSecretMatchGuard } from 'src/engine/core-modules/domain-manager/guards/cloudflare-secret.guard';
|
||||
import { CustomDomainService } from 'src/engine/core-modules/domain-manager/services/custom-domain.service';
|
||||
import { AnalyticsService } from 'src/engine/core-modules/analytics/services/analytics.service';
|
||||
import { CUSTOM_DOMAIN_ACTIVATED_EVENT } from 'src/engine/core-modules/analytics/utils/events/track/custom-domain/custom-domain-activated';
|
||||
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
|
||||
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
|
||||
import { handleException } from 'src/engine/core-modules/exception-handler/http-exception-handler.service';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
||||
@Controller('cloudflare')
|
||||
@Controller()
|
||||
@UseFilters(AuthRestApiExceptionFilter)
|
||||
export class CloudflareController {
|
||||
constructor(
|
||||
@@ -39,7 +39,7 @@ export class CloudflareController {
|
||||
private readonly analyticsService: AnalyticsService,
|
||||
) {}
|
||||
|
||||
@Post('custom-hostname-webhooks')
|
||||
@Post(['cloudflare/custom-hostname-webhooks', 'webhooks/cloudflare'])
|
||||
@UseGuards(CloudflareSecretMatchGuard)
|
||||
async customHostnameWebhooks(@Req() req: Request, @Res() res: Response) {
|
||||
if (!req.body?.data?.data?.hostname) {
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ export class HealthController {
|
||||
return this.health.check([]);
|
||||
}
|
||||
|
||||
@Get('/:indicatorId')
|
||||
@Get(':indicatorId')
|
||||
@HealthCheck()
|
||||
checkService(@Param('indicatorId') indicatorId: HealthIndicatorId) {
|
||||
const checks = {
|
||||
|
||||
@@ -4,11 +4,11 @@ import { Request, Response } from 'express';
|
||||
|
||||
import { OpenApiService } from 'src/engine/core-modules/open-api/open-api.service';
|
||||
|
||||
@Controller('open-api')
|
||||
@Controller()
|
||||
export class OpenApiController {
|
||||
constructor(private readonly openApiService: OpenApiService) {}
|
||||
|
||||
@Get('core')
|
||||
@Get(['open-api/core', 'rest/open-api/core'])
|
||||
async generateOpenApiSchemaCore(
|
||||
@Req() request: Request,
|
||||
@Res() res: Response,
|
||||
@@ -18,7 +18,7 @@ export class OpenApiController {
|
||||
res.send(data);
|
||||
}
|
||||
|
||||
@Get('metadata')
|
||||
@Get(['open-api/metadata', 'rest/open-api/metadata'])
|
||||
async generateOpenApiSchemaMetaData(
|
||||
@Req() request: Request,
|
||||
@Res() res: Response,
|
||||
|
||||
+6
-6
@@ -1,19 +1,19 @@
|
||||
import { Controller, Get, Param, Post, Req, UseFilters } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { Request } from 'express';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { WorkflowTriggerWorkspaceService } from 'src/modules/workflow/workflow-trigger/workspace-services/workflow-trigger.workspace-service';
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
|
||||
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
|
||||
import { WorkflowTriggerRestApiExceptionFilter } from 'src/engine/core-modules/workflow/filters/workflow-trigger-rest-api-exception.filter';
|
||||
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
|
||||
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
|
||||
import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
|
||||
import {
|
||||
WorkflowTriggerException,
|
||||
WorkflowTriggerExceptionCode,
|
||||
} from 'src/modules/workflow/workflow-trigger/exceptions/workflow-trigger.exception';
|
||||
import { WorkflowTriggerType } from 'src/modules/workflow/workflow-trigger/types/workflow-trigger.type';
|
||||
import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||
import { WorkflowTriggerWorkspaceService } from 'src/modules/workflow/workflow-trigger/workspace-services/workflow-trigger.workspace-service';
|
||||
|
||||
@Controller('webhooks')
|
||||
@UseFilters(WorkflowTriggerRestApiExceptionFilter)
|
||||
|
||||
+4
-1
@@ -55,7 +55,10 @@ export class WorkspaceMetadataCacheService {
|
||||
}
|
||||
|
||||
if (currentCacheVersion !== undefined) {
|
||||
this.workspaceCacheStorageService.flush(workspaceId, currentCacheVersion);
|
||||
this.workspaceCacheStorageService.flushVersionedMetadata(
|
||||
workspaceId,
|
||||
currentCacheVersion,
|
||||
);
|
||||
}
|
||||
|
||||
await this.workspaceCacheStorageService.addObjectMetadataCollectionOngoingCachingLock(
|
||||
|
||||
+8
-1
@@ -253,7 +253,10 @@ export class WorkspaceCacheStorageService {
|
||||
);
|
||||
}
|
||||
|
||||
async flush(workspaceId: string, metadataVersion: number): Promise<void> {
|
||||
async flushVersionedMetadata(
|
||||
workspaceId: string,
|
||||
metadataVersion: number,
|
||||
): Promise<void> {
|
||||
await this.cacheStorageService.del(
|
||||
`${WorkspaceCacheKeys.MetadataObjectMetadataMaps}:${workspaceId}:${metadataVersion}`,
|
||||
);
|
||||
@@ -272,6 +275,10 @@ export class WorkspaceCacheStorageService {
|
||||
await this.cacheStorageService.del(
|
||||
`${WorkspaceCacheKeys.MetadataObjectMetadataOngoingCachingLock}:${workspaceId}:${metadataVersion}`,
|
||||
);
|
||||
}
|
||||
|
||||
async flush(workspaceId: string, metadataVersion: number): Promise<void> {
|
||||
await this.flushVersionedMetadata(workspaceId, metadataVersion);
|
||||
|
||||
await this.cacheStorageService.del(
|
||||
`${WorkspaceCacheKeys.MetadataPermissionsRolesPermissions}:${workspaceId}`,
|
||||
|
||||
+6
-6
@@ -18,7 +18,7 @@ describe('BillingController (integration)', () => {
|
||||
};
|
||||
|
||||
await client
|
||||
.post('/billing/webhooks')
|
||||
.post('/webhooks/stripe')
|
||||
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`)
|
||||
.set('stripe-signature', 'correct-signature')
|
||||
.set('Content-Type', 'application/json')
|
||||
@@ -29,7 +29,7 @@ describe('BillingController (integration)', () => {
|
||||
});
|
||||
|
||||
await client
|
||||
.post('/billing/webhooks')
|
||||
.post('/webhooks/stripe')
|
||||
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`)
|
||||
.set('stripe-signature', 'correct-signature')
|
||||
.set('Content-Type', 'application/json')
|
||||
@@ -51,7 +51,7 @@ describe('BillingController (integration)', () => {
|
||||
};
|
||||
|
||||
await client
|
||||
.post('/billing/webhooks')
|
||||
.post('/webhooks/stripe')
|
||||
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`)
|
||||
.set('stripe-signature', 'correct-signature')
|
||||
.set('Content-Type', 'application/json')
|
||||
@@ -63,7 +63,7 @@ describe('BillingController (integration)', () => {
|
||||
});
|
||||
|
||||
await client
|
||||
.post('/billing/webhooks')
|
||||
.post('/webhooks/stripe')
|
||||
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`)
|
||||
.set('stripe-signature', 'correct-signature')
|
||||
.set('Content-Type', 'application/json')
|
||||
@@ -83,7 +83,7 @@ describe('BillingController (integration)', () => {
|
||||
};
|
||||
|
||||
await client
|
||||
.post('/billing/webhooks')
|
||||
.post('/webhooks/stripe')
|
||||
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`)
|
||||
.set('stripe-signature', 'correct-signature')
|
||||
.set('Content-Type', 'application/json')
|
||||
@@ -102,7 +102,7 @@ describe('BillingController (integration)', () => {
|
||||
};
|
||||
|
||||
await client
|
||||
.post('/billing/webhooks')
|
||||
.post('/webhooks/stripe')
|
||||
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`)
|
||||
.set('stripe-signature', 'invalid-signature')
|
||||
.set('Content-Type', 'application/json')
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-shared",
|
||||
"version": "0.52.0-canary",
|
||||
"version": "0.51.5",
|
||||
"main": "dist/twenty-shared.cjs.js",
|
||||
"module": "dist/twenty-shared.esm.js",
|
||||
"license": "AGPL-3.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-ui",
|
||||
"version": "0.52.0-canary",
|
||||
"version": "0.51.5",
|
||||
"main": "dist/index.cjs",
|
||||
"module": "dist/index.mjs",
|
||||
"style": "./dist/style.css",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-website",
|
||||
"version": "0.52.0-canary",
|
||||
"version": "0.51.5",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"nx": "NX_DEFAULT_PROJECT=twenty-website node ../../node_modules/nx/bin/nx.js",
|
||||
|
||||
Reference in New Issue
Block a user