mirror of
https://github.com/hcengineering/platform.git
synced 2025-05-25 09:30:27 +00:00
Merge branch 'develop' into staging-new
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
commit
ae5b768859
@ -1,5 +1,11 @@
|
||||
import calendar from '@hcengineering/calendar'
|
||||
import { type PersonId, type WorkspaceInfoWithStatus, type WorkspaceUuid, systemAccountUuid } from '@hcengineering/core'
|
||||
import {
|
||||
type PersonId,
|
||||
type WorkspaceInfoWithStatus,
|
||||
type WorkspaceUuid,
|
||||
isActiveMode,
|
||||
systemAccountUuid
|
||||
} from '@hcengineering/core'
|
||||
import { getClient as getKvsClient } from '@hcengineering/kvs-client'
|
||||
import { createClient, getAccountClient } from '@hcengineering/server-client'
|
||||
import { generateToken } from '@hcengineering/server-token'
|
||||
@ -129,6 +135,7 @@ async function migrateCalendarIntegrations (
|
||||
if (ws == null) {
|
||||
continue
|
||||
}
|
||||
if (!isActiveMode(ws.mode)) continue
|
||||
token.workspace = ws.uuid
|
||||
|
||||
const personId = await getPersonIdByEmail(ws.uuid, token.email, token.userId)
|
||||
@ -215,6 +222,7 @@ async function migrateCalendarHistory (
|
||||
if (ws == null) {
|
||||
continue
|
||||
}
|
||||
if (!isActiveMode(ws.mode)) continue
|
||||
|
||||
const personId = await getPersonIdByEmail(ws.uuid, history.email, history.userId)
|
||||
if (personId == null) {
|
||||
|
@ -32,6 +32,7 @@ import {
|
||||
type PermissionsStore,
|
||||
type Person,
|
||||
type PersonsByPermission,
|
||||
type MembersBySpace,
|
||||
type SocialIdentity
|
||||
} from '@hcengineering/contact'
|
||||
import core, {
|
||||
@ -732,19 +733,33 @@ export async function resolveLocationData (loc: Location): Promise<LocationData>
|
||||
}
|
||||
|
||||
export function checkMyPermission (_id: Ref<Permission>, space: Ref<TypedSpace>, store: PermissionsStore): boolean {
|
||||
const arePermissionsDisabled = getMetadata(core.metadata.DisablePermissions) ?? false
|
||||
if (arePermissionsDisabled) return true
|
||||
return (store.whitelist.has(space) || store.ps[space]?.has(_id)) ?? false
|
||||
}
|
||||
|
||||
export function getPermittedPersons (
|
||||
_id: Ref<Permission>,
|
||||
space: Ref<TypedSpace>,
|
||||
store: PermissionsStore
|
||||
): Array<Ref<Person>> {
|
||||
const arePermissionsDisabled = getMetadata(core.metadata.DisablePermissions) ?? false
|
||||
if (arePermissionsDisabled) return Array.from(store.ms[space] ?? [])
|
||||
return store.whitelist.has(space) ? Array.from(store.ms[space] ?? []) : Array.from(store.ap[space]?.[_id] ?? [])
|
||||
}
|
||||
|
||||
const spacesStore = writable<Space[]>([])
|
||||
|
||||
export const permissionsStore = derived([spacesStore, personRefByAccountUuidStore], ([spaces, personRefByAccount]) => {
|
||||
const whitelistedSpaces = new Set<Ref<Space>>()
|
||||
const permissionsBySpace: PermissionsBySpace = {}
|
||||
const employeesByPermission: PersonsByPermission = {}
|
||||
const membersBySpace: MembersBySpace = {}
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
|
||||
for (const s of spaces) {
|
||||
membersBySpace[s._id] = new Set(s.members.map((m) => personRefByAccount.get(m)).filter(notEmpty))
|
||||
if (hierarchy.isDerived(s._class, core.class.TypedSpace)) {
|
||||
const type = client.getModel().findAllSync(core.class.SpaceType, { _id: (s as TypedSpace).type })[0]
|
||||
const mixin = type?.targetClass
|
||||
@ -790,6 +805,7 @@ export const permissionsStore = derived([spacesStore, personRefByAccountUuidStor
|
||||
return {
|
||||
ps: permissionsBySpace,
|
||||
ap: employeesByPermission,
|
||||
ms: membersBySpace,
|
||||
whitelist: whitelistedSpaces
|
||||
}
|
||||
})
|
||||
@ -815,6 +831,7 @@ spaceTypesQuery.query(core.class.SpaceType, {}, (types) => {
|
||||
projection: {
|
||||
_id: 1,
|
||||
type: 1,
|
||||
members: 1,
|
||||
...targetClasses
|
||||
} as any
|
||||
}
|
||||
|
@ -52,9 +52,11 @@ export const AVATAR_COLORS: ColorDefinition[] = [
|
||||
|
||||
export type PermissionsBySpace = Record<Ref<Space>, Set<Ref<Permission>>>
|
||||
export type PersonsByPermission = Record<Ref<Space>, Record<Ref<Permission>, Set<Ref<Person>>>>
|
||||
export type MembersBySpace = Record<Ref<Space>, Set<Ref<Person>>>
|
||||
export interface PermissionsStore {
|
||||
ps: PermissionsBySpace
|
||||
ap: PersonsByPermission
|
||||
ms: MembersBySpace
|
||||
whitelist: Set<Ref<Space>>
|
||||
}
|
||||
|
||||
|
@ -4,18 +4,18 @@
|
||||
//
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { RequestStatus } from '@hcengineering/request'
|
||||
import { Label, ModernDialog, showPopup } from '@hcengineering/ui'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { Employee } from '@hcengineering/contact'
|
||||
import { Class, Ref } from '@hcengineering/core'
|
||||
import { UserBoxItems, permissionsStore } from '@hcengineering/contact-resources'
|
||||
import { UserBoxItems, getPermittedPersons, permissionsStore } from '@hcengineering/contact-resources'
|
||||
import documents, {
|
||||
ControlledDocument,
|
||||
ControlledDocumentState,
|
||||
DocumentRequest
|
||||
} from '@hcengineering/controlled-documents'
|
||||
import { Class, Ref } from '@hcengineering/core'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { RequestStatus } from '@hcengineering/request'
|
||||
import { Label, ModernDialog, showPopup } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
import documentsRes from '../plugin'
|
||||
import { sendApprovalRequest, sendReviewRequest } from '../utils'
|
||||
@ -38,7 +38,7 @@
|
||||
const permissionId = isReviewRequest ? documents.permission.ReviewDocument : documents.permission.ApproveDocument
|
||||
$: permissionsSpace =
|
||||
controlledDoc.space === documents.space.UnsortedTemplates ? documents.space.QualityDocuments : controlledDoc.space
|
||||
$: permittedPeople = $permissionsStore.ap[permissionsSpace]?.[permissionId] ?? new Set()
|
||||
$: permittedPeople = new Set(getPermittedPersons(permissionId, permissionsSpace, $permissionsStore))
|
||||
$: permittedEmployees = Array.from(permittedPeople) as Ref<Employee>[]
|
||||
|
||||
let docRequest: DocumentRequest | undefined
|
||||
|
@ -14,7 +14,7 @@
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import { type Doc, type Ref, type Space } from '@hcengineering/core'
|
||||
import { TypedSpace, type Doc, type Ref, type Space } from '@hcengineering/core'
|
||||
import documents, {
|
||||
type DocumentSpace,
|
||||
type DocumentSpaceType,
|
||||
@ -23,7 +23,7 @@
|
||||
} from '@hcengineering/controlled-documents'
|
||||
import { SpaceSelector, getClient } from '@hcengineering/presentation'
|
||||
import { Label } from '@hcengineering/ui'
|
||||
import { permissionsStore } from '@hcengineering/contact-resources'
|
||||
import { checkMyPermission, permissionsStore } from '@hcengineering/contact-resources'
|
||||
|
||||
import { $locationStep as locationStep, locationStepUpdated } from '../../../stores/wizards/create-document'
|
||||
import DocumentParentSelector from '../../hierarchy/DocumentParentSelector.svelte'
|
||||
@ -82,9 +82,9 @@
|
||||
|
||||
$: canProceed = $locationStep.space !== undefined && $locationStep.project !== undefined
|
||||
$: hasParentSelector = $locationStep.space !== documents.space.UnsortedTemplates
|
||||
$: restrictedSpaces = Object.entries($permissionsStore.ps)
|
||||
.filter(([, pss]) => !pss.has(documents.permission.CreateDocument))
|
||||
.map(([s]) => s) as Ref<Space>[]
|
||||
$: restrictedSpaces = Object.keys($permissionsStore.ps).filter(
|
||||
(s) => !checkMyPermission(documents.permission.CreateDocument, s as Ref<TypedSpace>, $permissionsStore)
|
||||
) as Ref<TypedSpace>[]
|
||||
|
||||
$: spaceQuery = isTemplate
|
||||
? { _id: { $nin: restrictedSpaces }, archived: false, _class: { $nin: externalSpaces } }
|
||||
|
@ -13,12 +13,12 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { Label } from '@hcengineering/ui'
|
||||
import { TypedSpace, type Data, type Ref, type Permission } from '@hcengineering/core'
|
||||
import { type Employee, type PermissionsStore, getCurrentEmployee } from '@hcengineering/contact'
|
||||
import { getCurrentEmployee, type Employee } from '@hcengineering/contact'
|
||||
import { UserBoxItems, getPermittedPersons, permissionsStore } from '@hcengineering/contact-resources'
|
||||
import documents, { type ControlledDocument } from '@hcengineering/controlled-documents'
|
||||
import { UserBoxItems, permissionsStore } from '@hcengineering/contact-resources'
|
||||
import { TypedSpace, type Data, type Ref } from '@hcengineering/core'
|
||||
import { Label } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
export let controlledDoc: Data<ControlledDocument>
|
||||
export let space: Ref<TypedSpace>
|
||||
@ -34,23 +34,23 @@
|
||||
|
||||
$: permissionsSpace = space === documents.space.UnsortedTemplates ? documents.space.QualityDocuments : space
|
||||
|
||||
function getPermittedPersons (
|
||||
permission: Ref<Permission>,
|
||||
space: Ref<TypedSpace>,
|
||||
permissionsStore: PermissionsStore
|
||||
): Ref<Employee>[] {
|
||||
return Array.from(permissionsStore.ap[space]?.[permission] ?? []) as Ref<Employee>[]
|
||||
}
|
||||
$: permittedReviewers = getPermittedPersons(
|
||||
documents.permission.ReviewDocument,
|
||||
permissionsSpace,
|
||||
$permissionsStore
|
||||
) as Ref<Employee>[]
|
||||
|
||||
$: permittedReviewers = getPermittedPersons(documents.permission.ReviewDocument, permissionsSpace, $permissionsStore)
|
||||
|
||||
$: permittedApprovers = getPermittedPersons(documents.permission.ApproveDocument, permissionsSpace, $permissionsStore)
|
||||
$: permittedApprovers = getPermittedPersons(
|
||||
documents.permission.ApproveDocument,
|
||||
permissionsSpace,
|
||||
$permissionsStore
|
||||
) as Ref<Employee>[]
|
||||
|
||||
$: permittedCoAuthors = getPermittedPersons(
|
||||
documents.permission.CoAuthorDocument,
|
||||
permissionsSpace,
|
||||
$permissionsStore
|
||||
).filter((person) => person !== currentEmployee)
|
||||
).filter((person) => person !== currentEmployee) as Ref<Employee>[]
|
||||
|
||||
function handleUsersUpdated (type: 'reviewers' | 'approvers' | 'coAuthors', users: Ref<Employee>[]): void {
|
||||
dispatch('update', { type, users })
|
||||
|
@ -25,10 +25,10 @@
|
||||
type Project,
|
||||
type ProjectDocument
|
||||
} from '@hcengineering/controlled-documents'
|
||||
import { type Doc, type Ref, type Space } from '@hcengineering/core'
|
||||
import { TypedSpace, type Doc, type Ref, type Space } from '@hcengineering/core'
|
||||
import presentation, { getClient, SpaceSelector } from '@hcengineering/presentation'
|
||||
import { Button, Label } from '@hcengineering/ui'
|
||||
import { permissionsStore } from '@hcengineering/contact-resources'
|
||||
import { checkMyPermission, permissionsStore } from '@hcengineering/contact-resources'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
import documentsRes from '../../../plugin'
|
||||
@ -139,9 +139,9 @@
|
||||
const externalSpaces = hierarchy.getDescendants(documents.class.ExternalSpace)
|
||||
|
||||
$: hasParentSelector = targetSpaceId !== documents.space.UnsortedTemplates
|
||||
$: permissionRestrictedSpaces = Object.entries($permissionsStore.ps)
|
||||
.filter(([, pss]) => !pss.has(documents.permission.CreateDocument))
|
||||
.map(([s]) => s) as Ref<Space>[]
|
||||
$: permissionRestrictedSpaces = Object.keys($permissionsStore.ps).filter(
|
||||
(s) => !checkMyPermission(documents.permission.CreateDocument, s as Ref<TypedSpace>, $permissionsStore)
|
||||
) as Ref<TypedSpace>[]
|
||||
$: restrictedSpaces =
|
||||
sourceSpaceId !== undefined ? permissionRestrictedSpaces.concat(sourceSpaceId) : permissionRestrictedSpaces
|
||||
|
||||
|
@ -703,7 +703,9 @@ export async function getDocumentMetaTitle (
|
||||
|
||||
if (object === undefined) return ''
|
||||
|
||||
return object.title
|
||||
const hint = await translate(documentsResources.string.LatestVersionHint, {})
|
||||
|
||||
return object.title + ` (${hint})`
|
||||
}
|
||||
|
||||
export async function controlledDocumentReferenceObjectProvider (
|
||||
|
@ -25,7 +25,7 @@ import { getClient } from './client'
|
||||
import { addUserByEmail, removeUserByEmail } from './kvsUtils'
|
||||
import { IncomingSyncManager, lock } from './sync'
|
||||
import { CALENDAR_INTEGRATION, GoogleEmail, SCOPES, State, Token, User } from './types'
|
||||
import { getGoogleClient, getServiceToken } from './utils'
|
||||
import { getGoogleClient, getWorkspaceToken } from './utils'
|
||||
import { WatchController } from './watch'
|
||||
|
||||
interface AuthResult {
|
||||
@ -58,7 +58,7 @@ export class AuthController {
|
||||
await ctx.with('Create auth controller', { workspace: state.workspace, user: state.userId }, async () => {
|
||||
const mutex = await lock(`${state.workspace}:${state.userId}`)
|
||||
try {
|
||||
const client = await getClient(getServiceToken())
|
||||
const client = await getClient(getWorkspaceToken(state.workspace))
|
||||
const txOp = new TxOperations(client, core.account.System)
|
||||
const controller = new AuthController(ctx, accountClient, txOp, state)
|
||||
await controller.process(code)
|
||||
@ -78,7 +78,7 @@ export class AuthController {
|
||||
await ctx.with('Signout auth controller', { workspace, userId }, async () => {
|
||||
const mutex = await lock(`${workspace}:${userId}`)
|
||||
try {
|
||||
const client = await getClient(getServiceToken())
|
||||
const client = await getClient(getWorkspaceToken(workspace))
|
||||
const txOp = new TxOperations(client, core.account.System)
|
||||
const controller = new AuthController(ctx, accountClient, txOp, {
|
||||
userId,
|
||||
|
@ -19,7 +19,7 @@ import { getClient } from './client'
|
||||
import { getUserByEmail } from './kvsUtils'
|
||||
import { IncomingSyncManager } from './sync'
|
||||
import { GoogleEmail, Token } from './types'
|
||||
import { getGoogleClient, getServiceToken } from './utils'
|
||||
import { getGoogleClient, getWorkspaceToken } from './utils'
|
||||
|
||||
export class PushHandler {
|
||||
constructor (
|
||||
@ -29,7 +29,7 @@ export class PushHandler {
|
||||
|
||||
async sync (token: Token, calendarId: string | null): Promise<void> {
|
||||
await this.ctx.with('Push handler', { workspace: token.workspace, user: token.userId }, async () => {
|
||||
const client = await getClient(getServiceToken())
|
||||
const client = await getClient(getWorkspaceToken(token.workspace))
|
||||
const txOp = new TxOperations(client, core.account.System)
|
||||
const res = getGoogleClient()
|
||||
res.auth.setCredentials(token)
|
||||
|
@ -221,10 +221,11 @@ async function saveMessageToSpaces (
|
||||
archived: false,
|
||||
createdBy: modifiedBy,
|
||||
modifiedBy,
|
||||
parent: channel
|
||||
parent: channel,
|
||||
createdOn: createdDate
|
||||
},
|
||||
generateId(),
|
||||
undefined,
|
||||
createdDate,
|
||||
modifiedBy
|
||||
)
|
||||
await client.createMixin(
|
||||
|
Loading…
Reference in New Issue
Block a user