@esri/hub-discussions
Advanced tools
Comparing version 25.5.0 to 25.6.0
import { AclCategory, AclSubCategory, Role, } from "../types"; | ||
import { CANNOT_DISCUSS } from "./constants"; | ||
import { isOrgAdmin } from "./platform"; | ||
var ChannelAction; | ||
(function (ChannelAction) { | ||
ChannelAction["READ_POSTS"] = "readPosts"; | ||
ChannelAction["WRITE_POSTS"] = "writePosts"; | ||
ChannelAction["MODERATE_CHANNEL"] = "moderateChannel"; | ||
})(ChannelAction || (ChannelAction = {})); | ||
export class ChannelPermission { | ||
constructor(channelAcl, creator) { | ||
this.ALLOWED_GROUP_MEMBER_TYPES = ["owner", "admin", "member"]; | ||
this.ADMIN_GROUP_MEMBER_TYPES = ["owner", "admin"]; | ||
this.ALLOWED_ROLES_FOR_POSTING = Object.values(Role).filter((role) => role !== Role.READ); | ||
this.ALLOWED_ROLES_FOR_MODERATION = [ | ||
Role.MODERATE, | ||
Role.MANAGE, | ||
Role.OWNER, | ||
]; | ||
this.isChannelAclEmpty = channelAcl.length === 0; | ||
@@ -25,3 +24,3 @@ this.permissionsByCategory = {}; | ||
canPostToChannel(user) { | ||
if (this.canAnyUserWrite()) { | ||
if (this.canAnyUser(ChannelAction.WRITE_POSTS)) { | ||
return true; | ||
@@ -32,6 +31,6 @@ } | ||
} | ||
return (this.canAnyAuthenticatedUserWrite() || | ||
this.isUserAWriteUser(user) || | ||
this.isUserPartOfWriteGroup(user) || | ||
this.isUserPartOfWriteOrg(user)); | ||
return (this.canAnyAuthenticatedUser(ChannelAction.WRITE_POSTS) || | ||
this.canSomeUser(ChannelAction.WRITE_POSTS, user) || | ||
this.canSomeUserGroup(ChannelAction.WRITE_POSTS, user) || | ||
this.canSomeUserOrg(ChannelAction.WRITE_POSTS, user)); | ||
} | ||
@@ -53,6 +52,62 @@ canCreateChannel(user) { | ||
return (user.username === this.channelCreator || | ||
this.isUserAModeratorUser(user) || | ||
this.isUserPartOfModeratorGroup(user) || | ||
this.isUserPartOfModeratorOrg(user)); | ||
this.canSomeUser(ChannelAction.MODERATE_CHANNEL, user) || | ||
this.canSomeUserGroup(ChannelAction.MODERATE_CHANNEL, user) || | ||
this.canSomeUserOrg(ChannelAction.MODERATE_CHANNEL, user)); | ||
} | ||
canReadChannel(user) { | ||
if (this.canAnyUser(ChannelAction.READ_POSTS)) { | ||
return true; | ||
} | ||
if (this.isUserUnAuthenticated(user)) { | ||
return false; | ||
} | ||
return (this.canAnyAuthenticatedUser(ChannelAction.READ_POSTS) || | ||
this.canSomeUser(ChannelAction.READ_POSTS, user) || | ||
this.canSomeUserGroup(ChannelAction.READ_POSTS, user) || | ||
this.canSomeUserOrg(ChannelAction.READ_POSTS, user)); | ||
} | ||
canAnyUser(action) { | ||
var _a; | ||
const anonymousUserRole = (_a = this.permissionsByCategory[AclCategory.ANONYMOUS_USER]) === null || _a === void 0 ? void 0 : _a[0].role; | ||
return channelActionLookup(action).includes(anonymousUserRole); | ||
} | ||
canAnyAuthenticatedUser(action) { | ||
var _a; | ||
const role = (_a = this.permissionsByCategory[AclCategory.AUTHENTICATED_USER]) === null || _a === void 0 ? void 0 : _a[0].role; | ||
return channelActionLookup(action).includes(role); | ||
} | ||
canSomeUser(action, user) { | ||
var _a; | ||
const userPermissions = (_a = this.permissionsByCategory[AclCategory.USER]) !== null && _a !== void 0 ? _a : []; | ||
const username = user.username; | ||
return userPermissions.some((permission) => { | ||
const { role, key } = permission; | ||
return key === username && channelActionLookup(action).includes(role); | ||
}); | ||
} | ||
canSomeUserGroup(action, user) { | ||
var _a; | ||
const groupAccessControls = (_a = this.permissionsByCategory[AclCategory.GROUP]) !== null && _a !== void 0 ? _a : []; | ||
const userGroupsById = this.mapUserGroupsById(user.groups); | ||
return groupAccessControls.some((permission) => { | ||
const group = userGroupsById[permission.key]; | ||
if (!group || !isGroupDiscussable(group)) { | ||
return false; | ||
} | ||
return (doesPermissionAllowGroupMemberType(permission, group) && | ||
channelActionLookup(action).includes(permission.role)); | ||
}); | ||
} | ||
canSomeUserOrg(action, user) { | ||
var _a; | ||
const orgPermissions = (_a = this.permissionsByCategory[AclCategory.ORG]) !== null && _a !== void 0 ? _a : []; | ||
return orgPermissions.some((permission) => { | ||
const { key } = permission; | ||
if (permission.key !== user.orgId) { | ||
return false; | ||
} | ||
return (doesPermissionAllowOrgRole(permission, user.role) && | ||
channelActionLookup(action).includes(permission.role)); | ||
}); | ||
} | ||
/** | ||
@@ -83,3 +138,3 @@ * canCreateChannelHelpers | ||
this.isMemberTypeAuthorized(userGroup) && | ||
this.isGroupDiscussable(userGroup)); | ||
isGroupDiscussable(userGroup)); | ||
}); | ||
@@ -107,62 +162,2 @@ } | ||
} | ||
canAnyUserWrite() { | ||
var _a; | ||
const role = (_a = this.permissionsByCategory[AclCategory.ANONYMOUS_USER]) === null || _a === void 0 ? void 0 : _a[0].role; | ||
return this.isAuthorizedToWritePost(role); | ||
} | ||
canAnyAuthenticatedUserWrite() { | ||
var _a; | ||
const role = (_a = this.permissionsByCategory[AclCategory.AUTHENTICATED_USER]) === null || _a === void 0 ? void 0 : _a[0].role; | ||
return this.isAuthorizedToWritePost(role); | ||
} | ||
isUserAWriteUser(user) { | ||
var _a; | ||
const userPermissions = (_a = this.permissionsByCategory[AclCategory.USER]) !== null && _a !== void 0 ? _a : []; | ||
const username = user.username; | ||
return userPermissions.some((permission) => { | ||
const { role, key } = permission; | ||
return key === username && this.isAuthorizedToWritePost(role); | ||
}); | ||
} | ||
isUserPartOfWriteGroup(user) { | ||
var _a; | ||
const groupPermissions = (_a = this.permissionsByCategory[AclCategory.GROUP]) !== null && _a !== void 0 ? _a : []; | ||
const userGroupsById = this.mapUserGroupsById(user.groups); | ||
return groupPermissions.some((permission) => { | ||
const userGroup = userGroupsById[permission.key]; | ||
return (userGroup && | ||
this.isMemberTypeAuthorized(userGroup) && | ||
this.isGroupDiscussable(userGroup) && | ||
(this.canAnyGroupMemberPost(permission) || | ||
(this.isMemberTypeAdmin(userGroup) && this.canAdminsPost(permission)))); | ||
}); | ||
} | ||
canAnyGroupMemberPost(permission) { | ||
const { subCategory, role } = permission; | ||
return (subCategory === AclSubCategory.MEMBER && | ||
this.isAuthorizedToWritePost(role)); | ||
} | ||
canAdminsPost(permission) { | ||
const { subCategory, role } = permission; | ||
return (subCategory === AclSubCategory.ADMIN && this.isAuthorizedToWritePost(role)); | ||
} | ||
isUserPartOfWriteOrg(user) { | ||
var _a; | ||
const orgPermissions = (_a = this.permissionsByCategory[AclCategory.ORG]) !== null && _a !== void 0 ? _a : []; | ||
const { orgId: userOrgId } = user; | ||
return orgPermissions.some((permission) => { | ||
const { key } = permission; | ||
return (key === userOrgId && | ||
(this.canAnyOrgMemberPost(permission) || | ||
(isOrgAdmin(user) && this.canAdminsPost(permission)))); | ||
}); | ||
} | ||
canAnyOrgMemberPost(permission) { | ||
const { subCategory, role } = permission; | ||
return (subCategory === AclSubCategory.MEMBER && | ||
this.isAuthorizedToWritePost(role)); | ||
} | ||
isAuthorizedToWritePost(role) { | ||
return this.ALLOWED_ROLES_FOR_POSTING.includes(role); | ||
} | ||
isUserUnAuthenticated(user) { | ||
@@ -181,59 +176,33 @@ return user.username === null || user.username === undefined; | ||
} | ||
isMemberTypeAdmin(userGroup) { | ||
const { userMembership: { memberType }, } = userGroup; | ||
return this.ADMIN_GROUP_MEMBER_TYPES.includes(memberType); | ||
} | ||
function isGroupDiscussable(userGroup) { | ||
const { typeKeywords = [] } = userGroup; | ||
return !typeKeywords.includes(CANNOT_DISCUSS); | ||
} | ||
function doesPermissionAllowGroupMemberType(permission, group) { | ||
if (permission.category !== AclCategory.GROUP || | ||
group.userMembership.memberType === "none") { | ||
return false; | ||
} | ||
isGroupDiscussable(userGroup) { | ||
const { typeKeywords = [] } = userGroup; | ||
return !typeKeywords.includes(CANNOT_DISCUSS); | ||
return ( | ||
// group owners and admins can do anything permissioned with SubCategory "member" | ||
group.userMembership.memberType === "owner" || | ||
group.userMembership.memberType === "admin" || | ||
permission.subCategory === AclSubCategory.MEMBER); | ||
} | ||
function doesPermissionAllowOrgRole(permission, orgRole) { | ||
return (permission.category === AclCategory.ORG && | ||
(permission.subCategory === AclSubCategory.MEMBER || | ||
(permission.subCategory === "admin" && orgRole === "org_admin"))); | ||
} | ||
function channelActionLookup(action) { | ||
if (action === ChannelAction.WRITE_POSTS) { | ||
return [Role.WRITE, Role.READWRITE, Role.MODERATE, Role.MANAGE, Role.OWNER]; | ||
} | ||
isAuthorizedToModerate(role) { | ||
return this.ALLOWED_ROLES_FOR_MODERATION.includes(role); | ||
if (action === ChannelAction.MODERATE_CHANNEL) { | ||
return [Role.MODERATE, Role.MANAGE, Role.OWNER]; | ||
} | ||
isUserAModeratorUser(user) { | ||
var _a; | ||
const userPermissions = (_a = this.permissionsByCategory[AclCategory.USER]) !== null && _a !== void 0 ? _a : []; | ||
const username = user.username; | ||
return userPermissions.some((permission) => { | ||
const { role, key } = permission; | ||
return key === username && this.isAuthorizedToModerate(role); | ||
}); | ||
} | ||
isUserPartOfModeratorGroup(user) { | ||
var _a; | ||
const groupPermissions = (_a = this.permissionsByCategory[AclCategory.GROUP]) !== null && _a !== void 0 ? _a : []; | ||
const userGroupsById = this.mapUserGroupsById(user.groups); | ||
return groupPermissions.some((permission) => { | ||
const userGroup = userGroupsById[permission.key]; | ||
return (userGroup && | ||
this.isMemberTypeAuthorized(userGroup) && | ||
(this.canAnyGroupMemberModerate(permission) || | ||
(this.isMemberTypeAdmin(userGroup) && | ||
this.canAdminsModerate(permission)))); | ||
}); | ||
} | ||
canAnyGroupMemberModerate(permission) { | ||
const { subCategory, role } = permission; | ||
return (subCategory === AclSubCategory.MEMBER && this.isAuthorizedToModerate(role)); | ||
} | ||
canAdminsModerate(permission) { | ||
const { subCategory, role } = permission; | ||
return (subCategory === AclSubCategory.ADMIN && this.isAuthorizedToModerate(role)); | ||
} | ||
isUserPartOfModeratorOrg(user) { | ||
var _a; | ||
const orgPermissions = (_a = this.permissionsByCategory[AclCategory.ORG]) !== null && _a !== void 0 ? _a : []; | ||
const { orgId: userOrgId } = user; | ||
return orgPermissions.some((permission) => { | ||
const { key } = permission; | ||
return (key === userOrgId && | ||
(this.canAnyOrgMemberModerate(permission) || | ||
(isOrgAdmin(user) && this.canAdminsModerate(permission)))); | ||
}); | ||
} | ||
canAnyOrgMemberModerate(permission) { | ||
const { subCategory, role } = permission; | ||
return (subCategory === AclSubCategory.MEMBER && this.isAuthorizedToModerate(role)); | ||
} | ||
// default to read action | ||
return [Role.READ, Role.READWRITE, Role.MODERATE, Role.MANAGE, Role.OWNER]; | ||
} | ||
//# sourceMappingURL=channel-permission.js.map |
@@ -1,38 +0,5 @@ | ||
import { reduceByGroupMembership } from "../platform"; | ||
export { canPostToChannel } from "./can-post-to-channel"; | ||
export { canCreateChannel } from "./can-create-channel"; | ||
export { canModifyChannel } from "./can-modify-channel"; | ||
function intersectGroups(membershipTypes) { | ||
return (user, channel) => { | ||
const { groups: sharedGroups = [] } = channel; | ||
const { groups: userGroups = [] } = user; | ||
const eligibleUserGroups = userGroups.reduce(reduceByGroupMembership(membershipTypes), []); | ||
const method = "some"; | ||
return sharedGroups[method]((group) => eligibleUserGroups.indexOf(group) > -1); | ||
}; | ||
} | ||
function isChannelOrgMember(channel, user) { | ||
// orgs.length = 1 until collaboration/discussion between many orgs is ideated | ||
return channel.orgs.length === 1 && channel.orgs.indexOf(user.orgId) > -1; | ||
} | ||
/** | ||
* Utility to determine whether User can view posts belonging to Channel | ||
* | ||
* @export | ||
* @param {IChannel} channel | ||
* @param {IUser} user | ||
* @return {*} {boolean} | ||
*/ | ||
export function canReadFromChannel(channel, user = {}) { | ||
if (channel.access === "private") { | ||
// ensure user is member of at least one group | ||
return intersectGroups(["member", "owner", "admin"])(user, channel); | ||
} | ||
if (channel.access === "org") { | ||
return (intersectGroups(["member", "owner", "admin"])(user, channel) || | ||
isChannelOrgMember(channel, user)); | ||
} | ||
// public channel | ||
return true; | ||
} | ||
export { canReadChannel, canReadFromChannel } from "./can-read-channel"; | ||
//# sourceMappingURL=index.js.map |
@@ -7,12 +7,11 @@ "use strict"; | ||
const platform_1 = require("./platform"); | ||
var ChannelAction; | ||
(function (ChannelAction) { | ||
ChannelAction["READ_POSTS"] = "readPosts"; | ||
ChannelAction["WRITE_POSTS"] = "writePosts"; | ||
ChannelAction["MODERATE_CHANNEL"] = "moderateChannel"; | ||
})(ChannelAction || (ChannelAction = {})); | ||
class ChannelPermission { | ||
constructor(channelAcl, creator) { | ||
this.ALLOWED_GROUP_MEMBER_TYPES = ["owner", "admin", "member"]; | ||
this.ADMIN_GROUP_MEMBER_TYPES = ["owner", "admin"]; | ||
this.ALLOWED_ROLES_FOR_POSTING = Object.values(types_1.Role).filter((role) => role !== types_1.Role.READ); | ||
this.ALLOWED_ROLES_FOR_MODERATION = [ | ||
types_1.Role.MODERATE, | ||
types_1.Role.MANAGE, | ||
types_1.Role.OWNER, | ||
]; | ||
this.isChannelAclEmpty = channelAcl.length === 0; | ||
@@ -29,3 +28,3 @@ this.permissionsByCategory = {}; | ||
canPostToChannel(user) { | ||
if (this.canAnyUserWrite()) { | ||
if (this.canAnyUser(ChannelAction.WRITE_POSTS)) { | ||
return true; | ||
@@ -36,6 +35,6 @@ } | ||
} | ||
return (this.canAnyAuthenticatedUserWrite() || | ||
this.isUserAWriteUser(user) || | ||
this.isUserPartOfWriteGroup(user) || | ||
this.isUserPartOfWriteOrg(user)); | ||
return (this.canAnyAuthenticatedUser(ChannelAction.WRITE_POSTS) || | ||
this.canSomeUser(ChannelAction.WRITE_POSTS, user) || | ||
this.canSomeUserGroup(ChannelAction.WRITE_POSTS, user) || | ||
this.canSomeUserOrg(ChannelAction.WRITE_POSTS, user)); | ||
} | ||
@@ -57,6 +56,62 @@ canCreateChannel(user) { | ||
return (user.username === this.channelCreator || | ||
this.isUserAModeratorUser(user) || | ||
this.isUserPartOfModeratorGroup(user) || | ||
this.isUserPartOfModeratorOrg(user)); | ||
this.canSomeUser(ChannelAction.MODERATE_CHANNEL, user) || | ||
this.canSomeUserGroup(ChannelAction.MODERATE_CHANNEL, user) || | ||
this.canSomeUserOrg(ChannelAction.MODERATE_CHANNEL, user)); | ||
} | ||
canReadChannel(user) { | ||
if (this.canAnyUser(ChannelAction.READ_POSTS)) { | ||
return true; | ||
} | ||
if (this.isUserUnAuthenticated(user)) { | ||
return false; | ||
} | ||
return (this.canAnyAuthenticatedUser(ChannelAction.READ_POSTS) || | ||
this.canSomeUser(ChannelAction.READ_POSTS, user) || | ||
this.canSomeUserGroup(ChannelAction.READ_POSTS, user) || | ||
this.canSomeUserOrg(ChannelAction.READ_POSTS, user)); | ||
} | ||
canAnyUser(action) { | ||
var _a; | ||
const anonymousUserRole = (_a = this.permissionsByCategory[types_1.AclCategory.ANONYMOUS_USER]) === null || _a === void 0 ? void 0 : _a[0].role; | ||
return channelActionLookup(action).includes(anonymousUserRole); | ||
} | ||
canAnyAuthenticatedUser(action) { | ||
var _a; | ||
const role = (_a = this.permissionsByCategory[types_1.AclCategory.AUTHENTICATED_USER]) === null || _a === void 0 ? void 0 : _a[0].role; | ||
return channelActionLookup(action).includes(role); | ||
} | ||
canSomeUser(action, user) { | ||
var _a; | ||
const userPermissions = (_a = this.permissionsByCategory[types_1.AclCategory.USER]) !== null && _a !== void 0 ? _a : []; | ||
const username = user.username; | ||
return userPermissions.some((permission) => { | ||
const { role, key } = permission; | ||
return key === username && channelActionLookup(action).includes(role); | ||
}); | ||
} | ||
canSomeUserGroup(action, user) { | ||
var _a; | ||
const groupAccessControls = (_a = this.permissionsByCategory[types_1.AclCategory.GROUP]) !== null && _a !== void 0 ? _a : []; | ||
const userGroupsById = this.mapUserGroupsById(user.groups); | ||
return groupAccessControls.some((permission) => { | ||
const group = userGroupsById[permission.key]; | ||
if (!group || !isGroupDiscussable(group)) { | ||
return false; | ||
} | ||
return (doesPermissionAllowGroupMemberType(permission, group) && | ||
channelActionLookup(action).includes(permission.role)); | ||
}); | ||
} | ||
canSomeUserOrg(action, user) { | ||
var _a; | ||
const orgPermissions = (_a = this.permissionsByCategory[types_1.AclCategory.ORG]) !== null && _a !== void 0 ? _a : []; | ||
return orgPermissions.some((permission) => { | ||
const { key } = permission; | ||
if (permission.key !== user.orgId) { | ||
return false; | ||
} | ||
return (doesPermissionAllowOrgRole(permission, user.role) && | ||
channelActionLookup(action).includes(permission.role)); | ||
}); | ||
} | ||
/** | ||
@@ -87,3 +142,3 @@ * canCreateChannelHelpers | ||
this.isMemberTypeAuthorized(userGroup) && | ||
this.isGroupDiscussable(userGroup)); | ||
isGroupDiscussable(userGroup)); | ||
}); | ||
@@ -111,62 +166,2 @@ } | ||
} | ||
canAnyUserWrite() { | ||
var _a; | ||
const role = (_a = this.permissionsByCategory[types_1.AclCategory.ANONYMOUS_USER]) === null || _a === void 0 ? void 0 : _a[0].role; | ||
return this.isAuthorizedToWritePost(role); | ||
} | ||
canAnyAuthenticatedUserWrite() { | ||
var _a; | ||
const role = (_a = this.permissionsByCategory[types_1.AclCategory.AUTHENTICATED_USER]) === null || _a === void 0 ? void 0 : _a[0].role; | ||
return this.isAuthorizedToWritePost(role); | ||
} | ||
isUserAWriteUser(user) { | ||
var _a; | ||
const userPermissions = (_a = this.permissionsByCategory[types_1.AclCategory.USER]) !== null && _a !== void 0 ? _a : []; | ||
const username = user.username; | ||
return userPermissions.some((permission) => { | ||
const { role, key } = permission; | ||
return key === username && this.isAuthorizedToWritePost(role); | ||
}); | ||
} | ||
isUserPartOfWriteGroup(user) { | ||
var _a; | ||
const groupPermissions = (_a = this.permissionsByCategory[types_1.AclCategory.GROUP]) !== null && _a !== void 0 ? _a : []; | ||
const userGroupsById = this.mapUserGroupsById(user.groups); | ||
return groupPermissions.some((permission) => { | ||
const userGroup = userGroupsById[permission.key]; | ||
return (userGroup && | ||
this.isMemberTypeAuthorized(userGroup) && | ||
this.isGroupDiscussable(userGroup) && | ||
(this.canAnyGroupMemberPost(permission) || | ||
(this.isMemberTypeAdmin(userGroup) && this.canAdminsPost(permission)))); | ||
}); | ||
} | ||
canAnyGroupMemberPost(permission) { | ||
const { subCategory, role } = permission; | ||
return (subCategory === types_1.AclSubCategory.MEMBER && | ||
this.isAuthorizedToWritePost(role)); | ||
} | ||
canAdminsPost(permission) { | ||
const { subCategory, role } = permission; | ||
return (subCategory === types_1.AclSubCategory.ADMIN && this.isAuthorizedToWritePost(role)); | ||
} | ||
isUserPartOfWriteOrg(user) { | ||
var _a; | ||
const orgPermissions = (_a = this.permissionsByCategory[types_1.AclCategory.ORG]) !== null && _a !== void 0 ? _a : []; | ||
const { orgId: userOrgId } = user; | ||
return orgPermissions.some((permission) => { | ||
const { key } = permission; | ||
return (key === userOrgId && | ||
(this.canAnyOrgMemberPost(permission) || | ||
(platform_1.isOrgAdmin(user) && this.canAdminsPost(permission)))); | ||
}); | ||
} | ||
canAnyOrgMemberPost(permission) { | ||
const { subCategory, role } = permission; | ||
return (subCategory === types_1.AclSubCategory.MEMBER && | ||
this.isAuthorizedToWritePost(role)); | ||
} | ||
isAuthorizedToWritePost(role) { | ||
return this.ALLOWED_ROLES_FOR_POSTING.includes(role); | ||
} | ||
isUserUnAuthenticated(user) { | ||
@@ -185,60 +180,34 @@ return user.username === null || user.username === undefined; | ||
} | ||
isMemberTypeAdmin(userGroup) { | ||
const { userMembership: { memberType }, } = userGroup; | ||
return this.ADMIN_GROUP_MEMBER_TYPES.includes(memberType); | ||
} | ||
exports.ChannelPermission = ChannelPermission; | ||
function isGroupDiscussable(userGroup) { | ||
const { typeKeywords = [] } = userGroup; | ||
return !typeKeywords.includes(constants_1.CANNOT_DISCUSS); | ||
} | ||
function doesPermissionAllowGroupMemberType(permission, group) { | ||
if (permission.category !== types_1.AclCategory.GROUP || | ||
group.userMembership.memberType === "none") { | ||
return false; | ||
} | ||
isGroupDiscussable(userGroup) { | ||
const { typeKeywords = [] } = userGroup; | ||
return !typeKeywords.includes(constants_1.CANNOT_DISCUSS); | ||
return ( | ||
// group owners and admins can do anything permissioned with SubCategory "member" | ||
group.userMembership.memberType === "owner" || | ||
group.userMembership.memberType === "admin" || | ||
permission.subCategory === types_1.AclSubCategory.MEMBER); | ||
} | ||
function doesPermissionAllowOrgRole(permission, orgRole) { | ||
return (permission.category === types_1.AclCategory.ORG && | ||
(permission.subCategory === types_1.AclSubCategory.MEMBER || | ||
(permission.subCategory === "admin" && orgRole === "org_admin"))); | ||
} | ||
function channelActionLookup(action) { | ||
if (action === ChannelAction.WRITE_POSTS) { | ||
return [types_1.Role.WRITE, types_1.Role.READWRITE, types_1.Role.MODERATE, types_1.Role.MANAGE, types_1.Role.OWNER]; | ||
} | ||
isAuthorizedToModerate(role) { | ||
return this.ALLOWED_ROLES_FOR_MODERATION.includes(role); | ||
if (action === ChannelAction.MODERATE_CHANNEL) { | ||
return [types_1.Role.MODERATE, types_1.Role.MANAGE, types_1.Role.OWNER]; | ||
} | ||
isUserAModeratorUser(user) { | ||
var _a; | ||
const userPermissions = (_a = this.permissionsByCategory[types_1.AclCategory.USER]) !== null && _a !== void 0 ? _a : []; | ||
const username = user.username; | ||
return userPermissions.some((permission) => { | ||
const { role, key } = permission; | ||
return key === username && this.isAuthorizedToModerate(role); | ||
}); | ||
} | ||
isUserPartOfModeratorGroup(user) { | ||
var _a; | ||
const groupPermissions = (_a = this.permissionsByCategory[types_1.AclCategory.GROUP]) !== null && _a !== void 0 ? _a : []; | ||
const userGroupsById = this.mapUserGroupsById(user.groups); | ||
return groupPermissions.some((permission) => { | ||
const userGroup = userGroupsById[permission.key]; | ||
return (userGroup && | ||
this.isMemberTypeAuthorized(userGroup) && | ||
(this.canAnyGroupMemberModerate(permission) || | ||
(this.isMemberTypeAdmin(userGroup) && | ||
this.canAdminsModerate(permission)))); | ||
}); | ||
} | ||
canAnyGroupMemberModerate(permission) { | ||
const { subCategory, role } = permission; | ||
return (subCategory === types_1.AclSubCategory.MEMBER && this.isAuthorizedToModerate(role)); | ||
} | ||
canAdminsModerate(permission) { | ||
const { subCategory, role } = permission; | ||
return (subCategory === types_1.AclSubCategory.ADMIN && this.isAuthorizedToModerate(role)); | ||
} | ||
isUserPartOfModeratorOrg(user) { | ||
var _a; | ||
const orgPermissions = (_a = this.permissionsByCategory[types_1.AclCategory.ORG]) !== null && _a !== void 0 ? _a : []; | ||
const { orgId: userOrgId } = user; | ||
return orgPermissions.some((permission) => { | ||
const { key } = permission; | ||
return (key === userOrgId && | ||
(this.canAnyOrgMemberModerate(permission) || | ||
(platform_1.isOrgAdmin(user) && this.canAdminsModerate(permission)))); | ||
}); | ||
} | ||
canAnyOrgMemberModerate(permission) { | ||
const { subCategory, role } = permission; | ||
return (subCategory === types_1.AclSubCategory.MEMBER && this.isAuthorizedToModerate(role)); | ||
} | ||
// default to read action | ||
return [types_1.Role.READ, types_1.Role.READWRITE, types_1.Role.MODERATE, types_1.Role.MANAGE, types_1.Role.OWNER]; | ||
} | ||
exports.ChannelPermission = ChannelPermission; | ||
//# sourceMappingURL=channel-permission.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.canReadFromChannel = void 0; | ||
const platform_1 = require("../platform"); | ||
var can_post_to_channel_1 = require("./can-post-to-channel"); | ||
@@ -11,36 +9,5 @@ Object.defineProperty(exports, "canPostToChannel", { enumerable: true, get: function () { return can_post_to_channel_1.canPostToChannel; } }); | ||
Object.defineProperty(exports, "canModifyChannel", { enumerable: true, get: function () { return can_modify_channel_1.canModifyChannel; } }); | ||
function intersectGroups(membershipTypes) { | ||
return (user, channel) => { | ||
const { groups: sharedGroups = [] } = channel; | ||
const { groups: userGroups = [] } = user; | ||
const eligibleUserGroups = userGroups.reduce(platform_1.reduceByGroupMembership(membershipTypes), []); | ||
const method = "some"; | ||
return sharedGroups[method]((group) => eligibleUserGroups.indexOf(group) > -1); | ||
}; | ||
} | ||
function isChannelOrgMember(channel, user) { | ||
// orgs.length = 1 until collaboration/discussion between many orgs is ideated | ||
return channel.orgs.length === 1 && channel.orgs.indexOf(user.orgId) > -1; | ||
} | ||
/** | ||
* Utility to determine whether User can view posts belonging to Channel | ||
* | ||
* @export | ||
* @param {IChannel} channel | ||
* @param {IUser} user | ||
* @return {*} {boolean} | ||
*/ | ||
function canReadFromChannel(channel, user = {}) { | ||
if (channel.access === "private") { | ||
// ensure user is member of at least one group | ||
return intersectGroups(["member", "owner", "admin"])(user, channel); | ||
} | ||
if (channel.access === "org") { | ||
return (intersectGroups(["member", "owner", "admin"])(user, channel) || | ||
isChannelOrgMember(channel, user)); | ||
} | ||
// public channel | ||
return true; | ||
} | ||
exports.canReadFromChannel = canReadFromChannel; | ||
var can_read_channel_1 = require("./can-read-channel"); | ||
Object.defineProperty(exports, "canReadChannel", { enumerable: true, get: function () { return can_read_channel_1.canReadChannel; } }); | ||
Object.defineProperty(exports, "canReadFromChannel", { enumerable: true, get: function () { return can_read_channel_1.canReadFromChannel; } }); | ||
//# sourceMappingURL=index.js.map |
import { IChannelAclPermission, IDiscussionsUser } from "../types"; | ||
export declare class ChannelPermission { | ||
private readonly ALLOWED_GROUP_MEMBER_TYPES; | ||
private readonly ADMIN_GROUP_MEMBER_TYPES; | ||
private readonly ALLOWED_ROLES_FOR_POSTING; | ||
private readonly ALLOWED_ROLES_FOR_MODERATION; | ||
private isChannelAclEmpty; | ||
@@ -14,2 +11,8 @@ private permissionsByCategory; | ||
canModerateChannel(user: IDiscussionsUser): boolean; | ||
canReadChannel(user: IDiscussionsUser): boolean; | ||
private canAnyUser; | ||
private canAnyAuthenticatedUser; | ||
private canSomeUser; | ||
private canSomeUserGroup; | ||
private canSomeUserOrg; | ||
/** | ||
@@ -24,23 +27,5 @@ * canCreateChannelHelpers | ||
private userCanAddUsersToAcl; | ||
private canAnyUserWrite; | ||
private canAnyAuthenticatedUserWrite; | ||
private isUserAWriteUser; | ||
private isUserPartOfWriteGroup; | ||
private canAnyGroupMemberPost; | ||
private canAdminsPost; | ||
private isUserPartOfWriteOrg; | ||
private canAnyOrgMemberPost; | ||
private isAuthorizedToWritePost; | ||
private isUserUnAuthenticated; | ||
private mapUserGroupsById; | ||
private isMemberTypeAuthorized; | ||
private isMemberTypeAdmin; | ||
private isGroupDiscussable; | ||
private isAuthorizedToModerate; | ||
private isUserAModeratorUser; | ||
private isUserPartOfModeratorGroup; | ||
private canAnyGroupMemberModerate; | ||
private canAdminsModerate; | ||
private isUserPartOfModeratorOrg; | ||
private canAnyOrgMemberModerate; | ||
} |
@@ -1,14 +0,4 @@ | ||
import { IUser } from "@esri/arcgis-rest-auth"; | ||
import { IChannel, IDiscussionsUser } from "../../types"; | ||
export { canPostToChannel } from "./can-post-to-channel"; | ||
export { canCreateChannel } from "./can-create-channel"; | ||
export { canModifyChannel } from "./can-modify-channel"; | ||
/** | ||
* Utility to determine whether User can view posts belonging to Channel | ||
* | ||
* @export | ||
* @param {IChannel} channel | ||
* @param {IUser} user | ||
* @return {*} {boolean} | ||
*/ | ||
export declare function canReadFromChannel(channel: IChannel, user?: IUser | IDiscussionsUser): boolean; | ||
export { canReadChannel, canReadFromChannel } from "./can-read-channel"; |
{ | ||
"name": "@esri/hub-discussions", | ||
"version": "25.5.0", | ||
"version": "25.6.0", | ||
"description": "Module to interact with ArcGIS Hub Discussions API in Node.js and modern browsers.", | ||
@@ -5,0 +5,0 @@ "main": "dist/node/index.js", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
127
203101
4044