Update manifest structure (#17547)
Move all sync entities in an `entities` key. Rename functions to
logicFunctions
```json
{
application: {
...
},
entities: {
objects: [],
logicFunctions: [],
...
}
}
```
This commit is contained in:
+70
-137
@@ -3,14 +3,14 @@ import { Injectable, Logger } from '@nestjs/common';
|
||||
import { parse } from 'path';
|
||||
|
||||
import {
|
||||
ApplicationManifest,
|
||||
Manifest,
|
||||
FieldManifest,
|
||||
ObjectExtensionManifest,
|
||||
ObjectManifest,
|
||||
RelationFieldManifest,
|
||||
RoleManifest,
|
||||
LogicFunctionManifest,
|
||||
LogicFunctionTriggerManifest,
|
||||
ObjectFieldManifest,
|
||||
RelationFieldManifest,
|
||||
} from 'twenty-shared/application';
|
||||
import { FieldMetadataType, HTTPMethod, Sources } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
@@ -29,7 +29,6 @@ import { FieldMetadataService } from 'src/engine/metadata-modules/field-metadata
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { findFlatEntitiesByApplicationId } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entities-by-application-id.util';
|
||||
import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { buildObjectIdByNameMaps } from 'src/engine/metadata-modules/flat-object-metadata/utils/build-object-id-by-name-maps.util';
|
||||
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
||||
import { FieldPermissionService } from 'src/engine/metadata-modules/object-permission/field-permission/field-permission.service';
|
||||
import { ObjectPermissionService } from 'src/engine/metadata-modules/object-permission/object-permission.service';
|
||||
@@ -87,21 +86,21 @@ export class ApplicationSyncService {
|
||||
applicationId: application.id,
|
||||
});
|
||||
|
||||
await this.syncRelations({
|
||||
await this.syncObjectRelations({
|
||||
objectsToSync: manifest.objects,
|
||||
workspaceId,
|
||||
applicationId: application.id,
|
||||
});
|
||||
|
||||
if (manifest.objectExtensions && manifest.objectExtensions.length > 0) {
|
||||
await this.syncObjectExtensionsOrThrow({
|
||||
objectExtensionsToSync: manifest.objectExtensions,
|
||||
if (manifest.fields.length > 0) {
|
||||
await this.syncFieldsOrThrow({
|
||||
fieldsToSync: manifest.fields,
|
||||
workspaceId,
|
||||
applicationId: application.id,
|
||||
});
|
||||
}
|
||||
|
||||
if (manifest.functions.length > 0) {
|
||||
if (manifest.logicFunctions.length > 0) {
|
||||
if (!isDefined(application.logicFunctionLayerId)) {
|
||||
throw new ApplicationException(
|
||||
`Failed to sync logic function, could not find a logic function layer.`,
|
||||
@@ -110,7 +109,7 @@ export class ApplicationSyncService {
|
||||
}
|
||||
|
||||
await this.syncLogicFunctions({
|
||||
logicFunctionsToSync: manifest.functions,
|
||||
logicFunctionsToSync: manifest.logicFunctions,
|
||||
code: manifest.sources,
|
||||
workspaceId,
|
||||
applicationId: application.id,
|
||||
@@ -148,13 +147,13 @@ export class ApplicationSyncService {
|
||||
version: packageJson.version,
|
||||
sourcePath: 'cli-sync', // Placeholder for CLI-synced apps
|
||||
logicFunctionLayerId: null,
|
||||
defaultLogicFunctionRoleId: null,
|
||||
defaultRoleId: null,
|
||||
workspaceId,
|
||||
}));
|
||||
|
||||
let logicFunctionLayerId = application.logicFunctionLayerId;
|
||||
|
||||
if (manifest.functions.length > 0) {
|
||||
if (manifest.logicFunctions.length > 0) {
|
||||
if (!isDefined(logicFunctionLayerId)) {
|
||||
logicFunctionLayerId = (
|
||||
await this.logicFunctionLayerService.create(
|
||||
@@ -190,7 +189,7 @@ export class ApplicationSyncService {
|
||||
description: manifest.application.description,
|
||||
version: packageJson.version,
|
||||
logicFunctionLayerId,
|
||||
defaultLogicFunctionRoleId: null,
|
||||
defaultRoleId: null,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -199,13 +198,13 @@ export class ApplicationSyncService {
|
||||
workspaceId,
|
||||
applicationId,
|
||||
}: {
|
||||
manifest: ApplicationManifest;
|
||||
manifest: Manifest;
|
||||
workspaceId: string;
|
||||
applicationId: string;
|
||||
}) {
|
||||
let defaultLogicFunctionRoleId: string | null = null;
|
||||
let defaultRoleId: string | null = null;
|
||||
|
||||
for (const role of manifest.roles ?? []) {
|
||||
for (const role of manifest.roles) {
|
||||
let existingRole = await this.roleService.getRoleByUniversalIdentifier({
|
||||
universalIdentifier: role.universalIdentifier,
|
||||
workspaceId,
|
||||
@@ -235,15 +234,15 @@ export class ApplicationSyncService {
|
||||
|
||||
if (
|
||||
existingRole.universalIdentifier ===
|
||||
manifest.application.functionRoleUniversalIdentifier
|
||||
manifest.application.defaultRoleUniversalIdentifier
|
||||
) {
|
||||
defaultLogicFunctionRoleId = existingRole.id;
|
||||
defaultRoleId = existingRole.id;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDefined(defaultLogicFunctionRoleId)) {
|
||||
if (isDefined(defaultRoleId)) {
|
||||
await this.applicationService.update(applicationId, {
|
||||
defaultLogicFunctionRoleId: defaultLogicFunctionRoleId,
|
||||
defaultRoleId: defaultRoleId,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -269,19 +268,13 @@ export class ApplicationSyncService {
|
||||
},
|
||||
);
|
||||
|
||||
const { idByNameSingular: objectIdByNameSingular } =
|
||||
buildObjectIdByNameMaps(flatObjectMetadataMaps);
|
||||
|
||||
const formattedObjectPermissions = role.objectPermissions
|
||||
?.map((perm) => ({
|
||||
...perm,
|
||||
objectMetadataId: isDefined(perm.objectNameSingular)
|
||||
? objectIdByNameSingular[perm.objectNameSingular]
|
||||
: isDefined(perm.objectUniversalIdentifier)
|
||||
? flatObjectMetadataMaps.idByUniversalIdentifier[
|
||||
perm.objectUniversalIdentifier
|
||||
]
|
||||
: undefined,
|
||||
objectMetadataId:
|
||||
flatObjectMetadataMaps.idByUniversalIdentifier[
|
||||
perm.objectUniversalIdentifier
|
||||
],
|
||||
}))
|
||||
.filter((perm): perm is typeof perm & { objectMetadataId: string } =>
|
||||
isDefined(perm.objectMetadataId),
|
||||
@@ -299,32 +292,15 @@ export class ApplicationSyncService {
|
||||
|
||||
const formattedFieldPermissions = role?.fieldPermissions
|
||||
?.map((perm) => {
|
||||
const objectMetadataId = isDefined(perm.objectNameSingular)
|
||||
? objectIdByNameSingular[perm.objectNameSingular]
|
||||
: isDefined(perm.objectUniversalIdentifier)
|
||||
? flatObjectMetadataMaps.idByUniversalIdentifier[
|
||||
perm.objectUniversalIdentifier
|
||||
]
|
||||
: undefined;
|
||||
const objectMetadataId =
|
||||
flatObjectMetadataMaps.idByUniversalIdentifier[
|
||||
perm.objectUniversalIdentifier
|
||||
];
|
||||
|
||||
const fieldMetadataId = isDefined(objectMetadataId)
|
||||
? isDefined(perm.fieldName)
|
||||
? Object.values(flatFieldMetadataMaps.byId).find(
|
||||
(flatField) =>
|
||||
isDefined(flatField) &&
|
||||
flatField.objectMetadataId === objectMetadataId &&
|
||||
flatField.name === perm.fieldName,
|
||||
)?.id
|
||||
: isDefined(perm.fieldUniversalIdentifier)
|
||||
? Object.values(flatFieldMetadataMaps.byId).find(
|
||||
(flatField) =>
|
||||
isDefined(flatField) &&
|
||||
flatField.objectMetadataId === objectMetadataId &&
|
||||
flatField.universalIdentifier ===
|
||||
perm.fieldUniversalIdentifier,
|
||||
)?.id
|
||||
: undefined
|
||||
: undefined;
|
||||
const fieldMetadataId =
|
||||
flatFieldMetadataMaps.idByUniversalIdentifier[
|
||||
perm.fieldUniversalIdentifier
|
||||
];
|
||||
|
||||
return {
|
||||
...perm,
|
||||
@@ -365,7 +341,7 @@ export class ApplicationSyncService {
|
||||
}
|
||||
|
||||
private isRelationFieldManifest(
|
||||
field: FieldManifest | RelationFieldManifest,
|
||||
field: ObjectFieldManifest,
|
||||
): field is RelationFieldManifest {
|
||||
return this.isFieldTypeRelation(field.type);
|
||||
}
|
||||
@@ -374,26 +350,22 @@ export class ApplicationSyncService {
|
||||
return type === FieldMetadataType.RELATION;
|
||||
}
|
||||
|
||||
private async syncFieldsWithoutRelations({
|
||||
private async syncObjectFieldsWithoutRelations({
|
||||
objectId,
|
||||
fieldsToSync: allFieldsToSync,
|
||||
fieldsToSync,
|
||||
workspaceId,
|
||||
applicationId,
|
||||
}: {
|
||||
objectId: string;
|
||||
workspaceId: string;
|
||||
applicationId: string;
|
||||
fieldsToSync?: (FieldManifest | RelationFieldManifest)[];
|
||||
fieldsToSync: ObjectFieldManifest[];
|
||||
}) {
|
||||
if (!isDefined(allFieldsToSync)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fieldsToSync = allFieldsToSync.filter(
|
||||
const fieldsWithoutRelation = fieldsToSync.filter(
|
||||
(field): field is FieldManifest => !this.isRelationFieldManifest(field),
|
||||
);
|
||||
|
||||
if (fieldsToSync.length === 0) {
|
||||
if (fieldsWithoutRelation.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -414,7 +386,7 @@ export class ApplicationSyncService {
|
||||
!this.isFieldTypeRelation(field.type),
|
||||
) as FlatFieldMetadata[];
|
||||
|
||||
const fieldsToSyncUniversalIds = fieldsToSync.map(
|
||||
const fieldsToSyncUniversalIds = fieldsWithoutRelation.map(
|
||||
(field) => field.universalIdentifier,
|
||||
);
|
||||
|
||||
@@ -436,7 +408,7 @@ export class ApplicationSyncService {
|
||||
fieldsToSyncUniversalIds.includes(field.universalIdentifier),
|
||||
);
|
||||
|
||||
const fieldsToCreate = fieldsToSync.filter(
|
||||
const fieldsToCreate = fieldsWithoutRelation.filter(
|
||||
(fieldToSync) =>
|
||||
!existingFieldsStandardIds.includes(fieldToSync.universalIdentifier),
|
||||
);
|
||||
@@ -456,7 +428,7 @@ export class ApplicationSyncService {
|
||||
}
|
||||
|
||||
for (const fieldToUpdate of fieldsToUpdate) {
|
||||
const fieldToSync = fieldsToSync.find(
|
||||
const fieldToSync = fieldsWithoutRelation.find(
|
||||
(field) =>
|
||||
field.universalIdentifier === fieldToUpdate.universalIdentifier,
|
||||
);
|
||||
@@ -512,21 +484,25 @@ export class ApplicationSyncService {
|
||||
}
|
||||
}
|
||||
|
||||
private async syncRelationFields({
|
||||
private async syncObjectFieldsRelationOnly({
|
||||
objectId,
|
||||
relationsToSync,
|
||||
fieldsToSync,
|
||||
workspaceId,
|
||||
applicationId,
|
||||
flatObjectMetadataMaps,
|
||||
}: {
|
||||
objectId: string;
|
||||
relationsToSync: RelationFieldManifest[];
|
||||
fieldsToSync: ObjectFieldManifest[];
|
||||
workspaceId: string;
|
||||
applicationId: string;
|
||||
flatObjectMetadataMaps: {
|
||||
idByUniversalIdentifier: Partial<Record<string, string>>;
|
||||
};
|
||||
}) {
|
||||
const relationFields = fieldsToSync.filter((field) =>
|
||||
this.isRelationFieldManifest(field),
|
||||
);
|
||||
|
||||
const { flatFieldMetadataMaps } =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
@@ -535,7 +511,7 @@ export class ApplicationSyncService {
|
||||
},
|
||||
);
|
||||
|
||||
for (const relation of relationsToSync) {
|
||||
for (const relation of relationFields) {
|
||||
const existingRelationField = Object.values(
|
||||
flatFieldMetadataMaps.byId,
|
||||
).find(
|
||||
@@ -677,7 +653,7 @@ export class ApplicationSyncService {
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
await this.syncFieldsWithoutRelations({
|
||||
await this.syncObjectFieldsWithoutRelations({
|
||||
fieldsToSync: objectToSync.fields,
|
||||
objectId: objectToUpdate.id,
|
||||
workspaceId,
|
||||
@@ -710,7 +686,7 @@ export class ApplicationSyncService {
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
await this.syncFieldsWithoutRelations({
|
||||
await this.syncObjectFieldsWithoutRelations({
|
||||
fieldsToSync: objectToCreate.fields,
|
||||
objectId: createdObject.id,
|
||||
workspaceId,
|
||||
@@ -719,7 +695,7 @@ export class ApplicationSyncService {
|
||||
}
|
||||
}
|
||||
|
||||
private async syncRelations({
|
||||
private async syncObjectRelations({
|
||||
objectsToSync,
|
||||
workspaceId,
|
||||
applicationId,
|
||||
@@ -737,15 +713,6 @@ export class ApplicationSyncService {
|
||||
);
|
||||
|
||||
for (const objectToSync of objectsToSync) {
|
||||
const relationFields = objectToSync.fields.filter(
|
||||
(field): field is RelationFieldManifest =>
|
||||
this.isRelationFieldManifest(field),
|
||||
);
|
||||
|
||||
if (relationFields.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const sourceObjectId =
|
||||
flatObjectMetadataMaps.idByUniversalIdentifier[
|
||||
objectToSync.universalIdentifier
|
||||
@@ -758,9 +725,9 @@ export class ApplicationSyncService {
|
||||
);
|
||||
}
|
||||
|
||||
await this.syncRelationFields({
|
||||
await this.syncObjectFieldsRelationOnly({
|
||||
objectId: sourceObjectId,
|
||||
relationsToSync: relationFields,
|
||||
fieldsToSync: objectToSync.fields,
|
||||
workspaceId,
|
||||
applicationId,
|
||||
flatObjectMetadataMaps,
|
||||
@@ -768,12 +735,12 @@ export class ApplicationSyncService {
|
||||
}
|
||||
}
|
||||
|
||||
private async syncObjectExtensionsOrThrow({
|
||||
objectExtensionsToSync,
|
||||
private async syncFieldsOrThrow({
|
||||
fieldsToSync,
|
||||
workspaceId,
|
||||
applicationId,
|
||||
}: {
|
||||
objectExtensionsToSync: ObjectExtensionManifest[];
|
||||
fieldsToSync: FieldManifest[];
|
||||
workspaceId: string;
|
||||
applicationId: string;
|
||||
}) {
|
||||
@@ -785,36 +752,11 @@ export class ApplicationSyncService {
|
||||
},
|
||||
);
|
||||
|
||||
const { idByNameSingular: objectIdByNameSingular } =
|
||||
buildObjectIdByNameMaps(flatObjectMetadataMaps);
|
||||
|
||||
for (const objectExtension of objectExtensionsToSync) {
|
||||
const { targetObject, fields } = objectExtension;
|
||||
|
||||
let targetObjectId: string | undefined;
|
||||
|
||||
if (isDefined(targetObject.nameSingular)) {
|
||||
targetObjectId = objectIdByNameSingular[targetObject.nameSingular];
|
||||
|
||||
if (!isDefined(targetObjectId)) {
|
||||
throw new ApplicationException(
|
||||
`Failed to find target object with nameSingular "${targetObject.nameSingular}" for object extension`,
|
||||
ApplicationExceptionCode.OBJECT_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
} else if (isDefined(targetObject.universalIdentifier)) {
|
||||
targetObjectId =
|
||||
flatObjectMetadataMaps.idByUniversalIdentifier[
|
||||
targetObject.universalIdentifier
|
||||
];
|
||||
|
||||
if (!isDefined(targetObjectId)) {
|
||||
throw new ApplicationException(
|
||||
`Failed to find target object with universalIdentifier "${targetObject.universalIdentifier}" for object extension`,
|
||||
ApplicationExceptionCode.OBJECT_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
}
|
||||
for (const fieldToSync of fieldsToSync) {
|
||||
const targetObjectId =
|
||||
flatObjectMetadataMaps.idByUniversalIdentifier[
|
||||
fieldToSync.objectUniversalIdentifier
|
||||
];
|
||||
|
||||
if (!isDefined(targetObjectId)) {
|
||||
throw new ApplicationException(
|
||||
@@ -823,29 +765,20 @@ export class ApplicationSyncService {
|
||||
);
|
||||
}
|
||||
|
||||
// Sync regular fields for this extension
|
||||
await this.syncFieldsWithoutRelations({
|
||||
await this.syncObjectFieldsWithoutRelations({
|
||||
objectId: targetObjectId,
|
||||
fieldsToSync: fields,
|
||||
fieldsToSync: [fieldToSync],
|
||||
workspaceId,
|
||||
applicationId,
|
||||
});
|
||||
|
||||
// Sync relation fields for this extension
|
||||
const relationFields = fields.filter(
|
||||
(field): field is RelationFieldManifest =>
|
||||
this.isRelationFieldManifest(field),
|
||||
);
|
||||
|
||||
if (relationFields.length > 0) {
|
||||
await this.syncRelationFields({
|
||||
objectId: targetObjectId,
|
||||
relationsToSync: relationFields,
|
||||
workspaceId,
|
||||
applicationId,
|
||||
flatObjectMetadataMaps,
|
||||
});
|
||||
}
|
||||
await this.syncObjectFieldsRelationOnly({
|
||||
objectId: targetObjectId,
|
||||
fieldsToSync: [fieldToSync],
|
||||
workspaceId,
|
||||
applicationId,
|
||||
flatObjectMetadataMaps,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,10 +57,10 @@ export class ApplicationEntity extends WorkspaceRelatedEntity {
|
||||
logicFunctionLayerId: string | null;
|
||||
|
||||
@Column({ nullable: true, type: 'uuid' })
|
||||
defaultLogicFunctionRoleId: string | null;
|
||||
defaultRoleId: string | null;
|
||||
|
||||
@Field(() => RoleDTO, { nullable: true })
|
||||
defaultLogicFunctionRole: RoleDTO | null;
|
||||
defaultRole: RoleDTO | null;
|
||||
|
||||
@Column({ nullable: false, type: 'boolean', default: true })
|
||||
canBeUninstalled: boolean;
|
||||
|
||||
@@ -7,8 +7,6 @@ import {
|
||||
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import path, { join } from 'path';
|
||||
|
||||
import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs';
|
||||
import { PermissionFlagType } from 'twenty-shared/constants';
|
||||
import { FileFolder } from 'twenty-shared/types';
|
||||
@@ -164,33 +162,16 @@ export class ApplicationResolver {
|
||||
);
|
||||
}
|
||||
|
||||
const stream = createReadStream();
|
||||
const buffer = await streamToBuffer(stream);
|
||||
const buffer = await streamToBuffer(createReadStream());
|
||||
|
||||
const dirname = path.dirname(filePath);
|
||||
|
||||
const filename = path.basename(filePath);
|
||||
|
||||
const folderPath = join(
|
||||
`workspace-${workspaceId}`,
|
||||
applicationUniversalIdentifier,
|
||||
fileFolder,
|
||||
dirname,
|
||||
);
|
||||
|
||||
await this.fileStorageService.writeFile({
|
||||
file: buffer,
|
||||
name: filename,
|
||||
folder: folderPath,
|
||||
return await this.fileStorageService.writeFile_v2({
|
||||
sourceFile: buffer,
|
||||
mimeType: mimetype,
|
||||
});
|
||||
|
||||
const createdFile = this.fileRepository.create({
|
||||
path: join(folderPath, filename),
|
||||
size: buffer.length,
|
||||
fileFolder,
|
||||
applicationUniversalIdentifier,
|
||||
workspaceId,
|
||||
resourcePath: filePath,
|
||||
settings: { isTemporaryFile: false, toDelete: false },
|
||||
});
|
||||
|
||||
return await this.fileRepository.save(createdFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,17 +33,14 @@ export class ApplicationService {
|
||||
where: { id: applicationId, workspaceId },
|
||||
});
|
||||
|
||||
if (
|
||||
!isDefined(application) ||
|
||||
!isDefined(application.defaultLogicFunctionRoleId)
|
||||
) {
|
||||
if (!isDefined(application) || !isDefined(application.defaultRoleId)) {
|
||||
throw new ApplicationException(
|
||||
`Could not find application ${applicationId}`,
|
||||
ApplicationExceptionCode.APPLICATION_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
return application.defaultLogicFunctionRoleId;
|
||||
return application.defaultRoleId;
|
||||
}
|
||||
|
||||
async findWorkspaceTwentyStandardAndCustomApplicationOrThrow({
|
||||
|
||||
@@ -47,7 +47,7 @@ export class ApplicationDTO {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Field({ nullable: true })
|
||||
defaultLogicFunctionRoleId?: string;
|
||||
defaultRoleId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@Field(() => RoleDTO, { nullable: true })
|
||||
|
||||
+2
-2
@@ -1,12 +1,12 @@
|
||||
import { ArgsType, Field } from '@nestjs/graphql';
|
||||
|
||||
import GraphQLJSON from 'graphql-type-json';
|
||||
import { ApplicationManifest, PackageJson } from 'twenty-shared/application';
|
||||
import { Manifest, PackageJson } from 'twenty-shared/application';
|
||||
|
||||
@ArgsType()
|
||||
export class ApplicationInput {
|
||||
@Field(() => GraphQLJSON, { nullable: false })
|
||||
manifest: ApplicationManifest;
|
||||
manifest: Manifest;
|
||||
|
||||
@Field(() => GraphQLJSON, { nullable: false })
|
||||
packageJson: PackageJson;
|
||||
|
||||
+2
-2
@@ -126,9 +126,9 @@ export class CommonApiContextBuilderService {
|
||||
);
|
||||
} else if (
|
||||
isApplicationAuthContext(authContext) &&
|
||||
isDefined(authContext.application.defaultLogicFunctionRoleId)
|
||||
isDefined(authContext.application.defaultRoleId)
|
||||
) {
|
||||
roleId = authContext.application.defaultLogicFunctionRoleId;
|
||||
roleId = authContext.application.defaultRoleId;
|
||||
} else if (isUserAuthContext(authContext)) {
|
||||
const userWorkspaceRoleId =
|
||||
await this.userRoleService.getRoleIdForUserWorkspace({
|
||||
|
||||
Reference in New Issue
Block a user