Commit Graph
70 Commits
Author SHA1 Message Date
nitinandGitHub 904be95148 Fix calendar booking step in onboarding when env var is not configured (#14707)
## The Issue

When CALENDAR_BOOKING_PAGE_ID env variable is not configured, the
onboarding flow still sets the booking step as pending in the database.
This causes users to get stuck on a broken booking page after
logout/login, as the Cal.com iframe tries to load with an empty calendar
link.

 ## The Fix

Made the booking step handling idempotent across the stack:

  Backend:
- setOnboardingBookOnboardingPending now checks if calendar is actually
configured before setting the step as pending
- getOnboardingStatus auto-cleans invalid booking states when detected
(booking pending but no calendar configured)
  - Empty strings in env are now treated as undefined in client config

  Frontend:
- Added navigation protection to redirect away from booking pages when
calendar isn't configured
- Existing defensive logic in useSetNextOnboardingStatus already skips
booking when no calendar ID

  Result

  - New users won't get invalid booking states
  - Existing bad data self-heals when users interact with the system
  - Backend and frontend stay in sync about when booking should be shown

Fixes the issue Felix reported where users saw a broken booking page in
production.
  
I think we should keep the old CAL_LINK constant for now - while we
could remove the booking onboarding step entirely, it would break the
plan/pricing modal which uses it as a fallback when no calendar is
configured. Open for discussion! -- May be we dont show the `Book a
Call` button if the env is not set -- but we should keep it as it is if
we want two different behaviors :)
  
  closes https://github.com/twentyhq/core-team-issues/issues/1558
2025-09-25 10:19:09 +02:00
5b9cda3341 Refactor table resize behavior (#14447)
This PR refactors table resize with the new layout using flex-wrap to
manage all the table with divs.

Due to flex-wrap, we have to manually compute some filling divs like the
last column filler div or the empty table container, otherwise the
header can wrap and display on two lines, which is the only real issue
with this implementation with wrap.

Remember that **using flex-wrap is necessary** to handle z-index as we
want for the scrolling and hovered portal cell interaction UX. Otherwise
we lose the capacity to have z-index fine-tuning on very specific edge
cases.

To handle the resize, the most performant solution was to create CSS
variables for each column width on the table, creating a class for each
column, then assigning each class to all divs that are in the same
column, using the index of the array or the fixed known position index
for that.

This PR also refactors a lot of small details around the resizing, the
naming of the component and the DX.

It notably introduces a new hook : `useHTMLElementByIdWhenAvailable`,
that is very relies on MutationObserver API to get a native HTML element
as soon as it is rendered.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2025-09-12 15:17:53 +02:00
f7cde28dd6 🔧 Restore PRs #14348 and #14352 that were reverted by PR #14347 (#14359)
## Problem

**CRITICAL:** Two PRs were accidentally reverted when PR #14347 "Prevent
csv export injections" was merged:

1. **PR #14348** "[Page Layout] - Review Refactor" -  **RESTORED**
2. **PR #14352** "Fix wrong path used by backend" -  **RESTORED**

## Root Cause Analysis

During the merge of PR #14347, there was a complex merge conflict with
PR #14352 "Fix wrong path used by backend". The merge commit
`324d7204bb` in the PR #14347 branch brought in changes from PR #14352,
but during the conflict resolution, **BOTH PR #14348 and PR #14352's
changes were accidentally overwritten**.

## What This PR Restores

This PR restores **BOTH** PRs by cherry-picking their commits:

###  PR #14348 Changes Restored:
- `GraphWidgetRenderer.tsx` - was deleted, now restored
- `WidgetRenderer.tsx` - was missing, now restored  
- `SettingsPageLayoutTabsInstanceId.ts` - was deleted, now restored
- `useUpdatePageLayoutWidget.ts` - was renamed back, now restored with
correct name
- Multiple test files that were deleted
- Several hook files that were renamed/reverted
- File renames: `usePageLayoutWidgetUpdate.ts` →
`useUpdatePageLayoutWidget.ts`
- Hook refactoring and test file organization
- Page layout component improvements

###  PR #14352 Changes Restored:
- **Types moved to twenty-shared:**
  - `packages/twenty-shared/src/types/AppBasePath.ts`  RESTORED
  - `packages/twenty-shared/src/types/AppPath.ts`  RESTORED
  - `packages/twenty-shared/src/types/SettingsPath.ts`  RESTORED
- **Navigation utilities moved to twenty-shared:**
- `packages/twenty-shared/src/utils/navigation/getAppPath.ts`  RESTORED
- `packages/twenty-shared/src/utils/navigation/getSettingsPath.ts` 
RESTORED
- **200+ import statements updated** across the codebase to use
twenty-shared
- **Old type files deleted** from twenty-front/src/modules/types/

## Evidence of Complete Restoration

**Before (reverted state):**
-  Types were in `packages/twenty-front/src/modules/types/`
-  Page layout files missing
-  Hook files incorrectly named

**After (this PR):**
-  Types correctly in `packages/twenty-shared/src/types/`
-  All page layout files restored
-  Hook files correctly named
-  All import statements updated

## Verification

**Total changes:**
- PR #14348: 36 files changed, 863 insertions(+), 442 deletions(-)
- PR #14352: 243 files changed, 492 insertions(+), 461 deletions(-)
- **Combined: 279 files changed, 1355 insertions(+), 903 deletions(-)**

## Impact

This completely restores both PRs that were accidentally lost, ensuring:
1. Page layout refactoring work is back
2. Type organization and path utilities are correctly in twenty-shared
3. Backend email paths work correctly again
4. No functionality is lost

Fixes the reversion caused by the merge conflict in PR #14347.

---------

Co-authored-by: nitin <142569587+ehconitin@users.noreply.github.com>
2025-09-08 21:48:13 +02:00
cebcf4f1f5 Prevent csv export injections (#14347)
**Small Security Issue:** CSV exports were vulnerable to formula
injection attacks when users entered values starting with =, +, -, or @.
(only happens if a logged-in user injects corrupted data)

Solution:
- Added ZWJ (Zero-Width Joiner) protection that prefixes dangerous
values with invisible Unicode character
- This is the best way to preserve original data while preventing Excel
from executing formulas
- Added import cleanup to restore original values when re-importing
 
Changes:
- New sanitizeValueForCSVExport() function for security
- Updated all CSV export paths to use both security + formatting
functions
- Added comprehensive tests covering attack vectors and international
characters
- Also added cursor rules for better code consistency

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-09-08 17:57:46 +02:00
Félix MalfaitandGitHub 502bd07db9 Fix wrong path used by backend (#14352)
After moving a section on the frontend, this broke the path that was
sent by email on the backend.
This kind of error comes back every ~2-3 month under different forms so
we need a more robust solution: I moved routes to the shared folder,
that way we will share one common source of truth between the frontend
and the backend.

Fixes #14343
2025-09-08 16:07:13 +02:00
Félix MalfaitandGitHub d29dbd473b Upgrade SWC Core and Storybook to v8 (#13799)
This is is a blocker for various sub-migrations
2025-08-11 12:02:33 +02:00
Félix MalfaitandGitHub 464a480043 Continue ESLINT9 Migration (#13795)
Might already fix #13793
2025-08-10 23:25:58 +02:00
Antoine MoreauxGitHubgreptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>Félix MalfaitFélix Malfait
00d12e854a BREAKING - feat(auth): refactor tokens logic & enhance email verification flow (#13487)
- Replaced `getAuthTokensFromLoginToken` with
`getAccessTokensFromLoginToken` for clarity.
- Introduced `getWorkspaceAgnosticTokenFromEmailVerificationToken`.
- Extended mutation inputs to include `locale` and
`verifyEmailNextPath`.
- Added email verification check and sending to various handlers.
- Updated GraphQL types and hooks to reflect these changes.


Fix #13412

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-07-31 12:00:59 +02:00
Nabhag MotivarasandGitHub 316f2ec38c refactor: to useCopyToClipboard to catch errors - when user has disable copy clipboard permission in browser (#13330)
as discussed here
https://github.com/twentyhq/twenty/issues/13292#issuecomment-3092215050
with @prastoin

- [x] introduce optional message param to `copyToClipboard` method in
`useCopyToClipboard` and refactor it across app, as in case if user has
disallowed clipboard permission in BROWSER unprotected clipboard access
breaks without catch.

- [x] Email copied to clipboard

- [x] run lingui extract
2025-07-30 11:13:55 +02:00
Raphaël BosiandGitHub 9eaa8ad517 Replace hotkey scopes by focus stack (Part 5 - Form field Inputs, Pages, Dialog ...) (#13106)
# Replace hotkey scopes by focus stack (Part 5 - Form field Inputs,
Pages, Dialog ...)

This PR is the 5th part of a refactoring aiming to deprecate the hotkey
scopes api in favor of the new focus stack api which is more robust.
Part 1: https://github.com/twentyhq/twenty/pull/12673
Part 2: https://github.com/twentyhq/twenty/pull/12798
Part 3: https://github.com/twentyhq/twenty/pull/12910
Part 4: https://github.com/twentyhq/twenty/pull/12933

In this part, all the last components using hotkey scopes were
refactored.
In the 6th and final part of this refactoring we will be able to
completely remove the hotkey scopes from the codebase.
2025-07-08 20:18:32 +02:00
EtienneandGitHub 56607c0449 Billing - fix duplicate customer in stripe + subscription constraint violation (#13091)
closes https://github.com/twentyhq/core-team-issues/issues/982
2025-07-08 11:17:59 +02:00
MarieandGitHub 288f0919db Define server error messages to display in FE from the server (#12973)
Currently, when a server query or mutation from the front-end fails, the
error message defined server-side is displayed in a snackbar in the
front-end.
These error messages usually contain technical details that don't belong
to the user interface, such as "ObjectMetadataCollection not found" or
"invalid ENUM value for ...".

**BE**
In addition to the original error message that is still needed (for the
request response, debugging, sentry monitoring etc.), we add a
`displayedErrorMessage` that will be used in the snackbars. It's only
relevant to add it for the messages that will reach the FE (ie. not in
jobs or in rest api for instance) and if it can help the user sort out /
fix things (ie. we do add displayedErrorMessage for "Cannot create
multiple draft versions for the same workflow" or "Cannot delete
[field], please update the label identifier field first", but not
"Object metadata does not exist"), even if in practice in the FE users
should not be able to perform an action that will not work (ie should
not be able to save creation of multiple draft versions of the same
workflows).

**FE**
To ease the usage we replaced enqueueSnackBar with enqueueErrorSnackBar
and enqueueSuccessSnackBar with an api that only requires to pass on the
error.
If no displayedErrorMessage is specified then the default error message
is `An error occured.`
2025-07-03 12:42:10 +00:00
nitinandGitHub a8fb039e65 poc - cal.com integration in onboarding flow (#12530) 2025-06-19 15:27:38 +05:30
EtienneandGitHub 83f28f113a Onboarding - fix infinite loop (#12694)
To reproduce : 
- IS_BILLING_ENABLED=true
- Start creating a workspace. At each onboarding step - Create Profile /
SyncEmails / InviteTeam - suspend your workspace > infinite loop

closes https://github.com/twentyhq/twenty/issues/12272
2025-06-18 11:56:34 +02:00
Antoine MoreauxandGitHub b1af98f93d refactor(auth): add workspaces selection (#12098) 2025-06-13 16:17:35 +02:00
EtienneandGitHub 081376f594 Onboarding - add nextPath logic after email verification (#12342)
Context :
Plan choice [on pricing page on website](https://twenty.com/pricing)
should redirect you the right plan on app /plan-required page (after
sign in), thanks to query parameters and BillingCheckoutSessionState
sync.
With email verification, an other session starts at CTA click in
verification email. Initial BillingCheckoutSessionState is lost and user
can't submit to the plan he choose.

Solution : 
Pass a nextPath query parameter in email verification link

To test : 
- Modify .env to add IS_BILLING_ENABLED (+ reset db + sync billing) +
IS_EMAIL_VERIFICATION_REQUIRED
- Start test from this page
http://app.localhost:3001/welcome?billingCheckoutSession={%22plan%22:%22ENTERPRISE%22,%22interval%22:%22Year%22,%22requirePaymentMethod%22:true}
- After verification, check you arrive on /plan-required page with
Enterprise plan on a yearly interval (default is Pro/monthly).

closes https://github.com/twentyhq/twenty/issues/12288
2025-05-28 17:20:31 +00:00
ffdedf7af3 Fix "PageChangeEffect does not run when changing view on the same object" (#12196)
Fixes https://github.com/twentyhq/core-team-issues/issues/950

This issue was due to the memoization inside `useIsMatchingLocation`,
which was rerendered only if the pathname changed but not the search
params.

After discussion with @lucasbordeau, we decided to remove the hook
`useIsMatchingLocation` and to create an equivalent util function which
takes the location as an argument.

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-05-22 12:06:07 +02:00
Raphaël BosiandGitHub c982bcdb52 Introduce focus stack to handle hotkeys (#12166)
# Introduce focus stack to handle hotkeys

This PR introduces a focus stack to track the order in which the
elements are focused:
- Each focused element has a unique focus id
- When an element is focused, it is pushed on top of the stack
- When an element loses focus, we remove it from the stack 

This focus stack is then used to determine which hotkeys are available.
The previous implementation lead to many regressions because of race
conditions, of wrong order of open and close operations and by
overwriting previous states. This implementation should be way more
robust than the previous one.

The new api can be incrementally implemented since it preserves
backwards compatibility by writing to the old hotkey scopes states.
For now, it has been implemented on the modal components.

To test this PR, verify that the shortcuts still work correctly,
especially for the modal components.
2025-05-21 15:52:40 +02:00
9df4778954 Fix: Reset password flow fails when user is signed in (#11811)
### Demo


https://github.com/user-attachments/assets/9589c7cc-f6ba-484a-b002-615c11a92729

Note: For the demo video, I hardcoded the email and manually set the
isTokenValid state to true.

Closes #11689

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: prastoin <paul@twenty.com>
2025-05-02 10:04:44 +02:00
Baptiste DevessierandGitHub 1ba0c24071 Set the page hotkey scope only once (#11626)
The `useEffect` in the `PageChangeEffect` component that sets the page's
hotkey scope is run 4-5 times every time the page changes. It should be
executed only once when the location changes. The re-runs are due to
unstable dependencies that shouldn't re-trigger the `useEffect`.

This PR minimizes the re-runs of the `useEffect`. In the following
video, I discuss a more global pattern.

The documentation for the `useEffectEvent` hook:
https://react.dev/learn/separating-events-from-effects#extracting-non-reactive-logic-out-of-effects.


https://github.com/user-attachments/assets/8c0c238b-f1c4-4bbb-b083-0825f7176599
2025-04-17 16:57:49 +02:00
b6e344e7be Various fixes (#11448)
# Scrollbar fix

Fixes https://github.com/twentyhq/twenty/issues/11403

<img width="1512" alt="image"
src="https://github.com/user-attachments/assets/b13fe0f2-8c61-4ea8-9ea1-e61e571a90da"
/>

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
2025-04-09 01:03:43 +02:00
2308091b13 Remove overlay-scroll-bar (#11258)
## What

- Deprecate overlayscrollbars as we decided to follow the native
behavior
- rework on performances (avoid calling recoil states too much at field
level which is quite expensive)
- Also implements:
https://github.com/twentyhq/core-team-issues/issues/569

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2025-04-04 16:13:48 +02:00
Baptiste DevessierandGitHub 9353e777ea Copy JSON values on click (#11382)
https://github.com/user-attachments/assets/1638c196-fb9c-4f2b-910c-6d8b0693a37a

Closes https://github.com/twentyhq/core-team-issues/issues/568
2025-04-04 11:20:57 +02:00
Antoine MoreauxandGitHub 44bf393b06 fix(email-validation): validation email cross workspace (#11261)
- Finish removing captcha guard from validation  email
- Fix an issue where domain validation wasn't working on a multi-domain
setup
2025-04-02 08:06:34 +00:00
Paul RastoinandGitHub 9ad8287dbc [REFACTOR] twenty-shared multi barrel and CJS/ESM build with preconstruct (#11083)
# Introduction

In this PR we've migrated `twenty-shared` from a `vite` app
[libary-mode](https://vite.dev/guide/build#library-mode) to a
[preconstruct](https://preconstruct.tools/) "atomic" application ( in
the future would like to introduce preconstruct to handle of all our
atomic dependencies such as `twenty-emails` `twenty-ui` etc it will be
integrated at the monorepo's root directly, would be to invasive in the
first, starting incremental via `twenty-shared`)

For more information regarding the motivations please refer to nor:
- https://github.com/twentyhq/core-team-issues/issues/587
-
https://github.com/twentyhq/core-team-issues/issues/281#issuecomment-2630949682

close https://github.com/twentyhq/core-team-issues/issues/589
close https://github.com/twentyhq/core-team-issues/issues/590

## How to test
In order to ease the review this PR will ship all the codegen at the
very end, the actual meaning full diff is `+2,411 −114`
In order to migrate existing dependent packages to `twenty-shared` multi
barrel new arch you need to run in local:
```sh
yarn tsx packages/twenty-shared/scripts/migrateFromSingleToMultiBarrelImport.ts && \
npx nx run-many -t lint --fix -p twenty-front twenty-ui twenty-server twenty-emails twenty-shared twenty-zapier
```
Note that `migrateFromSingleToMultiBarrelImport` is idempotent, it's atm
included in the PR but should not be merged. ( such as codegen will be
added before merging this script will be removed )

## Misc
- related opened issue preconstruct
https://github.com/preconstruct/preconstruct/issues/617

## Closed related PR
- https://github.com/twentyhq/twenty/pull/11028
- https://github.com/twentyhq/twenty/pull/10993
- https://github.com/twentyhq/twenty/pull/10960

## Upcoming enhancement: ( in others dedicated PRs )
- 1/ refactor generate barrel to export atomic module instead of `*`
- 2/ generate barrel own package with several files and tests
- 3/ Migration twenty-ui the same way
- 4/ Use `preconstruct` at monorepo global level

## Conclusion
As always any suggestions are welcomed !
2025-03-22 19:16:06 +01:00
Charles BochetandGitHub 2039986684 Fix error messages on sign up (#10399)
In this PR:
- adding logs to track workspace creation performance
- refactor useIsWorkspaceSuspended to be more generic
- only fetch favorites and views if workspace is Active to avoid error
messages on sign up (workspace is not created yet)
2025-02-21 18:34:40 +01:00
EtienneandGitHub ef9328e2e9 add not found redirection logic if object in url param not exists (#10339)
closes #10150
2025-02-20 09:17:52 +01:00
Antoine MoreauxandGitHub e081d8ab5e refactor(auth): simplify continueWithEmail and remove useCallback (#10068)
Refactored continueWithEmail to remove unnecessary dependencies and
simplified the useIsMatchingLocation hook by eliminating useCallback.
This reduces complexity and addresses potential infinite loop issues.
2025-02-07 09:50:23 +00:00
Antoine MoreauxandGitHub aaea49d5f5 fix(auth): prevent infinite redirect (#10065)
Refactored the isMatchingLocation function to use useCallback for
memoization, improving performance by avoiding unnecessary re-creations.
Moved addTrailingSlash and getConstructedPath inside useCallback for
better encapsulation.
2025-02-07 09:27:11 +00:00
Antoine MoreauxandGitHub a85c4f263a fix(settings routing): handle trailing slashes in base paths (#10055)
Adjusted URL construction to properly handle trailing slashes in base
paths, ensuring consistent matching logic. Added logic for setting the
hotkey scope when navigating to the domain settings path.
2025-02-06 16:07:19 +00:00
Paul RastoinandGitHub 7fd89678b7 [CHORE] Avoid isDefined duplicated reference, move it to twenty-shared (#9967)
# Introduction
Avoid having multiple `isDefined` definition across our pacakges
Also avoid importing `isDefined` from `twenty-ui` which exposes a huge
barrel for a such little util function

## In a nutshell
Removed own `isDefined.ts` definition from `twenty-ui` `twenty-front`
and `twenty-server` to move it to `twenty-shared`.
Updated imports for each packages, and added explicit dependencies to
`twenty-shared` if not already in place

Related PR https://github.com/twentyhq/twenty/pull/9941
2025-02-01 12:10:10 +01:00
Félix MalfaitandGitHub 86b0a7952b Fix API key not displayed (#9766)
Fixes #9761

Instead of cleaning RecoilState we should keep the api key visible as
long as the user didn't refresh/leave the app, it's better from a UX
perspective and the code is also more elegant, removing a useEffect


Note: the root cause of the bug was a missing "/settings" path in
isMatchingLocation in useCleaningRecoilState (due to the recent
refactoring) ; but I think this fix is better
2025-01-21 14:18:22 +01:00
e1731bb31e chore: update codegen config for enum naming convention (#9751)
Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-21 11:34:33 +01:00
Félix MalfaitandGitHub 152902d1be New useNavigateApp (#9729)
Todo : 
- replace all instances of useNavigate(
- remove getSettingsPagePath
- add eslint rule to enfore usage of useNavigateApp instead of
useNavigate
2025-01-18 13:58:12 +01:00
Charles BochetandGitHub f545bd1c40 Treat suspended workspace as workspaces that need to be synced (#9669)
In this PR:
- migrate WorkspaceActivationStatus to twenty-shared (and update case to
make FE and BE consistent)
- introduce isWorkspaceActiveOrSuspended in twenty-shared
- refactor the code to use it (when we fetch data on the FE, we want to
keep SUSPENDED workspace working + when we sync workspaces we want it
too)
2025-01-16 15:01:04 +01:00
26058f3e25 Update ChooseYourPlan page with new trial period options (#9628)
### Context
- Update /plan-required page to let users get free trial without credit
card plan
- Update usePageChangeEffectNavigateLocation to redirect paused and
canceled subscription (suspended workspace) to /settings/billing page

### To do

- [x] Update usePageChangeEffectNavigateLocation test
- [x] Update ChooseYourPlan sb test



closes #9520

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-16 11:10:36 +01:00
f722a2d619 Add Email Verification for non-Microsoft/Google Emails (#9288)
Closes twentyhq/twenty#8240 

This PR introduces email verification for non-Microsoft/Google Emails:

## Email Verification SignInUp Flow:

https://github.com/user-attachments/assets/740e9714-5413-4fd8-b02e-ace728ea47ef

The email verification link is sent as part of the
`SignInUpStep.EmailVerification`. The email verification token
validation is handled on a separate page (`AppPath.VerifyEmail`). A
verification email resend can be triggered from both pages.

## Email Verification Flow Screenshots (In Order):

![image](https://github.com/user-attachments/assets/d52237dc-fcc6-4754-a40f-b7d6294eebad)

![image](https://github.com/user-attachments/assets/263a4b6b-db49-406b-9e43-6c0f90488bb8)

![image](https://github.com/user-attachments/assets/0343ae51-32ef-48b8-8167-a96deb7db99e)

## Sent Email Details (Subject & Template):
![Screenshot 2025-01-05 at 11 56
56 PM](https://github.com/user-attachments/assets/475840d1-7d47-4792-b8c6-5c9ef5e02229)

![image](https://github.com/user-attachments/assets/a41b3b36-a36f-4a8e-b1f9-beeec7fe23e4)

### Successful Email Verification Redirect:

![image](https://github.com/user-attachments/assets/e2fad9e2-f4b1-485e-8f4a-32163c2718e7)

### Unsuccessful Email Verification (invalid token, invalid email, token
expired, user does not exist, etc.):

![image](https://github.com/user-attachments/assets/92f4b65e-2971-4f26-a9fa-7aafadd2b305)

### Force Sign In When Email Not Verified:

![image](https://github.com/user-attachments/assets/86d0f188-cded-49a6-bde9-9630fd18d71e)

# TODOs:

## Sign Up Process

- [x] Introduce server-level environment variable
IS_EMAIL_VERIFICATION_REQUIRED (defaults to false)
- [x] Ensure users joining an existing workspace through an invite are
not required to validate their email
- [x] Generate an email verification token
- [x] Store the token in appToken
- [x] Send email containing the verification link
  - [x] Create new email template for email verification
- [x] Create a frontend page to handle verification requests

## Sign In Process

- [x] After verifying user credentials, check if user's email is
verified and prompt to to verify
- [x] Show an option to resend the verification email

## Database

- [x] Rename the `emailVerified` colum on `user` to to `isEmailVerified`
for consistency

## During Deployment
- [x] Run a script/sql query to set `isEmailVerified` to `true` for all
users with a Google/Microsoft email and all users that show an
indication of a valid subscription (e.g. linked credit card)
- I have created a draft migration file below that shows one possible
approach to implementing this change:

```typescript
import { MigrationInterface, QueryRunner } from 'typeorm';

export class UpdateEmailVerifiedForActiveUsers1733318043628
  implements MigrationInterface
{
  name = 'UpdateEmailVerifiedForActiveUsers1733318043628';

  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`
      CREATE TABLE core."user_email_verified_backup" AS
      SELECT id, email, "isEmailVerified"
      FROM core."user"
      WHERE "deletedAt" IS NULL;
    `);

    await queryRunner.query(`
      -- Update isEmailVerified for users who have been part of workspaces with active subscriptions
      UPDATE core."user" u
      SET "isEmailVerified" = true
      WHERE EXISTS (
        -- Check if user has been part of a workspace through userWorkspace table
        SELECT 1 
        FROM core."userWorkspace" uw
        JOIN core."workspace" w ON uw."workspaceId" = w.id
        WHERE uw."userId" = u.id
        -- Check for valid subscription indicators
        AND (
          w."activationStatus" = 'ACTIVE'
          -- Add any other subscription-related conditions here
        )
      )
      AND u."deletedAt" IS NULL;
  `);
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.query(`
      UPDATE core."user" u
      SET "isEmailVerified" = b."isEmailVerified"
      FROM core."user_email_verified_backup" b
      WHERE u.id = b.id;
    `);

    await queryRunner.query(`DROP TABLE core."user_email_verified_backup";`);
  }
}

```

---------

Co-authored-by: Antoine Moreaux <moreaux.antoine@gmail.com>
Co-authored-by: Félix Malfait <felix@twenty.com>
2025-01-15 18:43:40 +01:00
martmullandGitHub c01e3af8ee Fix race condition on stripe subscription (#9629)
Fixes https://github.com/twentyhq/core-team-issues/issues/191
- remove automatic redirection on payment success page when subscription
status is undefined
- add an effect component to refresh the subscription status on payment
success page

Observation: Locally, I had to delay the stripe webhook subscription
created endpoint by 7s to see race condition issue


https://github.com/user-attachments/assets/463e1816-34fd-4c4f-b590-3994a3a3e91a
2025-01-15 16:08:34 +01:00
Lucas BordeauandGitHub 00a9646d68 Fixed date input fields (#9442)
- Fixed date input fields : proper hotkey management, like other fields
- Removed DropdownUnmountEffect which was causing many bugs.
2025-01-08 10:43:49 +01:00
MarieandGitHub 311b5f64c4 Refacto scroll + Aggregate queries for view groups (#9089)
Closes https://github.com/twentyhq/private-issues/issues/217.

Refactoring scroll not to cause table-wide re-render when opening a
dropdown (triggering a scroll lock) in the table.
2024-12-16 17:58:57 +01:00
martmullandGitHub b10d831371 8726 workflow add a test button in workflow code step (#9016)
- add test button to workflow code step
- add test tab to workflow code step


https://github.com/user-attachments/assets/e180a827-7321-49a2-8026-88490c557da2



![image](https://github.com/user-attachments/assets/cacbd756-de3f-4141-a84c-8e1853f6556b)

![image](https://github.com/user-attachments/assets/ee170d81-8a22-4178-bd6d-11a0e8c73365)
2024-12-13 10:16:29 +00:00
07aaf0801c fix: can't properly drag and drop in empty record group (#9039)
Fix #8968 

Fix issue with drag and drop when record group are empty.
Happy to discuss the implementation, as it's limited to the
`@hello-pangea/dnd` api.

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
2024-12-13 09:37:23 +01:00
e96ad9a1f2 Admin panel init (#8742)
WIP
Related issues - 
#7090 
#8547 
Master issue - 
#4499

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2024-11-28 13:43:11 +01:00
b09ecfbb8c Migrate to twenty-ui - display (#8004)
This PR was created by [GitStart](https://gitstart.com/) to address the
requirements from this ticket:
[TWNTY-6871](https://clients.gitstart.com/twenty/5449/tickets/TWNTY-6871).

 --- 

### Description

Migrate:

- Info display component
- Status display component
- SeparatorLineText display component

### Demo

###### SeparatorLineText In Storybook


![](https://assets-service.gitstart.com/4814/c0a2cd49-e545-469a-b3d3-c02eb462b60d.png)

Info Component on Storybook


![](https://assets-service.gitstart.com/4814/6f3019c5-99e0-4365-a81e-241294887f9e.png)

Status Component on Storybook


![](https://assets-service.gitstart.com/4814/29b5142a-468f-4d7e-88ff-4f3bfdd5abda.png)

###### Fixes twentyhq/private-issues#95

---------

Co-authored-by: gitstart-twenty <gitstart-twenty@users.noreply.github.com>
Co-authored-by: Charles Bochet <charles@twenty.com>
2024-10-24 17:50:14 +02:00
Baptiste DevessierandGitHub cddc92c00f Display workflow visualizer on show page (#6894)
- Removed the route I previously used to visualize workflows
- Created another tab in the `<ShowPageRightContainer />` component in
which we display the visualizer

Questions:

- Should I use a feature flag to hide the feature?

Closes #6858
2024-09-05 16:41:36 +02:00
martmullandGitHub 7e03419c16 Serverless function improvements (#6769)
- add layer for lambda execution
- add layer for local execution
- add package resolve for the monaco editor
- add route to get installed package for serverless functions
- add layer versioning
2024-09-02 15:25:20 +02:00
Baptiste DevessierandGitHub f7c99ddc7a Create new steps in workflow editor (#6764)
This PR adds the possibility of creating new steps. For now, only
actions are available. The steps are stored on the server, and the
visualizer is reloaded to include them.

Selecting a step opens the right drawer and shows its details. For now,
it's only the id of the step, but in the future, it will be the
parameters of the step.

In the future we'll want to let users add steps at any point in the
diagram. As a consequence, it's crucial to be able to walk in the tree
that make the steps to find the correct place where to put the new step.
I wrote a function that returns where the new step should be inserted.
This function will become recursive once we get branching implemented.

Things to mention:

- Reactflow needs every node and edge to have a unique identifier. In
this PR, I chose to use steps' id as nodes' id. That way, it's easy to
move from a node to a step, which helps make operations on a step
without resolving the step's id from the node's id.
2024-08-30 15:51:36 +02:00
747a1549e9 fix: defaultHomePagePath to be last visited page or alphatically first active object with the name (#6629)
### ISSUE 

- Closes #6612
- Closes #6125
- Closes #5949
- Closes #6652 

### Description 

- [x] need to check changes in jest test.
- [x] fallback to alphabetically firstActiveObject with the name if no
last visited exist


https://github.com/user-attachments/assets/dd11480b-c47f-4393-9857-8a55467061e3

- [x] fallback to last visited page with the last visited view by
default if no views would have toggled with subNav or viewChangeDropdown
it will fallback to INDEX or if no INDEX view then zero position view,
works with both subNavViewBar and viewChangeDropdown.



https://github.com/user-attachments/assets/33e97e55-2aa2-4c45-a3ab-fc8e43f4964c



https://github.com/user-attachments/assets/d1db76a2-da59-4cd2-81bf-d6119408fbbf

- [x] lastVisited view across the objects have been persisted so now
navigating back from x object to y or z to x will open always last
visited view and defaults to index or zero position view.



https://github.com/user-attachments/assets/70a01a11-a7ef-4031-926e-02923551466c

- [x] lastVisited Page with view has been persisted across the
workspace, scope is per workspace so jumping between workspace will also
work to have lastvisited object of particular workspace.



https://github.com/user-attachments/assets/25107339-8ec1-4421-9f6e-1da43b8f4816

- [x] when lastVisitedObject has been deactivated and going back from
settings should have a fallback Object that is alphabetically First
activeObject.



https://github.com/user-attachments/assets/6b24a933-b139-49ac-82b2-eac5e4848516


- [x] Creation of new View of **anyType** should also get persist and
that should get lastVisitedObject with View in case the user leaves from
there right away.



https://github.com/user-attachments/assets/80ff7114-051d-4e9b-ab58-0e1e3a7d328c

- [x] Similarly deleted view also works. 


https://github.com/user-attachments/assets/cb0b8043-fba4-4a66-941d-b3fa0a57eb22


- [x] fixed active subnav background when opening object directly with
root path **/** , it wasn't showing active subNav background.

Before: 


https://github.com/user-attachments/assets/db341c4a-f1f9-43c4-9838-37d1a1f5ab8e

Fixed: 


https://github.com/user-attachments/assets/0f0fd492-bc5d-4efe-b695-bee4e3f41d4e

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2024-08-28 17:15:54 +02:00
5d8162dc09 Added hotkeyScopes to serverless functions in settings (#6710)
Fixes #6656 
Is this the right way to implement keyboard listeners?
Please let me know, I'll make the changes accordingly.
:)


https://github.com/user-attachments/assets/af71d340-ead9-4659-81e6-a440522a194f

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2024-08-23 16:54:21 +02:00
5404a8ba2d fixes #6499 alignment issue on workspace switcher (#6589)
fix #6499 

- fix the size of workspace switcher to 32px from 40px

![Screenshot 2024-08-09
140212](https://github.com/user-attachments/assets/425c9089-8969-4d59-82ef-10572cfa7027)

- fix alignment issues

![Screenshot 2024-08-09
142357](https://github.com/user-attachments/assets/2e3e76f2-8a81-48e9-86ff-691c11215583)

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
2024-08-16 15:31:04 +02:00