Commit Graph

761 Commits

Author SHA1 Message Date
50f36e345e Lab (#9667)
https://github.com/twentyhq/core-team-issues/issues/76
2025-01-21 14:30:59 +01:00
4254ce9b2b fix(auth): improve query to find invitation (#9743) 2025-01-20 17:39:12 +01:00
b25330b607 fix: soft delete user when removing last userWorkspace (#9741)
### Context 

User (who has create a workspace and deleted it) can't create new
workspace because after deleting his previous workspace, user has not
been soft deleted.

There is several cases where user should be soft deleted :
1/ if user delete his account
2/ if a user's workspace is deleted + user has no other workspace
3/ If a workspaceMember is removed + user has no other workspace


### Solution
In `handleRemoveWorkspaceMember` method (logic used in the 3 cases),
soft delete user when removing the last userWorkspace


closes #9728

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-20 16:19:20 +01:00
59cb420d82 refactor(invitation): streamline invitation validation logic (#9699)
Replaced `validateInvitation` with `validatePersonalInvitation` across
services for consistent and specific validation handling. Removed
outdated public invitation validation and improved error handling for
workspace invitations. Updated tests to align with the refactored logic
and added checks for edge cases.
2025-01-20 12:25:08 +01:00
2c8954a44d fix(session-storage): add typing and trust proxy setting (#9725)
Added explicit typing for session storage options to improve type
safety. Enabled 'trust proxy' to ensure proper client IP and protocol
detection behind proxies. These changes improve security and reliability
in session handling.
2025-01-20 10:05:34 +00:00
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
6bd0244045 Fix date type update (#9700)
This PR fixes a problem with how TypeORM handles date without time. 

A date without time that is stored in PostgreSQL database as `date` type
gets returned as an ISO string date with a timezone that can shift its
date part in an unwanted way.

In short DB stores `2025-01-01`, TypeORM query builder returns
`2024-12-31T23:00:00Z` which gets parsed as `2024-12-31` on the front
end field.

We don't want to handle timezone here because we are manipulating a date
without its time part, so this PR adds a step that counteracts what
TypeORM does and returns `2025-01-01T00:00:00.000Z` so that the front
can parse it correctly.

@Weiko We might want to check other places of the backend where date
types are returned by TypeORM, we might have the same problem, this PR
only fixes it for updateOne resolver return.

- Fixed date persist on frontend which was shifting the date to a
different day due to timezone issue
- Fixed date returned by the backend update logic, which was shifting
the date by the timezone offset (so this PR adds back the offset so that
it stays at 00:00:00Z time)
2025-01-17 16:19:49 +01:00
b6b5fd1759 refactor(auth): remove redundant workspace lookup logic (#9716)
Removed unnecessary workspace lookup in `findWorkspaceForSignInUp` when
using password-based auth. Updated tests to validate the refactored
behavior and ensure no regressions in workspace resolution for different
auth scenarios.
2025-01-17 14:59:54 +01:00
f8f9bb2b78 Serverless function timeout concerns (#9689)
closes https://github.com/twentyhq/core-team-issues/issues/242
- unify timeout behavior between local and lambda
- add timeout in serverless entity
- set timeout default to 300s (5min)
2025-01-17 13:49:02 +00:00
679429447d fix(auth): update onboarding activation for specific users (#9702)
Adjust onboarding activation to trigger only for new users with
pictures. This prevents unnecessary activation steps for other user
types, streamlining the flow.
2025-01-17 14:31:24 +01:00
f44b31573a Set up localization with feature flag control (#9649)
Refers #8128 

Changes Introduced:
- Added i18n configuration.
- Added a feature flag for localization.
- Enabled language switching based on the flag.

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
2025-01-16 21:00:56 +01:00
6540057c98 fix(auth): return early in workspace access check (#9697)
Ensure early return in `hasUserAccessToWorkspaceOrThrow` for existing
users during sign-in. This prevents further unnecessary execution when
access validation is complete.
2025-01-16 17:36:53 +01:00
ad0dc7d664 fix(auth): streamline SSO auth callback logic (#9668)
Removed unused UserService dependency and simplified authCallback
function by using destructured parameters. Added checks for user email
and integrated invitation lookup and access validation for enhanced SSO
sign-in/up flow.
2025-01-16 16:07:06 +01:00
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
5982a5a8ba Aggregate queries and field metadata deletion (#9660) 2025-01-16 14:46:56 +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
f077efd171 Outlook integration (#9631)
Get Partial messages
2025-01-16 09:50:01 +01:00
789ff30dc7 fix(sso|auth): fix sso signinup (#9651)
Renamed `user` to `payload` for better context clarity and updated
related references. Adjusted the login token generation to use
`workspace.id`, improving readability and maintainability of the code.
2025-01-15 19:27:05 +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
585212b441 Aggregate queries - Fix empty / not empty operations on composite fields and array fields (#9644)
as per title

closes https://github.com/twentyhq/twenty/issues/9353
2025-01-15 16:59:46 +00:00
b5c5bee6cf Fix error message (#9646)
- fix typo
2025-01-15 16:29:42 +00:00
8e0c9fbf16 Aggregate queries - add seeds (#9640)
as per title
adding seeds on table views, kanban views, view groups
2025-01-15 15:52:09 +01:00
4fdea61f1d fix(auth): handle missing invitation during sign-up (#9572)
Add validation to throw an exception when a sign-up is attempted without
a valid invitation. Updated the test suite to cover this case and ensure
proper error handling with appropriate exceptions.

Fix https://github.com/twentyhq/twenty/issues/9566
https://github.com/twentyhq/twenty/issues/9564
2025-01-15 15:26:51 +01:00
eaa68424f5 Fix/record group index and seed (#9605)
- [x] [Disable group by on default view Options
menu](https://discord.com/channels/1130383047699738754/1328421803399446568)
- [x] Add default seed for view group
2025-01-15 09:37:15 +01:00
f2bee55e6c Remove missing log (#9621)
Forgot one log to remove
2025-01-14 17:42:33 +00:00
9360a6b1de Clean logs from console.time (#9620)
As title. We do not need those anymore.
2025-01-14 18:32:54 +01:00
42ddc09f74 Add command to tag workspace as suspended or as deleted (#9610)
In this PR:
- remove old versions upgrade commands
- add a 0.40 upgrade command to loop over all INACTIVE workspaces and
either: update to SUSPENDED (if workspaceSchema exists), update them to
SUSPENDED + deletedAt (if workspaceSchema does not exist anymore)

Note: why updating the deleted one to SUSPENDED? Because I plan to
remove INACTIVE case in the enum in 0.41

Tests made on production like database:
- dry-mode
- singleWorkspaceId
- 3 cases : suspended, deleted+suspended, deleted+suspended+delete all
data
2025-01-14 18:23:42 +01:00
508feb4e7e Introduce SUSPENDED Activation Status (#9609)
We are introducing a new workspace activationStatus "SUSPENDED". This
status represents a workspace which is SUSPENDED (either manually by the
admin or in case if IS_BILLING_ENABLED if the subscription is unpaid |
canceled | paused).

We will keep making sure these workspaces are healthy but prevent the
user from using it (they will be redirected to the billing page)
2025-01-14 14:52:45 +01:00
f0287d273d Add containsAny filter comparators in rest api (#9595)
- add missing `containsAny` filter comparator to filter multiSelect
fields
- fix app break if object with same name created
- fix flash when clicking on choose plan
### Before


https://github.com/user-attachments/assets/71709912-63e8-40f8-bc52-3ec0a62746bb


### After



https://github.com/user-attachments/assets/93ee02c2-e3d9-4bab-8b6a-62813fd40b2b
2025-01-14 11:40:02 +01:00
f9a90a6561 Fix featureFlag not matching gql type (#9585)
## Context

<img width="1349" alt="Screenshot 2025-01-13 at 17 18 24"
src="https://github.com/user-attachments/assets/4f5da0e9-0245-41c6-bde2-4d52e0ba34ed"
/>

Feature flags are stored in DB and then cast as FeatureFlag gql type
from its corresponding enum.
This means if a value from the DB does not match that enum type, the gql
server will reject the call when returning the object in the resolver.
(see screenshot above)

To solve that, we want to do 2 things:
- The ORM should still return the feature flag even if it's not valid,
this is actually in the DB so we don't want to "hide" that, however we
now have a warning message.
- The service is not changed for the same reason, the limitation comes
from gql behaviour so this is not the goal of the service nor the ORM to
act on it (except the warning message)
- The resolver should be updated, here we want to filter-out non-valid
feature flags so it does not break the API.

Because featureFlags used to be auto-generated by nestjsquery and we
want to change its behavior, I had to manually create a resolveField for
featureFlags and remove the auto-generated one. That means we lose some
features such as filter/sort coming from nestjs-query pagination (which
is something we will want to implement once we will remove nestjs-query
but that's a whole other subject)
2025-01-13 18:30:16 +01:00
55bae60f69 Fix wrong domainName for redirect url (#9586)
Closes https://github.com/twentyhq/twenty/issues/9097

Fixes the redirect url of stripe `checkout` and `billingPortal` sessions

## Before


https://github.com/user-attachments/assets/4ccab325-41e1-494e-854a-9d9a72e534f1

## After


https://github.com/user-attachments/assets/740b07f4-84b0-4670-a5b6-2684fde640c8
2025-01-13 17:03:01 +00:00
17850b76ab Aggregate queries follow up (#9581)
In this PR

- fixing Collapse on view groups views: aggregate bar should be included
in the collapse (@magrinj )
- respect the html table pattern: the aggregate bar is now a <tr>
element included in a <table> (before that, it was a <tr> not included
in anything)
- add a top-border on the aggregate bar
- introduce short labels for the on-cell value display (display "Empty"
instead of "Count empty" to lighten the interface)
- remove the feature flag !
2025-01-13 17:20:35 +01:00
b81879dead fix: drop record group feature flag (#9575) 2025-01-13 14:50:27 +01:00
5783d68d62 Remove serverless functions on version archivation (#9535)
Fixes https://github.com/twentyhq/core-team-issues/issues/52
- contrary to title, we do not remove serverless functions on workflow
version archivation because serverless fucntion might be used in another
workflow version
- we fix the serverless funciton version displayed in the code step
- we allow test function version in step display right drawer
- we delete serverless function only when serverless function has no
published version
2025-01-13 13:09:57 +00:00
b40f58a512 refactor(admin-panel): standardize FeatureFlagKey usage (#9548)
Replaced string-based feature flag keys with the typed FeatureFlagKey
enum across the admin panel module and related front-end hooks. This
ensures stronger type safety, reduces potential errors, and improves
consistency in handling feature flags.
2025-01-10 18:38:50 +01:00
92c119ed43 Add suggested values for variable dropdown (#9437)
<img width="378" alt="Capture d’écran 2025-01-07 à 15 37 20"
src="https://github.com/user-attachments/assets/c15abcac-684a-4c3b-ad12-62cf91afe927"
/>

Here is a first version:
- simple fields have a suggested value
- composite do not, but sub values of composite do
- json, arrays or complex values do not
2025-01-10 16:18:37 +01:00
5648c3b31c [refactor]: Remove isSSOEnabled logic throughout the codebase (#9462)
Eliminated all references to `isSSOEnabled` across the frontend,
backend, and configuration files. This change simplifies the codebase by
removing unnecessary feature flag checks, associated logic, and
environment variables. The SSO feature remains available without
reliance on this flag.
2025-01-10 14:45:35 +01:00
ddcb3dfd28 Feature flags env variable gating (#9481)
closes #9032

---------

Co-authored-by: Antoine Moreaux <moreaux.antoine@gmail.com>
2025-01-10 14:04:00 +01:00
75bf9e3c69 fix(admin-panel): resolve feature flag key mismatch (#9530)
Update feature flag handling by mapping input keys to enum values. This
ensures compatibility and prevents potential runtime errors when
updating workspace feature flags.
2025-01-10 12:30:42 +01:00
1f1cac3b00 chore: update returned attachement fullPath (#9516)
### Solution

fullPath prop on attachement (when returned by backend) is updated to
'domain + path' (formerly 'path').

Consequently, getFileAbsoluteURI util in front is removed.

closes #8763

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-09 19:12:36 +01:00
71a4593ba4 Move FieldMetadataType to twenty-shared (#9482)
Co-authored-by: Charles Bochet <charles@twenty.com>
2025-01-09 18:43:30 +01:00
c39af5f063 Add Integration and unit tests on Billing (#9317)
Solves [ https://github.com/twentyhq/private-issues/issues/214 ]

**TLDR**
Add unit and integration tests to Billing. First approach to run jest
integration tests directly from VSCode.

**In order to run the unit tests:**
Run unit test using the CLI or with the jest extension directly from
VSCode.

**In order to run the integration tests:**
Ensure that your database has the billingTables. If that's not the case,
migrate the database with IS_BILLING_ENABLED set to true:
` npx nx run twenty-server:test:integration
test/integration/billing/suites/billing-controller.integration-spec.ts`

**Doing:**
- Unit test on transformSubscriptionEventToSubscriptionItem
- More tests cases in billingController integration tests.

---------

Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
Co-authored-by: Weiko <corentin@twenty.com>
Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
2025-01-09 18:30:41 +01:00
4ed1db3845 fix AuthException parameters 2025-01-09 18:29:09 +01:00
524962a3d8 add httpExceptionHandlerService to oauthfilter (#9518)
## Context
500 from oauth controllers are never captured, fixing this
2025-01-09 17:48:36 +01:00
b61db75fc5 fix: add logo url response status check when creating workspace (#9474)
### Context
Workspace logo for work email is generated via twenty favicon service.
If twenty favicon can not find user domain favicon, it responds with
404.
### Fix
Check logo url before saving it when creating new workspace

closes #9359

---------

Co-authored-by: etiennejouan <jouan.etienne@gmail.com>
2025-01-09 14:07:48 +01:00
c535d21587 Include Date fields in aggregate operations on dates (#9479)
Follow-up on https://github.com/twentyhq/twenty/pull/9444/files - I had
forgotten to include Date field types (in addition to DateTime)
2025-01-09 12:13:21 +00:00
a2f2f4148a Migrate right drawer record page to the command menu (#9459)
Closes #9423



https://github.com/user-attachments/assets/0d93f170-8c4f-43ff-a0ca-3d2874d44820
2025-01-09 09:58:14 +01:00
e0e436a51d Fix File controller tests 2025-01-08 21:52:29 +01:00
9bfcd1573c Fix scalar throwing 500 (#9465)
## Context
Scalar validation/serde throws 500 instead of 400.

## Test
Before
<img width="785" alt="Screenshot 2025-01-08 at 19 17 14"
src="https://github.com/user-attachments/assets/61fadbd0-ce62-49be-bda6-c7047feb8725"
/>

After
<img width="831" alt="Screenshot 2025-01-08 at 19 16 05"
src="https://github.com/user-attachments/assets/d7038f0c-ea7a-4016-90d8-d2ce35c5763b"
/>
2025-01-08 19:24:14 +01:00
09513b66c4 Fix: Proper HTTP Status Code Usage for Authentication and Authorization Errors (#9463)
This PR ensures the correct usage of HTTP status codes (401 Unauthorized
and 403 Forbidden) for authentication and authorization errors, aligning
with standard HTTP semantics. The changes impact the handling of
AuthException across the application.

Changes Implemented
Updated Exception Handling Logic:

401 Unauthorized: Now used for cases where the user is unauthenticated
(e.g., missing JWT, expired JWT, invalid credentials).
403 Forbidden: Used strictly for cases where the user is authenticated
but lacks the required permissions.
2. Affected Files:
  before :- 
   
![Screenshot 2025-01-04
184617](https://github.com/user-attachments/assets/2d3f1c93-7d08-40d6-81b3-4c99d025a204)
 
  After:- 
  

![image](https://github.com/user-attachments/assets/7ca84182-8285-4d28-a4e4-56abefbdc4e2)
 
3.  Frontend Impact:

Verified frontend token renewal and error-handling flows.
Updated logic for handling 401 responses to trigger re-authentication
(e.g., token refresh or redirect to login).


4.Issue Resolved:   #9347
2025-01-08 19:23:14 +01:00