[permissions] Add settingsPermissions to getCurrentUser (#10054)
For a member with admin role: <img width="392" alt="Capture d’écran 2025-02-06 à 15 04 07" src="https://github.com/user-attachments/assets/f47e8611-9577-4d0b-889c-0846acfb0d75" /> For a member without admin role: <img width="394" alt="Capture d’écran 2025-02-06 à 15 04 51" src="https://github.com/user-attachments/assets/5daacd7a-aa4f-4e06-a886-661bf0830418" /> For a member of a workspace that does not have the feature flag enabled: <img width="390" alt="Capture d’écran 2025-02-06 à 15 05 22" src="https://github.com/user-attachments/assets/05071bd6-fd2d-4823-b121-8fd11313b833" />
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
import { Field, ObjectType } from '@nestjs/graphql';
|
||||
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
|
||||
|
||||
import { IDField } from '@ptc-org/nestjs-query-graphql';
|
||||
import { SettingsFeatures } from 'twenty-shared';
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
@ -19,6 +20,10 @@ import { TwoFactorMethod } from 'src/engine/core-modules/two-factor-method/two-f
|
||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
||||
registerEnumType(SettingsFeatures, {
|
||||
name: 'SettingsFeatures',
|
||||
});
|
||||
|
||||
@Entity({ name: 'userWorkspace', schema: 'core' })
|
||||
@ObjectType()
|
||||
@Unique('IndexOnUserIdAndWorkspaceIdUnique', ['userId', 'workspaceId'])
|
||||
@ -66,4 +71,7 @@ export class UserWorkspace {
|
||||
(twoFactorMethod) => twoFactorMethod.userWorkspace,
|
||||
)
|
||||
twoFactorMethods: Relation<TwoFactorMethod[]>;
|
||||
|
||||
@Field(() => [SettingsFeatures], { nullable: true })
|
||||
settingsPermissions?: SettingsFeatures[];
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ import { KeyValuePair } from 'src/engine/core-modules/key-value-pair/key-value-p
|
||||
import { OnboardingStatus } from 'src/engine/core-modules/onboarding/enums/onboarding-status.enum';
|
||||
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||
import { WorkspaceMember } from 'src/engine/core-modules/user/dtos/workspace-member.dto';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
||||
registerEnumType(OnboardingStatus, {
|
||||
name: 'OnboardingStatus',
|
||||
@ -99,4 +100,10 @@ export class User {
|
||||
|
||||
@Field(() => OnboardingStatus, { nullable: true })
|
||||
onboardingStatus: OnboardingStatus;
|
||||
|
||||
@Field(() => Workspace, { nullable: true })
|
||||
currentWorkspace: Relation<Workspace>;
|
||||
|
||||
@Field(() => UserWorkspace, { nullable: true })
|
||||
currentUserWorkspace?: Relation<UserWorkspace>;
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import { UserResolver } from 'src/engine/core-modules/user/user.resolver';
|
||||
import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module';
|
||||
import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
|
||||
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
|
||||
|
||||
import { userAutoResolverOpts } from './user.auto-resolver-opts';
|
||||
@ -48,6 +49,7 @@ import { UserService } from './services/user.service';
|
||||
DomainManagerModule,
|
||||
UserRoleModule,
|
||||
FeatureFlagModule,
|
||||
PermissionsModule,
|
||||
],
|
||||
exports: [UserService],
|
||||
providers: [UserService, UserResolver, TypeORMService],
|
||||
|
||||
@ -13,6 +13,7 @@ import crypto from 'crypto';
|
||||
|
||||
import { GraphQLJSONObject } from 'graphql-type-json';
|
||||
import { FileUpload, GraphQLUpload } from 'graphql-upload';
|
||||
import { SettingsFeatures } from 'twenty-shared';
|
||||
import { In, Repository } from 'typeorm';
|
||||
|
||||
import { SupportDriver } from 'src/engine/core-modules/environment/interfaces/support.interface';
|
||||
@ -47,6 +48,7 @@ import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator';
|
||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||
import { OriginHeader } from 'src/engine/decorators/auth/origin-header.decorator';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service';
|
||||
import { RoleDTO } from 'src/engine/metadata-modules/role/dtos/role.dto';
|
||||
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
|
||||
import { AccountsToReconnectKeys } from 'src/modules/connected-account/types/accounts-to-reconnect-key-value.type';
|
||||
@ -77,11 +79,15 @@ export class UserResolver {
|
||||
@InjectRepository(UserWorkspace, 'core')
|
||||
private readonly userWorkspaceRepository: Repository<UserWorkspace>,
|
||||
private readonly userRoleService: UserRoleService,
|
||||
private readonly permissionsService: PermissionsService,
|
||||
private readonly featureFlagService: FeatureFlagService,
|
||||
) {}
|
||||
|
||||
@Query(() => User)
|
||||
async currentUser(@AuthUser() { id: userId }: User): Promise<User> {
|
||||
async currentUser(
|
||||
@AuthUser() { id: userId }: User,
|
||||
@AuthWorkspace() workspace: Workspace,
|
||||
): Promise<User> {
|
||||
const user = await this.userRepository.findOne({
|
||||
where: {
|
||||
id: userId,
|
||||
@ -94,7 +100,36 @@ export class UserResolver {
|
||||
new AuthException('User not found', AuthExceptionCode.USER_NOT_FOUND),
|
||||
);
|
||||
|
||||
return user;
|
||||
const permissionsEnabled = await this.featureFlagService.isFeatureEnabled(
|
||||
FeatureFlagKey.IsPermissionsEnabled,
|
||||
workspace.id,
|
||||
);
|
||||
|
||||
if (permissionsEnabled === true) {
|
||||
const currentUserWorkspace = user.workspaces.find(
|
||||
(userWorkspace) => userWorkspace.workspace.id === workspace.id,
|
||||
);
|
||||
|
||||
if (!currentUserWorkspace) {
|
||||
throw new Error('Current user workspace not found');
|
||||
}
|
||||
const permissions =
|
||||
await this.permissionsService.getUserWorkspaceSettingsPermissions({
|
||||
userWorkspaceId: currentUserWorkspace.id,
|
||||
});
|
||||
|
||||
const permittedFeatures: SettingsFeatures[] = (
|
||||
Object.keys(permissions) as SettingsFeatures[]
|
||||
).filter((feature) => permissions[feature] === true);
|
||||
|
||||
currentUserWorkspace.settingsPermissions = permittedFeatures;
|
||||
user.currentUserWorkspace = currentUserWorkspace;
|
||||
}
|
||||
|
||||
return {
|
||||
...user,
|
||||
currentWorkspace: workspace,
|
||||
};
|
||||
}
|
||||
|
||||
@ResolveField(() => GraphQLJSONObject)
|
||||
|
||||
Reference in New Issue
Block a user