user-service.ts•8.22 kB
import {
ActivepiecesError,
ApEdition,
apId,
Cursor,
ErrorCode,
isNil,
PlatformId,
PlatformRole,
ProjectId,
SeekPage,
spreadIfDefined,
User,
UserId,
UserStatus,
UserWithMetaInformation } from '@activepieces/shared'
import dayjs from 'dayjs'
import { In } from 'typeorm'
import { userIdentityService } from '../authentication/user-identity/user-identity-service'
import { repoFactory } from '../core/db/repo-factory'
import { projectMemberRepo } from '../ee/projects/project-role/project-role.service'
import { buildPaginator } from '../helper/pagination/build-paginator'
import { paginationHelper } from '../helper/pagination/pagination-utils'
import { system } from '../helper/system/system'
import { platformService } from '../platform/platform.service'
import { UserEntity, UserSchema } from './user-entity'
export const userRepo = repoFactory(UserEntity)
export const userService = {
async create(params: CreateParams): Promise<User> {
const user: NewUser = {
id: apId(),
identityId: params.identityId,
platformRole: params.platformRole,
status: UserStatus.ACTIVE,
externalId: params.externalId,
platformId: params.platformId,
}
return userRepo().save(user)
},
async update({ id, status, platformId, platformRole, externalId, lastChangelogDismissed }: UpdateParams): Promise<UserWithMetaInformation> {
const user = await this.getOrThrow({ id })
const platform = await platformService.getOneOrThrow(user.platformId!)
if (platform.ownerId === user.id && status === UserStatus.INACTIVE) {
throw new ActivepiecesError({
code: ErrorCode.VALIDATION,
params: {
message: 'Admin cannot be deactivated',
},
})
}
const updateResult = await userRepo().update({
id,
platformId,
}, {
...spreadIfDefined('status', status),
...spreadIfDefined('platformRole', platformRole),
...spreadIfDefined('externalId', externalId),
...spreadIfDefined('lastChangelogDismissed', lastChangelogDismissed),
})
if (updateResult.affected !== 1) {
throw new ActivepiecesError({
code: ErrorCode.ENTITY_NOT_FOUND,
params: {
entityType: 'user',
entityId: id,
},
})
}
return this.getMetaInformation({ id })
},
async list({ platformId, externalId, cursorRequest, limit }: ListParams): Promise<SeekPage<UserWithMetaInformation>> {
const decodedCursor = paginationHelper.decodeCursor(cursorRequest)
const paginator = buildPaginator({
entity: UserEntity,
query: {
limit,
afterCursor: decodedCursor.nextCursor,
beforeCursor: decodedCursor.previousCursor,
},
})
const { data, cursor } = await paginator.paginate(userRepo().createQueryBuilder('user').where({
platformId,
...spreadIfDefined('externalId', externalId),
}))
const usersWithMetaInformation = await Promise.all(data.map(this.getMetaInformation))
return paginationHelper.createPage<UserWithMetaInformation>(usersWithMetaInformation, cursor)
},
async getOneByIdentityIdOnly({ identityId }: GetOneByIdentityIdOnlyParams): Promise<User | null> {
return userRepo().findOneBy({ identityId })
},
async getByIdentityId({ identityId }: GetByIdentityId): Promise<UserSchema[]> {
return userRepo().find({ where: { identityId } })
},
async getOneByIdentityAndPlatform({ identityId, platformId }: GetOneByIdentityIdParams): Promise<User | null> {
return userRepo().findOneBy({ identityId, platformId })
},
async get({ id }: IdParams): Promise<User | null> {
return userRepo().findOneBy({ id })
},
async getOrThrow({ id }: IdParams): Promise<User> {
const user = await userRepo().findOneBy({ id })
if (isNil(user)) {
throw new ActivepiecesError({
code: ErrorCode.ENTITY_NOT_FOUND,
params: { entityType: 'user', entityId: id },
})
}
return user
},
async getOneOrFail({ id }: IdParams): Promise<User> {
return userRepo().findOneOrFail({ where: { id } })
},
async delete({ id, platformId }: DeleteParams): Promise<void> {
await userRepo().delete({
id,
platformId,
})
},
async getByPlatformRole(id: PlatformId, role: PlatformRole): Promise<UserSchema[]> {
return userRepo().find({ where: { platformId: id, platformRole: role }, relations: { identity: true } })
},
async listProjectUsers({ platformId, projectId }: ListUsersForProjectParams): Promise<UserWithMetaInformation[]> {
const users = await getUsersForProject(platformId, projectId)
const usersWithMetaInformation = await userRepo().find({ where: { platformId, id: In(users) }, relations: { identity: true } }).then((users) => users.map(this.getMetaInformation))
return Promise.all(usersWithMetaInformation)
},
async getByPlatformAndExternalId({
platformId,
externalId,
}: GetByPlatformAndExternalIdParams): Promise<User | null> {
return userRepo().findOneBy({
platformId,
externalId,
})
},
async getMetaInformation({ id }: IdParams): Promise<UserWithMetaInformation> {
const user = await userRepo().findOneByOrFail({ id })
const identity = await userIdentityService(system.globalLogger()).getBasicInformation(user.identityId)
return {
id: user.id,
email: identity.email,
firstName: identity.firstName,
lastName: identity.lastName,
platformId: user.platformId,
platformRole: user.platformRole,
status: user.status,
externalId: user.externalId,
lastChangelogDismissed: user.lastChangelogDismissed,
created: user.created,
updated: user.updated,
}
},
async addOwnerToPlatform({
id,
platformId,
}: UpdatePlatformIdParams): Promise<void> {
await userRepo().update(id, {
updated: dayjs().toISOString(),
platformRole: PlatformRole.ADMIN,
platformId,
})
},
}
async function getUsersForProject(platformId: PlatformId, projectId: string) {
const platformAdmins = await userRepo().find({ where: { platformId, platformRole: PlatformRole.ADMIN } }).then((users) => users.map((user) => user.id))
const edition = system.getEdition()
if (edition === ApEdition.COMMUNITY) {
return platformAdmins
}
const projectMembers = await projectMemberRepo().find({ where: { projectId, platformId } }).then((members) => members.map((member) => member.userId))
return [...platformAdmins, ...projectMembers]
}
type ListUsersForProjectParams = {
projectId: ProjectId
platformId: PlatformId
}
type DeleteParams = {
id: UserId
platformId: PlatformId
}
type ListParams = {
platformId: PlatformId
externalId?: string
cursorRequest: Cursor
limit?: number
}
type GetOneByIdentityIdOnlyParams = {
identityId: string
}
type GetByIdentityId = {
identityId: string
}
type GetOneByIdentityIdParams = {
identityId: string
platformId: PlatformId
}
type UpdateParams = {
id: UserId
status?: UserStatus
platformId: PlatformId
platformRole?: PlatformRole
externalId?: string
lastChangelogDismissed?: string
}
type CreateParams = {
identityId: string
platformId: string | null
externalId?: string
platformRole: PlatformRole
}
type NewUser = Omit<User, 'created' | 'updated'>
type GetByPlatformAndExternalIdParams = {
platformId: string
externalId: string
}
type IdParams = {
id: UserId
}
type UpdatePlatformIdParams = {
id: UserId
platformId: string
}