aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/util/SharingManager.tsx4
-rw-r--r--src/client/views/DocComponent.tsx2
-rw-r--r--src/client/views/collections/CollectionView.tsx2
-rw-r--r--src/fields/util.ts44
4 files changed, 28 insertions, 24 deletions
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 0c8f19eae..914253e3c 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -177,7 +177,7 @@ export class SharingManager extends React.Component<{}> {
users.forEach(({ user, sharingDoc }) => {
if (permission !== SharingPermissions.None) Doc.AddDocToList(sharingDoc, storage, doc); // add the doc to the sharingDoc if it hasn't already been added
- else GetEffectiveAcl(doc, undefined, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); // remove the doc from the list if it already exists
+ else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc)); // remove the doc from the list if it already exists
});
}
});
@@ -273,7 +273,7 @@ export class SharingManager extends React.Component<{}> {
distributeAcls(acl, permission as SharingPermissions, doc);
if (permission !== SharingPermissions.None) Doc.AddDocToList(sharingDoc, storage, doc);
- else GetEffectiveAcl(doc, undefined, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc));
+ else GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc));
});
}
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 98e888538..a55f4adaf 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -164,7 +164,7 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
return false;
}
else {
- if (this.props.Document[AclSym]) {
+ if (this.props.Document[AclSym] && Object.keys(this.props.Document[AclSym]).length) {
added.forEach(d => {
for (const [key, value] of Object.entries(this.props.Document[AclSym])) {
if (d.author === denormalizeEmail(key.substring(4)) && !d.aliasOf) distributeAcls(key, SharingPermissions.Admin, d, true);
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index cfd24545b..a27fa5a66 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -140,7 +140,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
return false;
}
else {
- if (this.props.Document[AclSym]) {
+ if (this.props.Document[AclSym] && Object.keys(this.props.Document[AclSym])) {
added.forEach(d => {
for (const [key, value] of Object.entries(this.props.Document[AclSym])) {
if (d.author === denormalizeEmail(key.substring(4)) && !d.aliasOf) distributeAcls(key, SharingPermissions.Admin, d, true);
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 56736028a..dd0444d61 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -155,32 +155,35 @@ export enum SharingPermissions {
}
// return acl from cache or cache the acl and return. bcz: Argh! NOT WORKING ... nothing gets invalidated properly....
-const getEffectiveAclCache = computedFn(function (target: any, playgroundProp: boolean, user?: string) { return getEffectiveAcl(target, playgroundProp, user); }, true);
+const getEffectiveAclCache = computedFn(function (target: any, user?: string) { return getEffectiveAcl(target, user); }, true);
/**
* Calculates the effective access right to a document for the current user.
*/
-export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number, user?: string): symbol {
- if (!target) return AclPrivate;
- if (in_prop === UpdatingFromServer) return AclAdmin; // requesting the UpdatingFromServer prop must always go through to keep the local DB consistent
- const playgroundProp = in_prop && DocServer.PlaygroundFields?.includes(in_prop.toString()) ? true : false;
- return getEffectiveAcl(target, playgroundProp, user);
+export function GetEffectiveAcl(target: any, user?: string): symbol {
+ return target ? getEffectiveAcl(target, user) : AclPrivate;
}
-function getEffectiveAcl(target: any, playgroundProp: boolean, user?: string): symbol {
+function getPropAcl(target: any, prop: string | symbol | number) {
+ if (prop === UpdatingFromServer) return AclAdmin; // requesting the UpdatingFromServer prop must always go through to keep the local DB consistent
+ if (prop && DocServer.PlaygroundFields?.includes(prop.toString())) return AclEdit; // playground props are always editable
+ return GetEffectiveAcl(target);
+}
+
+let HierarchyMapping: Map<symbol, number> | undefined;
+
+function getEffectiveAcl(target: any, user?: string): symbol {
if (target[UpdatingFromServer]) return AclAdmin; // all changes received from the server must be processed as Admin
// if the current user is the author of the document / the current user is a member of the admin group
const userChecked = user || Doc.CurrentUserEmail;
- if (userChecked === (target.__fields?.author || target.author)) return AclAdmin;
+ if (userChecked === (target.__fields?.author || target.author)) return AclAdmin; // target may be a Doc of Proxy, so check __fields.author and .author
if (SnappingManager.GetCachedGroupByName("Admin")) return AclAdmin;
+ const targetAcls = target[AclSym];
- if (target[AclSym] && Object.keys(target[AclSym]).length) {
+ if (targetAcls && Object.keys(targetAcls).length) {
+ if (_overrideAcl) return AclEdit;
- // if the acl is being overriden or the property being modified is one of the playground fields (which can be freely modified)
- if (_overrideAcl || playgroundProp) return AclEdit;
-
- let effectiveAcl = AclPrivate;
- const HierarchyMapping = new Map<symbol, number>([
+ HierarchyMapping = HierarchyMapping || new Map<symbol, number>([
[AclPrivate, 0],
[AclReadonly, 1],
[AclAddonly, 2],
@@ -188,12 +191,13 @@ function getEffectiveAcl(target: any, playgroundProp: boolean, user?: string): s
[AclAdmin, 4]
]);
- for (const [key, value] of Object.entries(target[AclSym])) {
+ let effectiveAcl = AclPrivate;
+ for (const [key, value] of Object.entries(targetAcls)) {
// there are issues with storing fields with . in the name, so they are replaced with _ during creation
// as a result we need to restore them again during this comparison.
const entity = denormalizeEmail(key.substring(4)); // an individual or a group
- if (SnappingManager.GetCachedGroupByName(entity) || userChecked === entity) {
- if (HierarchyMapping.get(value as symbol)! > HierarchyMapping.get(effectiveAcl)!) {
+ if (HierarchyMapping.get(value as symbol)! > HierarchyMapping.get(effectiveAcl)!) {
+ if (SnappingManager.GetCachedGroupByName(entity) || userChecked === entity) {
effectiveAcl = value as symbol;
if (effectiveAcl === AclAdmin) return effectiveAcl;
}
@@ -201,8 +205,8 @@ function getEffectiveAcl(target: any, playgroundProp: boolean, user?: string): s
}
// if there's an overriding acl set through the properties panel or sharing menu, that's what's returned if the user isn't an admin of the document
- const override = target[AclSym]["acl-Override"];
- if (override !== AclUnset && override !== undefined) effectiveAcl = target[AclSym]["acl-Override"];
+ const override = targetAcls["acl-Override"];
+ if (override !== AclUnset && override !== undefined) effectiveAcl = override;
// if we're in playground mode, return AclEdit (or AclAdmin if that's the user's effectiveAcl)
return DocServer?.Control?.isReadOnly?.() && HierarchyMapping.get(effectiveAcl)! < 3 ? AclEdit : effectiveAcl;
@@ -282,7 +286,7 @@ const layoutProps = ["panX", "panY", "width", "height", "nativeWidth", "nativeHe
"chromeStatus", "viewType", "gridGap", "xMargin", "yMargin", "autoHeight"];
export function setter(target: any, in_prop: string | symbol | number, value: any, receiver: any): boolean {
let prop = in_prop;
- const effectiveAcl = GetEffectiveAcl(target, in_prop);
+ const effectiveAcl = getPropAcl(target, prop);
if (effectiveAcl !== AclEdit && effectiveAcl !== AclAdmin) return true;
// if you're trying to change an acl but don't have Admin access / you're trying to change it to something that isn't an acceptable acl, you can't