Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added src/dummy.js
Empty file.
224 changes: 121 additions & 103 deletions src/groups/create.js
Original file line number Diff line number Diff line change
@@ -1,104 +1,122 @@
'use strict';

const meta = require('../meta');
const plugins = require('../plugins');
const slugify = require('../slugify');
const db = require('../database');

module.exports = function (Groups) {
Groups.create = async function (data) {
const isSystem = isSystemGroup(data);
const timestamp = data.timestamp || Date.now();
let disableJoinRequests = parseInt(data.disableJoinRequests, 10) === 1 ? 1 : 0;
if (data.name === 'administrators') {
disableJoinRequests = 1;
}
const disableLeave = parseInt(data.disableLeave, 10) === 1 ? 1 : 0;
const isHidden = parseInt(data.hidden, 10) === 1;

Groups.validateGroupName(data.name);

const [exists, privGroupExists] = await Promise.all([
meta.userOrGroupExists(data.name),
privilegeGroupExists(data.name),
]);
if (exists || privGroupExists) {
throw new Error('[[error:group-already-exists]]');
}

const memberCount = data.hasOwnProperty('ownerUid') ? 1 : 0;
const isPrivate = data.hasOwnProperty('private') && data.private !== undefined ? parseInt(data.private, 10) === 1 : true;
let groupData = {
name: data.name,
slug: slugify(data.name),
createtime: timestamp,
userTitle: data.userTitle || data.name,
userTitleEnabled: parseInt(data.userTitleEnabled, 10) === 1 ? 1 : 0,
description: data.description || '',
memberCount: memberCount,
hidden: isHidden ? 1 : 0,
system: isSystem ? 1 : 0,
private: isPrivate ? 1 : 0,
disableJoinRequests: disableJoinRequests,
disableLeave: disableLeave,
};

await plugins.hooks.fire('filter:group.create', { group: groupData, data: data });

await db.sortedSetAdd('groups:createtime', groupData.createtime, groupData.name);
await db.setObject(`group:${groupData.name}`, groupData);

if (data.hasOwnProperty('ownerUid')) {
await db.setAdd(`group:${groupData.name}:owners`, data.ownerUid);
await db.sortedSetAdd(`group:${groupData.name}:members`, timestamp, data.ownerUid);
}

if (!isHidden && !isSystem) {
await db.sortedSetAddBulk([
['groups:visible:createtime', timestamp, groupData.name],
['groups:visible:memberCount', groupData.memberCount, groupData.name],
['groups:visible:name', 0, `${groupData.name.toLowerCase()}:${groupData.name}`],
]);
}

if (!Groups.isPrivilegeGroup(groupData.name)) {
await db.setObjectField('groupslug:groupname', groupData.slug, groupData.name);
}

groupData = await Groups.getGroupData(groupData.name);
plugins.hooks.fire('action:group.create', { group: groupData });
return groupData;
};

function isSystemGroup(data) {
return data.system === true || parseInt(data.system, 10) === 1 ||
Groups.systemGroups.includes(data.name) ||
Groups.isPrivilegeGroup(data.name);
}

async function privilegeGroupExists(name) {
return Groups.isPrivilegeGroup(name) && await db.isSortedSetMember('groups:createtime', name);
}

Groups.validateGroupName = function (name) {
if (!name) {
throw new Error('[[error:group-name-too-short]]');
}

if (typeof name !== 'string') {
throw new Error('[[error:invalid-group-name]]');
}

if (!Groups.isPrivilegeGroup(name) && name.length > meta.config.maximumGroupNameLength) {
throw new Error('[[error:group-name-too-long]]');
}

if (name === 'guests' || (!Groups.isPrivilegeGroup(name) && name.includes(':'))) {
throw new Error('[[error:invalid-group-name]]');
}

if (name.includes('/') || !slugify(name)) {
throw new Error('[[error:invalid-group-name]]');
}
};
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
const meta_1 = __importDefault(require("../meta"));
const plugins = __importStar(require("../plugins"));
const slugify_1 = __importDefault(require("../slugify"));
const db = __importStar(require("../database"));
function createGroup(Groups) {
function isSystemGroup(data) {
return data.system === true || parseInt(data.system, 10) === 1 ||
Groups.systemGroups.includes(data.name) ||
Groups.isPrivilegeGroup(data.name);
}
async function privilegeGroupExists(name) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
return Groups.isPrivilegeGroup(name) && await db.isSortedSetMember('groups:createtime', name);
}
Groups.create = async function (data) {
const isSystem = isSystemGroup(data);
const timestamp = data.timestamp || Date.now();
let disableJoinRequests = parseInt(data.disableJoinRequests, 10) === 1 ? 1 : 0;
if (data.name === 'administrators') {
disableJoinRequests = 1;
}
const disableLeave = parseInt(data.disableLeave, 10) === 1 ? 1 : 0;
const isHidden = parseInt(data.hidden, 10) === 1;
Groups.validateGroupName(data.name);
const [exists, privGroupExists] = await Promise.all([
meta_1.default.userOrGroupExists(data.name),
privilegeGroupExists(data.name),
]);
if (exists || privGroupExists) {
throw new Error('[[error:group-already-exists]]');
}
const memberCount = data.hasOwnProperty('ownerUid') ? 1 : 0;
const isPrivate = data.hasOwnProperty('private') && data.private !== undefined ? parseInt(data.private, 10) === 1 : true;
let groupData = {
name: data.name,
slug: (0, slugify_1.default)(data.name),
createtime: timestamp,
userTitle: data.userTitle || data.name,
userTitleEnabled: parseInt(data.userTitleEnabled, 10) === 1 ? 1 : 0,
description: data.description || '',
memberCount: memberCount,
hidden: isHidden ? 1 : 0,
system: isSystem ? 1 : 0,
private: isPrivate ? 1 : 0,
disableJoinRequests: disableJoinRequests,
disableLeave: disableLeave,
};
await plugins.hooks.fire('filter:group.create', { group: groupData, data: data });
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
await db.sortedSetAdd('groups:createtime', groupData.createtime, groupData.name);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
await db.setObject(`group:${groupData.name}`, groupData);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (data.hasOwnProperty('ownerUid')) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
await db.setAdd(`group:${groupData.name}:owners`, data.ownerUid);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
await db.sortedSetAdd(`group:${groupData.name}:members`, timestamp, data.ownerUid);
}
if (!isHidden && !isSystem) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
await db.sortedSetAddBulk([
['groups:visible:createtime', timestamp, groupData.name],
['groups:visible:memberCount', groupData.memberCount, groupData.name],
['groups:visible:name', 0, `${groupData.name.toLowerCase()}:${groupData.name}`],
]);
}
if (!Groups.isPrivilegeGroup(groupData.name)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
await db.setObjectField('groupslug:groupname', groupData.slug, groupData.name);
}
groupData = await Groups.getGroupData(groupData.name);
await plugins.hooks.fire('action:group.create', { group: groupData });
return groupData;
};
Groups.validateGroupName = function (name) {
if (!name) {
throw new Error('[[error:group-name-too-short]]');
}
if (typeof name !== 'string') {
throw new Error('[[error:invalid-group-name]]');
}
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (!Groups.isPrivilegeGroup(name) && name.length > meta_1.default.config.maximumGroupNameLength) {
throw new Error('[[error:group-name-too-long]]');
}
if (name === 'guests' || (!Groups.isPrivilegeGroup(name) && name.includes(':'))) {
throw new Error('[[error:invalid-group-name]]');
}
if (name.includes('/') || !(0, slugify_1.default)(name)) {
throw new Error('[[error:invalid-group-name]]');
}
};
}
module.exports = createGroup;
151 changes: 151 additions & 0 deletions src/groups/create.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import meta from '../meta';
import * as plugins from '../plugins';
import slugify from '../slugify';
import * as db from '../database';

interface GroupData {
name: string;
timestamp?: number;
disableJoinRequests?: string | number;
disableLeave?: string | number;
hidden?: string | number;
userTitle?: string;
userTitleEnabled?: string | number;
description?: string;
ownerUid?: number;
private?: string | number;
system?: string | number | boolean;
}

interface GroupDataComplete {
name: string;
slug: string;
createtime: number;
userTitle: string;
userTitleEnabled: number;
description: string;
memberCount: number;
hidden: number;
system: number;
private: number;
disableJoinRequests: number;
disableLeave: number;
}

interface GroupsInterface {
create: (data: GroupData) => Promise<GroupDataComplete>;
validateGroupName: (name: string) => void;
systemGroups: string[];
isPrivilegeGroup: (name: string) => boolean;
getGroupData: (name: string) => Promise<GroupDataComplete>;
}

function createGroup(Groups: GroupsInterface) {
function isSystemGroup(data: GroupData): boolean {
return data.system === true || parseInt(data.system as string, 10) === 1 ||
Groups.systemGroups.includes(data.name) ||
Groups.isPrivilegeGroup(data.name);
}

async function privilegeGroupExists(name: string): Promise<boolean> {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
return Groups.isPrivilegeGroup(name) && await db.isSortedSetMember('groups:createtime', name) as boolean;
}

Groups.create = async function (data: GroupData): Promise<GroupDataComplete> {
const isSystem = isSystemGroup(data);
const timestamp = data.timestamp || Date.now();
let disableJoinRequests = parseInt(data.disableJoinRequests as string, 10) === 1 ? 1 : 0;
if (data.name === 'administrators') {
disableJoinRequests = 1;
}
const disableLeave = parseInt(data.disableLeave as string, 10) === 1 ? 1 : 0;
const isHidden = parseInt(data.hidden as string, 10) === 1;

Groups.validateGroupName(data.name);

const [exists, privGroupExists] = await Promise.all([
meta.userOrGroupExists(data.name),
privilegeGroupExists(data.name),
]) as [boolean, boolean];
if (exists || privGroupExists) {
throw new Error('[[error:group-already-exists]]');
}

const memberCount = data.hasOwnProperty('ownerUid') ? 1 : 0;
const isPrivate = data.hasOwnProperty('private') && data.private !== undefined ? parseInt(data.private as string, 10) === 1 : true;
let groupData = {
name: data.name,
slug: slugify(data.name) as string,
createtime: timestamp,
userTitle: data.userTitle || data.name,
userTitleEnabled: parseInt(data.userTitleEnabled as string, 10) === 1 ? 1 : 0,
description: data.description || '',
memberCount: memberCount,
hidden: isHidden ? 1 : 0,
system: isSystem ? 1 : 0,
private: isPrivate ? 1 : 0,
disableJoinRequests: disableJoinRequests,
disableLeave: disableLeave,
};

await plugins.hooks.fire('filter:group.create', { group: groupData, data: data });

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
await db.sortedSetAdd('groups:createtime', groupData.createtime, groupData.name);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
await db.setObject(`group:${groupData.name}`, groupData);

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (data.hasOwnProperty('ownerUid')) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
await db.setAdd(`group:${groupData.name}:owners`, data.ownerUid);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
await db.sortedSetAdd(`group:${groupData.name}:members`, timestamp, data.ownerUid);
}

if (!isHidden && !isSystem) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
await db.sortedSetAddBulk([
['groups:visible:createtime', timestamp, groupData.name],
['groups:visible:memberCount', groupData.memberCount, groupData.name],
['groups:visible:name', 0, `${groupData.name.toLowerCase()}:${groupData.name}`],
]);
}

if (!Groups.isPrivilegeGroup(groupData.name)) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
await db.setObjectField('groupslug:groupname', groupData.slug, groupData.name);
}

groupData = await Groups.getGroupData(groupData.name);
await plugins.hooks.fire('action:group.create', { group: groupData });
return groupData;
};

Groups.validateGroupName = function (name: string): void {
if (!name) {
throw new Error('[[error:group-name-too-short]]');
}

if (typeof name !== 'string') {
throw new Error('[[error:invalid-group-name]]');
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (!Groups.isPrivilegeGroup(name) && name.length > meta.config.maximumGroupNameLength) {
throw new Error('[[error:group-name-too-long]]');
}

if (name === 'guests' || (!Groups.isPrivilegeGroup(name) && name.includes(':'))) {
throw new Error('[[error:invalid-group-name]]');
}

if (name.includes('/') || !slugify(name)) {
throw new Error('[[error:invalid-group-name]]');
}
};
}

export = createGroup

Loading