Skip to content

Commit 66e8f64

Browse files
authored
Decouple tables workspace user assignment from Openops organization user assignment (#1750)
Fixes OPS-3220. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Fixed the user sign-up flow to ensure new users are properly assigned to both the default organization and default workspace during onboarding. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 0c299e4 commit 66e8f64

4 files changed

Lines changed: 35 additions & 27 deletions

File tree

packages/server/api/src/app/authentication/basic/authentication-service.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import { AuthenticationResponse } from '@openops/shared';
33
import { userService } from '../../user/user-service';
44
import { getProjectAndToken } from '../context/create-project-auth-context';
55
import { createUser } from '../new-user/create-user';
6-
import { assignDefaultOrganization } from '../new-user/organization-assignment';
6+
import {
7+
addUserToDefaultWorkspace,
8+
assignDefaultOrganization,
9+
} from '../new-user/organization-assignment';
710
import { SignInParams, SignUpParams } from '../types';
811
import {
912
assertPasswordMatches,
@@ -15,7 +18,8 @@ export const authenticationService = {
1518
async signUp(params: SignUpParams): Promise<AuthenticationResponse> {
1619
const { user, tablesRefreshToken } = await createUser(params);
1720

18-
await assignDefaultOrganization(user);
21+
const updatedUser = await assignDefaultOrganization(user);
22+
await addUserToDefaultWorkspace(updatedUser);
1923

2024
const projectContext = await getProjectAndToken(user, tablesRefreshToken);
2125
return buildAuthResponse(projectContext);
Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
import { AppSystemProp, system } from '@openops/server-shared';
2-
import { ApplicationError, ErrorCode, isNil, User } from '@openops/shared';
2+
import {
3+
ApplicationError,
4+
ErrorCode,
5+
isNil,
6+
User,
7+
UserWithOrganization,
8+
} from '@openops/shared';
39
import { openopsTables } from '../../openops-tables';
410
import { authenticateAdminUserInOpenOpsTables } from '../../openops-tables/auth-admin-tables';
511
import { organizationService } from '../../organization/organization.service';
612
import { projectService } from '../../project/project-service';
713
import { userService } from '../../user/user-service';
814

9-
export async function assignDefaultOrganization(user: User): Promise<void> {
15+
export async function assignDefaultOrganization(
16+
user: User,
17+
): Promise<UserWithOrganization> {
1018
let organization = await organizationService.getOldestOrganization();
1119

1220
const adminUser = await userService.getUserByEmailOrFail({
@@ -26,13 +34,11 @@ export async function assignDefaultOrganization(user: User): Promise<void> {
2634
});
2735
}
2836

29-
await userService.addUserToOrganization({
30-
id: user.id,
31-
organizationId: organization.id,
32-
});
37+
return userService.addUserToOrganization(user, organization.id);
38+
}
3339

34-
const updatedUser = await userService.getOneOrThrow({ id: user.id });
35-
const project = await projectService.getOneForUser(updatedUser);
40+
export async function addUserToDefaultWorkspace(user: User): Promise<void> {
41+
const project = await projectService.getOneForUser(user);
3642

3743
if (isNil(project)) {
3844
throw new ApplicationError({
@@ -43,19 +49,10 @@ export async function assignDefaultOrganization(user: User): Promise<void> {
4349
});
4450
}
4551

46-
await addUserToDefaultWorkspace({
47-
email: user.email,
48-
workspaceId: project.tablesWorkspaceId,
49-
});
50-
}
51-
52-
async function addUserToDefaultWorkspace(values: {
53-
email: string;
54-
workspaceId: number;
55-
}): Promise<void> {
5652
const { token: defaultToken } = await authenticateAdminUserInOpenOpsTables();
5753

5854
await openopsTables.addUserToWorkspace(defaultToken, {
59-
...values,
55+
email: user.email,
56+
workspaceId: project.tablesWorkspaceId,
6057
});
6158
}

packages/server/api/src/app/user/user-service.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
UserId,
1616
UserMeta,
1717
UserStatus,
18+
UserWithOrganization,
1819
} from '@openops/shared';
1920
import dayjs from 'dayjs';
2021
import { passwordHasher } from '../authentication/basic/password-hasher';
@@ -283,13 +284,14 @@ export const userService = {
283284
});
284285
},
285286

286-
async addUserToOrganization({
287-
id,
288-
organizationId,
289-
}: UpdateOrganizationIdParams): Promise<void> {
290-
await userRepo().update(id, {
291-
updated: dayjs().toISOString(),
287+
async addUserToOrganization(
288+
user: User,
289+
organizationId: OrganizationId,
290+
): Promise<UserWithOrganization> {
291+
return userRepo().save({
292+
...user,
292293
organizationRole: OrganizationRole.MEMBER,
294+
updated: dayjs().toISOString(),
293295
organizationId,
294296
});
295297
},

packages/shared/src/lib/user/user.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Static, Type } from '@sinclair/typebox';
22
import { BaseModelSchema } from '../common/base-model';
33
import { OpenOpsId } from '../common/id-generator';
4+
import { OrganizationId } from '../organization';
45

56
export type UserId = OpenOpsId;
67

@@ -42,6 +43,10 @@ export const User = Type.Object({
4243

4344
export type User = Static<typeof User>;
4445

46+
export type UserWithOrganization = User & {
47+
organizationId: OrganizationId;
48+
};
49+
4550
export const UserMeta = Type.Object({
4651
id: Type.String(),
4752
email: Type.String(),

0 commit comments

Comments
 (0)