UNPKG

@sync-in/server

Version:

The secure, open-source platform for file storage, sharing, collaboration, and sync

315 lines (314 loc) 18.7 kB
/* * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com> * This file is part of Sync-in | The open source file sync and share solution * See the LICENSE file for licensing details */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "AdminUsersQueries", { enumerable: true, get: function() { return AdminUsersQueries; } }); const _common = require("@nestjs/common"); const _drizzleorm = require("drizzle-orm"); const _mysqlcore = require("drizzle-orm/mysql-core"); const _constants = require("../../../infrastructure/database/constants"); const _databaseinterface = require("../../../infrastructure/database/interfaces/database.interface"); const _utils = require("../../../infrastructure/database/utils"); const _group = require("../constants/group"); const _member = require("../constants/member"); const _user = require("../constants/user"); const _groupsschema = require("../schemas/groups.schema"); const _usersgroupsschema = require("../schemas/users-groups.schema"); const _usersguestsschema = require("../schemas/users-guests.schema"); const _usersschema = require("../schemas/users.schema"); const _usersqueriesservice = require("./users-queries.service"); function _ts_decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; } function _ts_metadata(k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); } function _ts_param(paramIndex, decorator) { return function(target, key) { decorator(target, key, paramIndex); }; } let AdminUsersQueries = class AdminUsersQueries { async listUsers(userId) { const where = [ (0, _drizzleorm.lte)(_usersschema.users.role, _user.USER_ROLE.USER), ...userId ? [ (0, _drizzleorm.eq)(_usersschema.users.id, userId) ] : [] ]; const q = this.db.select({ id: _usersschema.users.id, login: _usersschema.users.login, email: _usersschema.users.email, role: _usersschema.users.role, fullName: (0, _usersschema.userFullNameSQL)(_usersschema.users), isActive: _usersschema.users.isActive, ...userId && { firstName: _usersschema.users.firstName, lastName: _usersschema.users.lastName, notification: _usersschema.users.notification, permissions: _usersschema.users.permissions, groups: (0, _utils.concatDistinctObjectsInArray)(_groupsschema.groups.id, { id: _groupsschema.groups.id, name: _groupsschema.groups.name, description: _groupsschema.groups.description, type: _drizzleorm.sql.raw(`'${_member.MEMBER_TYPE.GROUP}'`), permissions: _groupsschema.groups.permissions, createdAt: (0, _utils.dateTimeUTC)(_usersgroupsschema.usersGroups.createdAt) }) }, language: _usersschema.users.language, passwordAttempts: _usersschema.users.passwordAttempts, storageUsage: _usersschema.users.storageUsage, storageQuota: _usersschema.users.storageQuota, currentIp: _usersschema.users.currentIp, lastIp: _usersschema.users.lastIp, currentAccess: _usersschema.users.currentAccess, lastAccess: _usersschema.users.lastAccess, createdAt: _usersschema.users.createdAt }).from(_usersschema.users); if (userId) { q.leftJoin(_usersgroupsschema.usersGroups, (0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.userId, _usersschema.users.id)); q.leftJoin(_groupsschema.groups, (0, _drizzleorm.and)((0, _drizzleorm.eq)(_groupsschema.groups.id, _usersgroupsschema.usersGroups.groupId), (0, _drizzleorm.eq)(_groupsschema.groups.type, _group.GROUP_TYPE.USER))); q.limit(1); } q.where((0, _drizzleorm.and)(...where)).groupBy(_usersschema.users.id); const rs = await q; if (userId) { return rs.length ? rs[0] : null; } return rs; } async groupFromId(groupId) { const groupParent = (0, _mysqlcore.alias)(_groupsschema.groups, 'groupParent'); const [group] = await this.db.select({ id: _groupsschema.groups.id, name: _groupsschema.groups.name, type: _groupsschema.groups.type, description: _groupsschema.groups.description, permissions: _groupsschema.groups.permissions, visibility: _groupsschema.groups.visibility, createdAt: _groupsschema.groups.createdAt, modifiedAt: _groupsschema.groups.modifiedAt, parent: { id: groupParent.id, name: groupParent.name } }).from(_groupsschema.groups).leftJoin(groupParent, (0, _drizzleorm.eq)(groupParent.id, _groupsschema.groups.parentId)).where((0, _drizzleorm.eq)(_groupsschema.groups.id, groupId)).limit(1); return group; } async deleteUser(userId, userLogin) { return (0, _utils.dbCheckAffectedRows)(await this.db.delete(_usersschema.users).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_usersschema.users.id, userId), (0, _drizzleorm.eq)(_usersschema.users.login, userLogin))), 1, false); } async groupFromName(groupName) { const [group] = await this.db.select({ id: _groupsschema.groups.id, name: _groupsschema.groups.name, type: _groupsschema.groups.type }).from(_groupsschema.groups).where((0, _drizzleorm.eq)(_groupsschema.groups.name, groupName)).limit(1); return group; } async browseRootGroupMembers(type = _group.GROUP_TYPE.USER) { const childGroups = (0, _mysqlcore.alias)(_groupsschema.groups, 'childGroups'); return this.db.select({ id: _groupsschema.groups.id, name: _groupsschema.groups.name, description: _groupsschema.groups.description, createdAt: _groupsschema.groups.createdAt, modifiedAt: _groupsschema.groups.modifiedAt, type: (0, _drizzleorm.sql)`IF(${_groupsschema.groups.type} = ${_group.GROUP_TYPE.USER}, ${_member.MEMBER_TYPE.GROUP}, ${_member.MEMBER_TYPE.PGROUP})`, counts: { users: (0, _drizzleorm.count)(_usersgroupsschema.usersGroups.userId), groups: (0, _drizzleorm.countDistinct)(childGroups.id) } }).from(_groupsschema.groups).leftJoin(_usersgroupsschema.usersGroups, (0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.groupId, _groupsschema.groups.id)).leftJoin(childGroups, (0, _drizzleorm.eq)(childGroups.parentId, _groupsschema.groups.id)).where((0, _drizzleorm.and)((0, _drizzleorm.isNull)(_groupsschema.groups.parentId), (0, _drizzleorm.eq)(_groupsschema.groups.type, type))).groupBy(_groupsschema.groups.id); } async browseGroupMembers(groupId, type = _group.GROUP_TYPE.USER) { const childGroups = (0, _mysqlcore.alias)(_groupsschema.groups, 'childGroups'); const childGroupMembers = (0, _mysqlcore.alias)(_usersgroupsschema.usersGroups, 'childGroupMembers'); const subChildGroups = (0, _mysqlcore.alias)(_groupsschema.groups, 'subChildGroups'); const userMembers = this.db.select({ id: _usersschema.users.id, login: _usersschema.users.login, name: (0, _usersschema.userFullNameSQL)(_usersschema.users).as('name'), description: _usersschema.users.email, createdAt: _usersgroupsschema.usersGroups.createdAt, modifiedAt: (0, _drizzleorm.sql)`NULL`, type: (0, _drizzleorm.sql)`${_member.MEMBER_TYPE.USER}`, groupRole: (0, _drizzleorm.sql)`${_usersgroupsschema.usersGroups.role}`.mapWith(Number), counts: { users: (0, _drizzleorm.sql)`0`, groups: (0, _drizzleorm.sql)`0` } }).from(_groupsschema.groups).innerJoin(_usersgroupsschema.usersGroups, (0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.groupId, _groupsschema.groups.id)).leftJoin(_usersschema.users, (0, _drizzleorm.eq)(_usersschema.users.id, _usersgroupsschema.usersGroups.userId)).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_groupsschema.groups.id, groupId), (0, _drizzleorm.eq)(_groupsschema.groups.type, type), (0, _drizzleorm.isNotNull)(_usersschema.users.id))).groupBy(_usersschema.users.id); if (type === _group.GROUP_TYPE.PERSONAL) { return userMembers; } const groupMembers = this.db.select({ id: childGroups.id, login: (0, _drizzleorm.sql)`NULL`, name: childGroups.name, description: childGroups.description, createdAt: childGroups.createdAt, modifiedAt: childGroups.modifiedAt, type: (0, _drizzleorm.sql)`${_member.MEMBER_TYPE.GROUP}`, groupRole: (0, _drizzleorm.sql)`null`, counts: { users: (0, _drizzleorm.count)(_usersgroupsschema.usersGroups.userId), groups: (0, _drizzleorm.count)(subChildGroups.id) } }).from(_groupsschema.groups).innerJoin(childGroups, (0, _drizzleorm.eq)(childGroups.parentId, _groupsschema.groups.id)).leftJoin(_usersgroupsschema.usersGroups, (0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.groupId, childGroups.id)).leftJoin(childGroupMembers, (0, _drizzleorm.eq)(childGroupMembers.groupId, childGroups.id)).leftJoin(subChildGroups, (0, _drizzleorm.eq)(subChildGroups.parentId, childGroups.id)).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_groupsschema.groups.id, groupId), (0, _drizzleorm.eq)(_groupsschema.groups.type, type), (0, _drizzleorm.isNotNull)(childGroups.id))).groupBy(childGroups.id); return (0, _mysqlcore.union)(userMembers, groupMembers); } async updateUserGroups(userId, groups) { if (groups.add.length) { try { (0, _utils.dbCheckAffectedRows)(await this.db.insert(_usersgroupsschema.usersGroups).values(groups.add.map((gid)=>({ userId: userId, groupId: gid }))), groups.add.length); this.logger.log(`${this.updateUserGroups.name} - user (${userId}) groups ${JSON.stringify(groups.add)} was added`); this.usersQueries.clearWhiteListCaches([ userId ]); } catch (e) { this.logger.error(`${this.updateUserGroups.name} - user (${userId}) groups ${JSON.stringify(groups.add)} was not added: ${e}`); throw new Error('User groups was not added'); } } if (groups.delete.length) { try { (0, _utils.dbCheckAffectedRows)(await this.db.delete(_usersgroupsschema.usersGroups).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.userId, userId), (0, _drizzleorm.inArray)(_usersgroupsschema.usersGroups.groupId, groups.delete))), groups.delete.length); this.logger.log(`${this.updateUserGroups.name} - user (${userId}) groups ${JSON.stringify(groups.delete)} was deleted`); this.usersQueries.clearWhiteListCaches([ userId ]); } catch (e) { this.logger.error(`${this.updateUserGroups.name} - user (${userId}) groups ${JSON.stringify(groups.delete)} was not deleted: ${e}`); throw new Error('User groups was not deleted'); } } } async createGroup(createGroupDto) { return (0, _utils.dbGetInsertedId)(await this.db.insert(_groupsschema.groups).values({ ...createGroupDto, type: _group.GROUP_TYPE.USER })); } async updateGroup(groupId, set) { try { (0, _utils.dbCheckAffectedRows)(await this.db.update(_groupsschema.groups).set(set).where((0, _drizzleorm.eq)(_groupsschema.groups.id, groupId)), 1); this.logger.log(`${this.updateGroup.name} - group (${groupId}) was updated : ${JSON.stringify(set)}`); return true; } catch (e) { this.logger.error(`${this.updateGroup.name} - group (${groupId}) was not updated : ${JSON.stringify(set)} : ${e}`); return false; } } async deleteGroup(groupId) { const [parent] = await this.db.select({ id: _groupsschema.groups.parentId }).from(_groupsschema.groups).where((0, _drizzleorm.eq)(_groupsschema.groups.id, groupId)).limit(1); const parentId = parent?.id; if (parentId) { // attach child groups to current parent await this.db.update(_groupsschema.groups).set({ parentId: parentId }).where((0, _drizzleorm.eq)(_groupsschema.groups.parentId, groupId)); } return (0, _utils.dbCheckAffectedRows)(await this.db.delete(_groupsschema.groups).where((0, _drizzleorm.eq)(_groupsschema.groups.id, groupId)).limit(1), 1, false); } async addUsersToGroup(groupId, userIds, lowerOrEqualUserRole = _user.USER_ROLE.GUEST) { const userIdsWithRequiredRole = await this.db.select({ id: _usersschema.users.id }).from(_usersschema.users).where((0, _drizzleorm.and)((0, _drizzleorm.inArray)(_usersschema.users.id, userIds), (0, _drizzleorm.lte)(_usersschema.users.role, lowerOrEqualUserRole))); userIds = userIdsWithRequiredRole.map((u)=>u.id); if (userIds.length === 0) { throw new Error('No users to add to group'); } try { (0, _utils.dbCheckAffectedRows)(await this.db.insert(_usersgroupsschema.usersGroups).values(userIdsWithRequiredRole.map((u)=>({ groupId: groupId, userId: u.id }))), userIdsWithRequiredRole.length); this.logger.log(`${this.addUsersToGroup.name} - users (${userIds}) was added to group (${groupId})`); this.usersQueries.clearWhiteListCaches(userIds); } catch (e) { this.logger.error(`${this.addUsersToGroup.name} - unable to add users (${userIds}) to group (${groupId}) : ${e}`); throw new Error('Unable to add users to group'); } } async updateUserFromGroup(groupId, userId, role) { try { (0, _utils.dbCheckAffectedRows)(await this.db.update(_usersgroupsschema.usersGroups).set({ role: role }).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.groupId, groupId), (0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.userId, userId))).limit(1), 1); this.logger.log(`${this.updateUserFromGroup.name} - user (${userId}) was updated on group (${groupId}) as ${_user.USER_GROUP_ROLE[role]}`); } catch (e) { this.logger.error(`${this.updateUserFromGroup.name} - user (${userId}) was not updated on group (${groupId}) as ${_user.USER_GROUP_ROLE[role]} : ${e}`); throw new Error('Unable to update user from group'); } } async removeUserFromGroup(groupId, userId) { try { (0, _utils.dbCheckAffectedRows)(await this.db.delete(_usersgroupsschema.usersGroups).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.groupId, groupId), (0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.userId, userId))).limit(1), 1); this.logger.log(`${this.removeUserFromGroup.name} - user (${userId}) was removed from group (${groupId})`); this.usersQueries.clearWhiteListCaches([ userId ]); } catch (e) { this.logger.error(`${this.removeUserFromGroup.name} - user (${userId}) or group (${groupId}) does not exist : ${e}`); throw new Error('Unable to remove user from group'); } } async updateGuestManagers(guestId, managers) { if (managers.add.length) { try { (0, _utils.dbCheckAffectedRows)(await this.db.insert(_usersguestsschema.usersGuests).values(managers.add.map((uid)=>({ userId: uid, guestId: guestId }))), managers.add.length); this.logger.log(`${this.updateGuestManagers.name} - guest (${guestId}) managers ${JSON.stringify(managers.add)} was added`); } catch (e) { this.logger.error(`${this.updateGuestManagers.name} - guest (${guestId}) managers ${JSON.stringify(managers.add)} was not added: ${e}`); throw new Error('Guest managers was not added'); } } if (managers.delete.length) { try { (0, _utils.dbCheckAffectedRows)(await this.db.delete(_usersguestsschema.usersGuests).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_usersguestsschema.usersGuests.guestId, guestId), (0, _drizzleorm.inArray)(_usersguestsschema.usersGuests.userId, managers.delete))), managers.delete.length); this.logger.log(`${this.updateGuestManagers.name} - guest (${guestId}) managers ${JSON.stringify(managers.delete)} was deleted`); } catch (e) { this.logger.error(`${this.updateGuestManagers.name} - guest (${guestId}) managers ${JSON.stringify(managers.delete)} was not deleted: ${e}`); throw new Error('Guest managers was not deleted'); } } } constructor(db, usersQueries){ this.db = db; this.usersQueries = usersQueries; this.logger = new _common.Logger(AdminUsersQueries.name); } }; AdminUsersQueries = _ts_decorate([ (0, _common.Injectable)(), _ts_param(0, (0, _common.Inject)(_constants.DB_TOKEN_PROVIDER)), _ts_metadata("design:type", Function), _ts_metadata("design:paramtypes", [ typeof _databaseinterface.DBSchema === "undefined" ? Object : _databaseinterface.DBSchema, typeof _usersqueriesservice.UsersQueries === "undefined" ? Object : _usersqueriesservice.UsersQueries ]) ], AdminUsersQueries); //# sourceMappingURL=admin-users-queries.service.js.map