@sync-in/server
Version:
The secure, open-source platform for file storage, sharing, collaboration, and sync
570 lines (568 loc) • 33.6 kB
JavaScript
/*
* 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, "UsersQueries", {
enumerable: true,
get: function() {
return UsersQueries;
}
});
const _common = require("@nestjs/common");
const _drizzleorm = require("drizzle-orm");
const _mysqlcore = require("drizzle-orm/mysql-core");
const _functions = require("../../../common/functions");
const _cachedecorator = require("../../../infrastructure/cache/cache.decorator");
const _cacheservice = require("../../../infrastructure/cache/services/cache.service");
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");
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 UsersQueries = class UsersQueries {
checkUserExists(login, email) {
if (!login && !email) {
throw new Error('login or email must be specified');
}
const columns = {};
const where = [];
if (login) {
columns.login = true;
where.push((0, _drizzleorm.eq)(_usersschema.users.login, login));
}
if (email) {
columns.email = true;
where.push((0, _drizzleorm.eq)(_usersschema.users.email, email));
}
const operator = login && email ? _drizzleorm.or : _drizzleorm.and;
return this.db.query.users.findFirst({
columns: columns,
where: operator(...where)
});
}
setOnlineStatus(userId, onlineStatus) {
return this.updateUserOrGuest(userId, {
onlineStatus: onlineStatus
});
}
getOnlineUsers(userIds) {
return this.db.select({
id: _usersschema.users.id,
login: _usersschema.users.login,
email: _usersschema.users.email,
fullName: (0, _usersschema.userFullNameSQL)(_usersschema.users),
onlineStatus: _usersschema.users.onlineStatus
}).from(_usersschema.users).where((0, _drizzleorm.inArray)(_usersschema.users.id, userIds));
}
async checkGroupNameExists(groupName) {
const [group] = await this.db.select({
name: _groupsschema.groups.name
}).from(_groupsschema.groups).where((0, _drizzleorm.eq)(_groupsschema.groups.name, groupName)).limit(1);
return !!group?.name;
}
async compareUserPassword(userId, password) {
const [hash] = await this.selectUsers([
'password'
], [
(0, _drizzleorm.eq)(_usersschema.users.id, userId)
]);
if (!hash) return false;
return (0, _functions.comparePassword)(password, hash.password);
}
async from(userId, loginOrEmail) {
// retrieve user with application permissions
let pQuery = userId ? this.fromIdPermissionsQuery : this.fromLoginOrEmailPermissionsQuery;
if (!pQuery) {
const where = userId ? (0, _drizzleorm.eq)(_usersschema.users.id, _drizzleorm.sql.placeholder('userId')) : (0, _drizzleorm.or)((0, _drizzleorm.eq)(_usersschema.users.login, _drizzleorm.sql.placeholder('loginOrEmail')), (0, _drizzleorm.eq)(_usersschema.users.email, _drizzleorm.sql.placeholder('loginOrEmail')));
pQuery = this.db.select({
user: _usersschema.users,
groupsPermissions: (0, _drizzleorm.sql)`GROUP_CONCAT(DISTINCT (${_groupsschema.groups.permissions}) SEPARATOR ${_user.USER_PERMS_SEP})`
}).from(_usersschema.users).leftJoin(_usersgroupsschema.usersGroups, (0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.userId, _usersschema.users.id)).leftJoin(_groupsschema.groups, (0, _drizzleorm.and)((0, _drizzleorm.eq)(_groupsschema.groups.id, _usersgroupsschema.usersGroups.groupId), (0, _drizzleorm.ne)(_groupsschema.groups.permissions, ''))).where(where).groupBy(_usersschema.users.id).limit(1).prepare();
if (userId) {
this.fromIdPermissionsQuery = pQuery;
} else {
this.fromLoginOrEmailPermissionsQuery = pQuery;
}
}
const r = await pQuery.execute(userId ? {
userId
} : {
loginOrEmail
});
if (!r.length) return null;
const [user, groupsPermissions] = [
r[0].user,
r[0].groupsPermissions
];
// merge user and groups permissions
user.permissions = (0, _functions.uniquePermissions)(`${user.permissions},${groupsPermissions}`, _user.USER_PERMS_SEP);
return user;
}
selectUsers(fields = [
'id',
'login',
'email'
], where) {
const select = (0, _utils.convertToSelect)(_usersschema.users, fields);
return this.db.select(select).from(_usersschema.users).where((0, _drizzleorm.and)(...where));
}
async selectUserProperties(userId, fields) {
const select = (0, _utils.convertToSelect)(_usersschema.users, fields);
const [r] = await this.db.select(select).from(_usersschema.users).where((0, _drizzleorm.eq)(_usersschema.users.id, userId)).limit(1);
return r;
}
async createUserOrGuest(createUserDto, userRole) {
const userId = (0, _utils.dbGetInsertedId)(await this.db.insert(_usersschema.users).values({
...createUserDto,
role: userRole
}));
if (userRole === _user.USER_ROLE.USER && createUserDto.groups?.length) {
await this.db.insert(_usersgroupsschema.usersGroups).values(createUserDto.groups.map((gid)=>({
userId: userId,
groupId: gid
})));
}
if (userRole === _user.USER_ROLE.GUEST && createUserDto.managers?.length) {
await this.db.insert(_usersguestsschema.usersGuests).values(createUserDto.managers.map((uid)=>({
guestId: userId,
userId: uid
})));
}
return userId;
}
async updateUserOrGuest(userId, set, userRole) {
try {
(0, _utils.dbCheckAffectedRows)(await this.db.update(_usersschema.users).set({
...set,
...userRole && {
role: userRole
}
}).where((0, _drizzleorm.eq)(_usersschema.users.id, userId)), 1);
this.logger.verbose(`${this.updateUserOrGuest.name} - user (${userId}) was updated : ${JSON.stringify((0, _functions.anonymizePassword)(set))}`);
return true;
} catch (e) {
this.logger.error(`${this.updateUserOrGuest.name} - user (${userId}) was not updated : ${JSON.stringify((0, _functions.anonymizePassword)(set))} : ${e}`);
return false;
}
}
async deleteGuestLink(userId) {
(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.role, _user.USER_ROLE.LINK))), 1);
}
async searchUsersOrGroups(searchMembersDto, userId) {
const limit = searchMembersDto.onlyUsers || searchMembersDto.onlyGroups ? 6 : 3;
const members = [];
if (!searchMembersDto.onlyGroups) {
for (const u of (await this.searchUsers(searchMembersDto, userId, limit))){
members.push({
id: u.id,
login: u.login,
name: u.fullName,
description: u.email,
type: u.role === _user.USER_ROLE.GUEST ? _member.MEMBER_TYPE.GUEST : _member.MEMBER_TYPE.USER,
permissions: searchMembersDto.withPermissions ? u.permissions : undefined
});
}
}
if (!searchMembersDto.onlyUsers) {
for (const g of (await this.searchGroups(searchMembersDto, userId, limit))){
members.push({
id: g.id,
name: g.name,
description: g.description,
type: g.type === _group.GROUP_TYPE.USER ? _member.MEMBER_TYPE.GROUP : _member.MEMBER_TYPE.PGROUP,
permissions: searchMembersDto.withPermissions ? g.permissions : undefined
});
}
}
return members;
}
async groupFromName(userId, name) {
const [group] = await this.db.select({
id: _groupsschema.groups.id,
name: _groupsschema.groups.name,
type: _groupsschema.groups.type,
role: _usersgroupsschema.usersGroups.role
}).from(_usersgroupsschema.usersGroups).innerJoin(_groupsschema.groups, (0, _drizzleorm.eq)(_groupsschema.groups.id, _usersgroupsschema.usersGroups.groupId)).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.userId, userId), (0, _drizzleorm.eq)(_groupsschema.groups.name, name))).limit(1);
return group;
}
async browseRootGroups(userId) {
const members = (0, _mysqlcore.alias)(_usersgroupsschema.usersGroups, 'members');
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})`,
groupRole: (0, _drizzleorm.sql)`${_usersgroupsschema.usersGroups.role}`,
counts: {
users: (0, _drizzleorm.countDistinct)(members.userId)
}
}).from(_usersgroupsschema.usersGroups).innerJoin(_groupsschema.groups, (0, _drizzleorm.and)((0, _drizzleorm.eq)(_groupsschema.groups.id, _usersgroupsschema.usersGroups.groupId), (0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.userId, userId))).leftJoin(members, (0, _drizzleorm.eq)(members.groupId, _groupsschema.groups.id)).groupBy(_groupsschema.groups.id);
}
async browseGroupMembers(groupId) {
return 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,
type: (0, _drizzleorm.sql)`${_member.MEMBER_TYPE.USER}`,
groupRole: (0, _drizzleorm.sql)`${_usersgroupsschema.usersGroups.role}`
}).from(_groupsschema.groups).innerJoin(_usersgroupsschema.usersGroups, (0, _drizzleorm.and)((0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.groupId, _groupsschema.groups.id), (0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.groupId, groupId))).leftJoin(_usersschema.users, (0, _drizzleorm.eq)(_usersschema.users.id, _usersgroupsschema.usersGroups.userId)).groupBy(_usersschema.users.id);
}
async canDeletePersonalGroup(userId, groupId) {
const [group] = await this.db.select({
id: _usersgroupsschema.usersGroups.groupId
}).from(_usersgroupsschema.usersGroups).innerJoin(_groupsschema.groups, (0, _drizzleorm.and)((0, _drizzleorm.eq)(_groupsschema.groups.id, _usersgroupsschema.usersGroups.groupId))).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_groupsschema.groups.type, _group.GROUP_TYPE.PERSONAL), (0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.userId, userId), (0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.groupId, groupId), (0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.role, _user.USER_GROUP_ROLE.MANAGER))).limit(1);
return !!group?.id;
}
async getGroup(userId, groupId, asAdmin = false) {
const [group] = await 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})`
}).from(_usersgroupsschema.usersGroups).innerJoin(_groupsschema.groups, (0, _drizzleorm.and)((0, _drizzleorm.eq)(_groupsschema.groups.id, _usersgroupsschema.usersGroups.groupId))).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.groupId, groupId), (0, _drizzleorm.sql)`IF(${+asAdmin} = 0, ${_usersgroupsschema.usersGroups.userId} = ${userId} AND ${_usersgroupsschema.usersGroups.role} = ${_user.USER_GROUP_ROLE.MANAGER}, 1)`)).limit(1);
return group;
}
async getGroupWithMembers(userId, groupId, asAdmin = false) {
const usersGroupsAlias = (0, _mysqlcore.alias)(_usersgroupsschema.usersGroups, 'usersFromGroups');
const [group] = await 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}, ${_drizzleorm.sql.raw(`'${_member.MEMBER_TYPE.GROUP}'`)}, ${_drizzleorm.sql.raw(`'${_member.MEMBER_TYPE.PGROUP}'`)})`,
members: (0, _utils.concatDistinctObjectsInArray)(_usersschema.users.id, {
id: _usersschema.users.id,
login: _usersschema.users.login,
name: (0, _usersschema.userFullNameSQL)(_usersschema.users),
description: _usersschema.users.email,
type: _drizzleorm.sql.raw(`'${_member.MEMBER_TYPE.USER}'`),
groupRole: usersGroupsAlias.role,
createdAt: (0, _utils.dateTimeUTC)(usersGroupsAlias.createdAt)
})
}).from(_usersgroupsschema.usersGroups).innerJoin(_groupsschema.groups, (0, _drizzleorm.eq)(_groupsschema.groups.id, _usersgroupsschema.usersGroups.groupId)).leftJoin(usersGroupsAlias, (0, _drizzleorm.and)((0, _drizzleorm.eq)(usersGroupsAlias.groupId, _groupsschema.groups.id))).leftJoin(_usersschema.users, (0, _drizzleorm.eq)(_usersschema.users.id, usersGroupsAlias.userId)).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.groupId, groupId), (0, _drizzleorm.sql)`IF(${+asAdmin} = 0, ${_usersgroupsschema.usersGroups.userId} = ${userId} AND ${_usersgroupsschema.usersGroups.role} = ${_user.USER_GROUP_ROLE.MANAGER}, 1)`)).groupBy(_groupsschema.groups.id).limit(1);
return group;
}
async deletePersonalGroup(groupId) {
return (0, _utils.dbCheckAffectedRows)(await this.db.delete(_groupsschema.groups).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_groupsschema.groups.id, groupId), (0, _drizzleorm.eq)(_groupsschema.groups.type, _group.GROUP_TYPE.PERSONAL))).limit(1), 1, false);
}
async createPersonalGroup(managerId, userCreateOrUpdateGroupDto) {
const groupId = (0, _utils.dbGetInsertedId)(await this.db.insert(_groupsschema.groups).values({
...userCreateOrUpdateGroupDto,
type: _group.GROUP_TYPE.PERSONAL,
visibility: _group.GROUP_VISIBILITY.PRIVATE
}));
await this.db.insert(_usersgroupsschema.usersGroups).values({
userId: managerId,
groupId: groupId,
role: _user.USER_GROUP_ROLE.MANAGER
});
return groupId;
}
async updateGroup(groupId, set) {
if (Object.keys(set).length) {
try {
await this.db.update(_groupsschema.groups).set(set).where((0, _drizzleorm.eq)(_groupsschema.groups.id, groupId));
this.logger.log(`${this.updateGroup.name} - group (${groupId}) was updated : ${JSON.stringify(set)}`);
} catch (e) {
this.logger.error(`${this.updateGroup.name} - group (${groupId}) was not updated : ${JSON.stringify(set)} : ${e}`);
throw new Error('Group was not updated');
}
}
}
async updateGroupMembers(groupId, members) {
if (members?.add?.length) {
try {
await this.db.insert(_usersgroupsschema.usersGroups).values(members.add.map((m)=>({
userId: m.id,
groupId: groupId,
role: m.groupRole
})));
// clear cache
this.clearWhiteListCaches(members.add.map((m)=>m.id));
this.logger.log(`${this.updateGroupMembers.name} - users ${JSON.stringify(members.add.map((m)=>m.id))} was added to group (${groupId})`);
} catch (e) {
this.logger.error(`${this.updateGroupMembers.name} - users ${JSON.stringify(members.add.map((m)=>m.id))} was not added to group (${groupId}) : ${e}`);
throw new Error('Group members was not added');
}
}
if (members?.remove?.length) {
try {
await this.db.delete(_usersgroupsschema.usersGroups).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_usersgroupsschema.usersGroups.groupId, groupId), (0, _drizzleorm.inArray)(_usersgroupsschema.usersGroups.userId, members.remove))).limit(members.remove.length);
// clear cache
this.clearWhiteListCaches(members.remove);
this.logger.log(`${this.updateGroupMembers.name} - users ${JSON.stringify(members.remove)} was removed from group (${groupId})`);
} catch (e) {
this.logger.error(`${this.updateGroupMembers.name} - users ${JSON.stringify(members.remove)} was not removed from group (${groupId}) : ${e}`);
throw new Error('Group members was not removed');
}
}
}
async listGuests(guestId, managerId, asAdmin = false) {
const where = [
...guestId ? [
(0, _drizzleorm.eq)(_usersguestsschema.usersGuests.guestId, guestId)
] : [],
...asAdmin ? [] : [
(0, _drizzleorm.eq)(_usersguestsschema.usersGuests.userId, managerId)
]
];
const managersGuestAlias = (0, _mysqlcore.alias)(_usersguestsschema.usersGuests, 'managersGuestAlias');
const managersAlias = (0, _mysqlcore.alias)(_usersschema.users, 'managersAlias');
const guests = await this.db.select({
id: _usersschema.users.id,
login: _usersschema.users.login,
email: _usersschema.users.email,
firstName: _usersschema.users.firstName,
lastName: _usersschema.users.lastName,
fullName: (0, _usersschema.userFullNameSQL)(_usersschema.users),
role: _usersschema.users.role,
isActive: _usersschema.users.isActive,
passwordAttempts: _usersschema.users.passwordAttempts,
language: _usersschema.users.language,
notification: _usersschema.users.notification,
currentAccess: _usersschema.users.currentAccess,
lastAccess: _usersschema.users.lastAccess,
currentIp: _usersschema.users.currentIp,
lastIp: _usersschema.users.lastIp,
createdAt: _usersschema.users.createdAt,
managers: (0, _utils.concatDistinctObjectsInArray)(managersAlias.id, {
id: managersAlias.id,
login: managersAlias.login,
name: (0, _usersschema.userFullNameSQL)(managersAlias),
type: _drizzleorm.sql.raw(`'${_member.MEMBER_TYPE.USER}'`),
description: managersAlias.email,
createdAt: (0, _utils.dateTimeUTC)(managersGuestAlias.createdAt)
})
}).from(_usersguestsschema.usersGuests).innerJoin(_usersschema.users, (0, _drizzleorm.and)((0, _drizzleorm.eq)(_usersschema.users.id, _usersguestsschema.usersGuests.guestId), (0, _drizzleorm.eq)(_usersschema.users.role, _user.USER_ROLE.GUEST))).leftJoin(managersGuestAlias, (0, _drizzleorm.eq)(managersGuestAlias.guestId, _usersschema.users.id)).leftJoin(managersAlias, (0, _drizzleorm.eq)(managersAlias.id, managersGuestAlias.userId)).where((0, _drizzleorm.and)(...where)).groupBy(_usersschema.users.id).limit(guestId ? 1 : undefined);
return guestId ? guests[0] : guests;
}
async isGuestManager(managerId, guestId) {
const [guest] = await this.db.select({
id: _usersguestsschema.usersGuests.guestId,
login: _usersschema.users.login
}).from(_usersguestsschema.usersGuests).innerJoin(_usersschema.users, (0, _drizzleorm.eq)(_usersschema.users.id, _usersguestsschema.usersGuests.guestId)).where((0, _drizzleorm.and)((0, _drizzleorm.eq)(_usersguestsschema.usersGuests.userId, managerId), (0, _drizzleorm.eq)(_usersguestsschema.usersGuests.guestId, guestId), (0, _drizzleorm.eq)(_usersschema.users.role, _user.USER_ROLE.GUEST))).limit(1);
return guest;
}
async searchGroups(searchMembersDto, userId, limit = 3) {
/* Search for groups */ const where = [
(0, _drizzleorm.like)(_groupsschema.groups.name, `%${searchMembersDto.search}%`)
];
if (userId) {
let idsWhitelist = await this.groupsWhitelist(userId);
if (searchMembersDto.ignoreGroupIds?.length) {
idsWhitelist = idsWhitelist.filter((id)=>searchMembersDto.ignoreGroupIds.indexOf(id) === -1);
}
where.unshift((0, _drizzleorm.inArray)(_groupsschema.groups.id, idsWhitelist));
} else if (searchMembersDto.ignoreGroupIds?.length) {
where.unshift((0, _drizzleorm.notInArray)(_groupsschema.groups.id, searchMembersDto.ignoreGroupIds));
}
if (searchMembersDto.excludePersonalGroups) {
where.unshift((0, _drizzleorm.eq)(_groupsschema.groups.type, _group.GROUP_TYPE.USER));
}
return this.db.select({
id: _groupsschema.groups.id,
name: _groupsschema.groups.name,
description: _groupsschema.groups.description,
type: _groupsschema.groups.type,
permissions: _groupsschema.groups.permissions
}).from(_groupsschema.groups).where((0, _drizzleorm.and)(...where)).limit(limit);
}
async searchUsers(searchMembersDto, userId, limit = 3) {
/* Search for users */ const where = [
(0, _drizzleorm.ne)(_usersschema.users.role, _user.USER_ROLE.LINK),
(0, _drizzleorm.or)((0, _drizzleorm.like)((0, _drizzleorm.sql)`CONCAT_WS('-', ${_usersschema.users.login}, ${_usersschema.users.email}, ${_usersschema.users.firstName}, ${_usersschema.users.lastName})`, `%${searchMembersDto.search}%`))
];
if (userId) {
let idsWhitelist = await this.usersWhitelist(userId);
if (searchMembersDto.ignoreUserIds?.length) {
idsWhitelist = idsWhitelist.filter((id)=>searchMembersDto.ignoreUserIds.indexOf(id) === -1);
}
where.unshift((0, _drizzleorm.inArray)(_usersschema.users.id, idsWhitelist));
} else {
if (searchMembersDto.ignoreUserIds?.length) {
where.unshift((0, _drizzleorm.notInArray)(_usersschema.users.id, searchMembersDto.ignoreUserIds));
}
}
if (typeof searchMembersDto.usersRole !== 'undefined') {
if (searchMembersDto.usersRole === _user.USER_ROLE.USER) {
// allow admin users
where.unshift((0, _drizzleorm.lte)(_usersschema.users.role, searchMembersDto.usersRole));
} else {
where.unshift((0, _drizzleorm.eq)(_usersschema.users.role, searchMembersDto.usersRole));
}
}
return this.db.select({
id: _usersschema.users.id,
login: _usersschema.users.login,
email: _usersschema.users.email,
fullName: (0, _usersschema.userFullNameSQL)(_usersschema.users),
role: _usersschema.users.role,
permissions: _usersschema.users.permissions
}).from(_usersschema.users).where((0, _drizzleorm.and)(...where)).limit(limit);
}
async usersWhitelist(userId, lowerOrEqualUserRole = _user.USER_ROLE.GUEST) {
/* Get the list of user ids allowed to the current user
- all users with no groups (except link users)
- all users who are members of the current user's groups (excluding link users and members of isolated groups)
- all guests managed by the current user
- all managers who manage the current guest
*/ const usersAlias = (0, _mysqlcore.alias)(_usersschema.users, 'usersAlias');
const groupsAlias = (0, _mysqlcore.alias)(_groupsschema.groups, 'groupsAlias');
const userIds = (0, _drizzleorm.sql)`
WITH RECURSIVE children (id, parentId) AS
(SELECT ${_groupsschema.groups.id},
${_groupsschema.groups.parentId}
FROM ${_groupsschema.groups}
WHERE (${_groupsschema.groups.id} IN (SELECT ${_usersgroupsschema.usersGroups.groupId}
FROM ${_usersgroupsschema.usersGroups}
WHERE ${_usersgroupsschema.usersGroups.userId} = ${userId}
AND ${_groupsschema.groups.visibility} != ${_group.GROUP_VISIBILITY.ISOLATED}))
UNION
SELECT ${groupsAlias.id},
${groupsAlias.parentId}
FROM ${_groupsschema.groups} AS groupsAlias
INNER JOIN children cs ON ${groupsAlias.parentId} = cs.id AND ${groupsAlias.visibility} = ${_drizzleorm.sql.raw(`${_group.GROUP_VISIBILITY.VISIBLE}`)})
SELECT JSON_ARRAYAGG(id) AS ids
FROM (
-- Users from visible child groups
SELECT ${_usersschema.users.id} AS id
FROM children
INNER JOIN ${_usersgroupsschema.usersGroups} ON ${_usersgroupsschema.usersGroups.groupId} = children.id
INNER JOIN ${_usersschema.users} ON ${_usersgroupsschema.usersGroups.userId} = ${_usersschema.users.id} AND ${_usersschema.users.role} <= ${_drizzleorm.sql.raw(`${lowerOrEqualUserRole}`)}
UNION
-- Users visible but not assigned to groups
SELECT ${usersAlias.id} AS id
FROM ${_usersschema.users} AS usersAlias
INNER JOIN ${_usersschema.users} ON ${_usersschema.users.id} = ${usersAlias.id} AND ${_usersschema.users.role} <= ${_drizzleorm.sql.raw(`${lowerOrEqualUserRole}`)}
WHERE NOT EXISTS (SELECT ${_usersgroupsschema.usersGroups.userId} FROM ${_usersgroupsschema.usersGroups} WHERE ${_usersgroupsschema.usersGroups.userId} = ${usersAlias.id})
UNION
-- Users or guests that are manager/managed
SELECT CASE
WHEN ${_usersguestsschema.usersGuests.userId} = ${userId} THEN ${_usersguestsschema.usersGuests.guestId}
WHEN ${_usersguestsschema.usersGuests.guestId} = ${userId} THEN ${_usersguestsschema.usersGuests.userId}
END AS id
FROM ${_usersguestsschema.usersGuests}
WHERE ${_usersguestsschema.usersGuests.userId} = ${userId}
OR ${_usersguestsschema.usersGuests.guestId} = ${userId}) AS usersUnion
`;
const [r] = await this.db.execute(userIds);
return JSON.parse(r[0].ids) || [];
}
async groupsWhitelist(userId) {
/* Get the list of groups ids allowed to the current user
- all parent groups for which the user is a member (includes personal groups, excludes isolated groups)
- all subgroups inherited from parent groups
*/ const groupsAlias = (0, _mysqlcore.alias)(_groupsschema.groups, 'groupsAlias');
const groupIds = (0, _drizzleorm.sql)`
WITH RECURSIVE children (id, parentId, type) AS
(SELECT ${_groupsschema.groups.id},
${_groupsschema.groups.parentId},
${_groupsschema.groups.type}
FROM ${_groupsschema.groups}
WHERE (${_groupsschema.groups.id} IN (SELECT ${_usersgroupsschema.usersGroups.groupId}
FROM ${_usersgroupsschema.usersGroups}
WHERE ${_usersgroupsschema.usersGroups.userId} = ${userId}
AND ${_groupsschema.groups.visibility} != ${_group.GROUP_VISIBILITY.ISOLATED}))
UNION
SELECT ${groupsAlias.id},
${groupsAlias.parentId},
${groupsAlias.type}
FROM ${_groupsschema.groups} AS groupsAlias
INNER JOIN children cs ON ${groupsAlias.parentId} = cs.id AND ${groupsAlias.visibility} = ${_group.GROUP_VISIBILITY.VISIBLE})
SELECT JSON_ARRAYAGG(children.id) as ids
FROM children
`;
const [r] = await this.db.execute(groupIds);
return JSON.parse(r[0].ids) || [];
}
clearWhiteListCaches(userIds) {
this.cache.mdel([
...userIds.map((id)=>this.cache.genSlugKey(this.constructor.name, this.usersWhitelist.name, id)),
...userIds.map((id)=>this.cache.genSlugKey(this.constructor.name, this.groupsWhitelist.name, id))
]).catch((e)=>this.logger.error(`${this.clearWhiteListCaches.name} - ${e}`));
}
async allUserIdsFromGroupsAndSubGroups(groupIds) {
if (!groupIds.length) return [];
const subGroup = (0, _mysqlcore.alias)(_groupsschema.groups, 'subGroup');
const withChildren = (0, _drizzleorm.sql)`
WITH RECURSIVE child (id, parentId) AS
(SELECT ${_groupsschema.groups.id}, ${_groupsschema.groups.parentId}
FROM ${_groupsschema.groups}
WHERE ${(0, _drizzleorm.inArray)(_groupsschema.groups.id, groupIds)}
UNION
SELECT ${subGroup.id},
${subGroup.parentId}
FROM ${_groupsschema.groups} AS subGroup
INNER JOIN child AS cs ON ${subGroup.parentId} = cs.id)
SELECT DISTINCT ${_usersgroupsschema.usersGroups.userId} as userId
FROM child
INNER JOIN ${_usersgroupsschema.usersGroups} ON child.id = ${_usersgroupsschema.usersGroups.groupId}
`;
const [r] = await this.db.execute(withChildren);
return r.length ? r.map((r)=>r.userId) : [];
}
constructor(db, cache){
this.db = db;
this.cache = cache;
this.logger = new _common.Logger(UsersQueries.name);
this.fromLoginOrEmailPermissionsQuery = null;
this.fromIdPermissionsQuery = null;
}
};
_ts_decorate([
(0, _cachedecorator.CacheDecorator)(900),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
Number,
typeof _user.USER_ROLE === "undefined" ? Object : _user.USER_ROLE
]),
_ts_metadata("design:returntype", Promise)
], UsersQueries.prototype, "usersWhitelist", null);
_ts_decorate([
(0, _cachedecorator.CacheDecorator)(900),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
Number
]),
_ts_metadata("design:returntype", Promise)
], UsersQueries.prototype, "groupsWhitelist", null);
UsersQueries = _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 _cacheservice.Cache === "undefined" ? Object : _cacheservice.Cache
])
], UsersQueries);
//# sourceMappingURL=users-queries.service.js.map