Socket
Socket
Sign inDemoInstall

@esri/hub-discussions

Package Overview
Dependencies
Maintainers
42
Versions
284
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@esri/hub-discussions - npm Package Compare versions

Comparing version 23.0.0-next.1 to 23.0.0

dist/esm/utils/posts/can-modify-post-status.js

101

dist/esm/utils/channel-permission.js

@@ -7,3 +7,9 @@ import { AclCategory, AclSubCategory, Role, } from "../types";

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;

@@ -30,2 +36,5 @@ this.permissionsByCategory = {};

}
canModifyPostStatus(user, channelCreator) {
return this.canModifyChannel(user, channelCreator);
}
canCreateChannel(user) {

@@ -41,5 +50,19 @@ if (this.isUserUnAuthenticated(user) || this.isChannelAclEmpty) {

}
canModifyChannel(user, channelCreator) {
if (this.isUserUnAuthenticated(user)) {
return false;
}
if (user.username === channelCreator) {
return true;
}
return (this.aclAllowsThisUserToModifyChannel(user) ||
this.aclAllowsThisUserToModifyChannelByGroups(user) ||
this.aclAllowsThisUserToModifyChannelByOrg(user));
}
isAuthorizedToPost(role) {
return this.ALLOWED_ROLES_FOR_POSTING.includes(role);
}
isAuthorizedToModerate(role) {
return this.ALLOWED_ROLES_FOR_MODERATION.includes(role);
}
isUserUnAuthenticated(user) {

@@ -58,2 +81,6 @@ return user.username === null || user.username === undefined;

}
isMemberTypeAdmin(userGroup) {
const { userMembership: { memberType }, } = userGroup;
return this.ADMIN_GROUP_MEMBER_TYPES.includes(memberType);
}
isGroupDiscussable(userGroup) {

@@ -63,9 +90,14 @@ const { typeKeywords = [] } = userGroup;

}
/**
* canPostToChannel helpers
*/
aclAllowsAnyUserToPost() {
var _a;
return this.isAuthorizedToPost((_a = this.permissionsByCategory[AclCategory.ANONYMOUS_USER]) === null || _a === void 0 ? void 0 : _a[0].role);
const role = (_a = this.permissionsByCategory[AclCategory.ANONYMOUS_USER]) === null || _a === void 0 ? void 0 : _a[0].role;
return this.isAuthorizedToPost(role);
}
aclAllowsAnyAuthenticatedUserToPost() {
var _a;
return this.isAuthorizedToPost((_a = this.permissionsByCategory[AclCategory.AUTHENTICATED_USER]) === null || _a === void 0 ? void 0 : _a[0].role);
const role = (_a = this.permissionsByCategory[AclCategory.AUTHENTICATED_USER]) === null || _a === void 0 ? void 0 : _a[0].role;
return this.isAuthorizedToPost(role);
}

@@ -91,3 +123,3 @@ aclAllowsThisUserToPost(user) {

(this.canAnyGroupMemberPost(permission) ||
this.isGroupAdminAndCanAdminsPost(userGroup, permission)));
(this.isMemberTypeAdmin(userGroup) && this.canAdminsPost(permission))));
});

@@ -99,9 +131,5 @@ }

}
isGroupAdminAndCanAdminsPost(userGroup, permission) {
canAdminsPost(permission) {
const { subCategory, role } = permission;
const { userMembership: { memberType }, } = userGroup;
const isGroupAdmin = memberType === "admin" || memberType === "owner";
return (isGroupAdmin &&
subCategory === AclSubCategory.ADMIN &&
this.isAuthorizedToPost(role));
return (subCategory === AclSubCategory.ADMIN && this.isAuthorizedToPost(role));
}

@@ -116,3 +144,3 @@ aclAllowsThisUserToPostByOrg(user) {

(this.canAnyOrgMemberPost(permission) ||
this.isOrgAdminAndAdminsCanPost(permission, user)));
(isOrgAdmin(user) && this.canAdminsPost(permission))));
});

@@ -124,8 +152,53 @@ }

}
isOrgAdminAndAdminsCanPost(permission, user) {
/**
* canModifyChannel helpers
*/
aclAllowsThisUserToModifyChannel(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);
});
}
aclAllowsThisUserToModifyChannelByGroups(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 (isOrgAdmin(user) &&
subCategory === AclSubCategory.ADMIN &&
this.isAuthorizedToPost(role));
return (subCategory === AclSubCategory.MEMBER && this.isAuthorizedToModerate(role));
}
canAdminsModerate(permission) {
const { subCategory, role } = permission;
return (subCategory === AclSubCategory.ADMIN && this.isAuthorizedToModerate(role));
}
aclAllowsThisUserToModifyChannelByOrg(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));
}
/**
* canCreateChannelHelpers
*/
userCanAddAnonymousToAcl(user) {

@@ -132,0 +205,0 @@ if (!this.permissionsByCategory[AclCategory.ANONYMOUS_USER]) {

13

dist/esm/utils/posts/index.js
import { parseDatasetId } from "@esri/hub-common";
import { canModifyChannel } from "../channels";
import { CANNOT_DISCUSS, MENTION_ATTRIBUTE } from "../constants";
export { canModifyPost } from "../posts/can-modify-post";
export { canModifyPost } from "./can-modify-post";
export { canModifyPostStatus } from "./can-modify-post-status";
/**

@@ -53,12 +54,2 @@ * Utility that parses a discussion URI string into its component parts

/**
* Determines if the given user has sufficient privileges to modify a post's status
* @param post An IPost object
* @param channel An IChannel object
* @param user An IUser object
* @returns true if the user can modify the post
*/
export function canModifyPostStatus(channel, user) {
return canModifyChannel(channel, user);
}
/**
* Determines if the given user has sufficient privileges to delete the given post

@@ -65,0 +56,0 @@ * @param post An IPost object

@@ -10,3 +10,9 @@ "use strict";

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;

@@ -33,2 +39,5 @@ this.permissionsByCategory = {};

}
canModifyPostStatus(user, channelCreator) {
return this.canModifyChannel(user, channelCreator);
}
canCreateChannel(user) {

@@ -44,5 +53,19 @@ if (this.isUserUnAuthenticated(user) || this.isChannelAclEmpty) {

}
canModifyChannel(user, channelCreator) {
if (this.isUserUnAuthenticated(user)) {
return false;
}
if (user.username === channelCreator) {
return true;
}
return (this.aclAllowsThisUserToModifyChannel(user) ||
this.aclAllowsThisUserToModifyChannelByGroups(user) ||
this.aclAllowsThisUserToModifyChannelByOrg(user));
}
isAuthorizedToPost(role) {
return this.ALLOWED_ROLES_FOR_POSTING.includes(role);
}
isAuthorizedToModerate(role) {
return this.ALLOWED_ROLES_FOR_MODERATION.includes(role);
}
isUserUnAuthenticated(user) {

@@ -61,2 +84,6 @@ return user.username === null || user.username === undefined;

}
isMemberTypeAdmin(userGroup) {
const { userMembership: { memberType }, } = userGroup;
return this.ADMIN_GROUP_MEMBER_TYPES.includes(memberType);
}
isGroupDiscussable(userGroup) {

@@ -66,9 +93,14 @@ const { typeKeywords = [] } = userGroup;

}
/**
* canPostToChannel helpers
*/
aclAllowsAnyUserToPost() {
var _a;
return this.isAuthorizedToPost((_a = this.permissionsByCategory[types_1.AclCategory.ANONYMOUS_USER]) === null || _a === void 0 ? void 0 : _a[0].role);
const role = (_a = this.permissionsByCategory[types_1.AclCategory.ANONYMOUS_USER]) === null || _a === void 0 ? void 0 : _a[0].role;
return this.isAuthorizedToPost(role);
}
aclAllowsAnyAuthenticatedUserToPost() {
var _a;
return this.isAuthorizedToPost((_a = this.permissionsByCategory[types_1.AclCategory.AUTHENTICATED_USER]) === null || _a === void 0 ? void 0 : _a[0].role);
const role = (_a = this.permissionsByCategory[types_1.AclCategory.AUTHENTICATED_USER]) === null || _a === void 0 ? void 0 : _a[0].role;
return this.isAuthorizedToPost(role);
}

@@ -94,3 +126,3 @@ aclAllowsThisUserToPost(user) {

(this.canAnyGroupMemberPost(permission) ||
this.isGroupAdminAndCanAdminsPost(userGroup, permission)));
(this.isMemberTypeAdmin(userGroup) && this.canAdminsPost(permission))));
});

@@ -102,9 +134,5 @@ }

}
isGroupAdminAndCanAdminsPost(userGroup, permission) {
canAdminsPost(permission) {
const { subCategory, role } = permission;
const { userMembership: { memberType }, } = userGroup;
const isGroupAdmin = memberType === "admin" || memberType === "owner";
return (isGroupAdmin &&
subCategory === types_1.AclSubCategory.ADMIN &&
this.isAuthorizedToPost(role));
return (subCategory === types_1.AclSubCategory.ADMIN && this.isAuthorizedToPost(role));
}

@@ -119,3 +147,3 @@ aclAllowsThisUserToPostByOrg(user) {

(this.canAnyOrgMemberPost(permission) ||
this.isOrgAdminAndAdminsCanPost(permission, user)));
(platform_1.isOrgAdmin(user) && this.canAdminsPost(permission))));
});

@@ -127,8 +155,53 @@ }

}
isOrgAdminAndAdminsCanPost(permission, user) {
/**
* canModifyChannel helpers
*/
aclAllowsThisUserToModifyChannel(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);
});
}
aclAllowsThisUserToModifyChannelByGroups(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 (platform_1.isOrgAdmin(user) &&
subCategory === types_1.AclSubCategory.ADMIN &&
this.isAuthorizedToPost(role));
return (subCategory === types_1.AclSubCategory.MEMBER && this.isAuthorizedToModerate(role));
}
canAdminsModerate(permission) {
const { subCategory, role } = permission;
return (subCategory === types_1.AclSubCategory.ADMIN && this.isAuthorizedToModerate(role));
}
aclAllowsThisUserToModifyChannelByOrg(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));
}
/**
* canCreateChannelHelpers
*/
userCanAddAnonymousToAcl(user) {

@@ -135,0 +208,0 @@ if (!this.permissionsByCategory[types_1.AclCategory.ANONYMOUS_USER]) {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseMentionedUsers = exports.canDeletePost = exports.canModifyPostStatus = exports.isDiscussable = exports.parseDiscussionURI = void 0;
exports.parseMentionedUsers = exports.canDeletePost = exports.isDiscussable = exports.parseDiscussionURI = void 0;
const hub_common_1 = require("@esri/hub-common");
const channels_1 = require("../channels");
const constants_1 = require("../constants");
var can_modify_post_1 = require("../posts/can-modify-post");
var can_modify_post_1 = require("./can-modify-post");
Object.defineProperty(exports, "canModifyPost", { enumerable: true, get: function () { return can_modify_post_1.canModifyPost; } });
var can_modify_post_status_1 = require("./can-modify-post-status");
Object.defineProperty(exports, "canModifyPostStatus", { enumerable: true, get: function () { return can_modify_post_status_1.canModifyPostStatus; } });
/**

@@ -59,13 +61,2 @@ * Utility that parses a discussion URI string into its component parts

/**
* Determines if the given user has sufficient privileges to modify a post's status
* @param post An IPost object
* @param channel An IChannel object
* @param user An IUser object
* @returns true if the user can modify the post
*/
function canModifyPostStatus(channel, user) {
return channels_1.canModifyChannel(channel, user);
}
exports.canModifyPostStatus = canModifyPostStatus;
/**
* Determines if the given user has sufficient privileges to delete the given post

@@ -72,0 +63,0 @@ * @param post An IPost object

@@ -401,3 +401,3 @@ import { IPagingParams, IPagedResponse as IRestPagedResponse, IUser } from "@esri/arcgis-rest-types";

*/
export interface IPost extends IWithAuthor, IWithEditor, IWithTimestamps {
export interface IPost extends Partial<IWithAuthor>, Partial<IWithEditor>, IWithTimestamps {
id: string;

@@ -433,2 +433,3 @@ title: string | null;

appInfo?: string;
asAnonymous?: boolean;
}

@@ -435,0 +436,0 @@ /**

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;

@@ -9,8 +11,15 @@ private permissionsByCategory;

canPostToChannel(user: IDiscussionsUser): boolean;
canModifyPostStatus(user: IDiscussionsUser, channelCreator: string): boolean;
canCreateChannel(user: IDiscussionsUser): boolean;
canModifyChannel(user: IDiscussionsUser, channelCreator: string): boolean;
private isAuthorizedToPost;
private isAuthorizedToModerate;
private isUserUnAuthenticated;
private mapUserGroupsById;
private isMemberTypeAuthorized;
private isMemberTypeAdmin;
private isGroupDiscussable;
/**
* canPostToChannel helpers
*/
private aclAllowsAnyUserToPost;

@@ -21,6 +30,17 @@ private aclAllowsAnyAuthenticatedUserToPost;

private canAnyGroupMemberPost;
private isGroupAdminAndCanAdminsPost;
private canAdminsPost;
private aclAllowsThisUserToPostByOrg;
private canAnyOrgMemberPost;
private isOrgAdminAndAdminsCanPost;
/**
* canModifyChannel helpers
*/
private aclAllowsThisUserToModifyChannel;
private aclAllowsThisUserToModifyChannelByGroups;
private canAnyGroupMemberModerate;
private canAdminsModerate;
private aclAllowsThisUserToModifyChannelByOrg;
private canAnyOrgMemberModerate;
/**
* canCreateChannelHelpers
*/
private userCanAddAnonymousToAcl;

@@ -27,0 +47,0 @@ private userCanAddUnauthenticatedToAcl;

@@ -5,3 +5,4 @@ import { IGroup, IItem } from "@esri/arcgis-rest-portal";

import { IUser } from "@esri/arcgis-rest-auth";
export { canModifyPost } from "../posts/can-modify-post";
export { canModifyPost } from "./can-modify-post";
export { canModifyPostStatus } from "./can-modify-post-status";
/**

@@ -24,10 +25,2 @@ * Utility that parses a discussion URI string into its component parts

/**
* Determines if the given user has sufficient privileges to modify a post's status
* @param post An IPost object
* @param channel An IChannel object
* @param user An IUser object
* @returns true if the user can modify the post
*/
export declare function canModifyPostStatus(channel: IChannel, user: IUser): boolean;
/**
* Determines if the given user has sufficient privileges to delete the given post

@@ -34,0 +27,0 @@ * @param post An IPost object

{
"name": "@esri/hub-discussions",
"version": "23.0.0-next.1",
"version": "23.0.0",
"description": "Module to interact with ArcGIS Hub Discussions API in Node.js and modern browsers.",

@@ -16,6 +16,6 @@ "main": "dist/node/index.js",

"@esri/arcgis-rest-request": "^2.14.0 || 3",
"@esri/hub-common": "^13.0.0-next.1"
"@esri/hub-common": "^12.4.0"
},
"devDependencies": {
"@esri/hub-common": "^13.0.0-next.1",
"@esri/hub-common": "*",
"@types/geojson": "^7946.0.7",

@@ -22,0 +22,0 @@ "typescript": "^3.8.1"

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

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc