@topgroup/diginext
Version:
A BUILD SERVER & CLI to deploy apps to any Kubernetes clusters.
232 lines (231 loc) • 10.4 kB
JavaScript
;
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 };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.UserService = void 0;
const User_1 = require("../entities/User");
const dx_user_1 = require("../modules/diginext/dx-user");
const mongodb_1 = require("../plugins/mongodb");
const user_utils_1 = require("../plugins/user-utils");
const BaseService_1 = __importDefault(require("./BaseService"));
const RoleService_1 = require("./RoleService");
class UserService extends BaseService_1.default {
constructor(ownership) {
super(User_1.userSchema, ownership);
}
async find(filter, options, pagination) {
// if (filter) filter.type = { $nin: ["service_account", "api_key"] };
return super.find(filter, options, pagination);
}
async findOne(filter, options) {
// if (filter) filter.type = { $nin: ["service_account", "api_key"] };
return super.findOne(filter, options);
}
async create(data, options = {}) {
var _a;
let newUser = await super.create(data, options);
if (!newUser.username)
newUser = await this.updateOne({ _id: newUser._id }, { username: newUser.slug });
// create user on "dxup.dev" via "dxApi"
try {
console.log(newUser.providers[0]);
const dxUserRes = await (0, dx_user_1.dxCreateUser)({
name: newUser.name,
username: newUser.username,
image: newUser.image || "",
providers: newUser.providers[0],
email: newUser.email,
password: newUser.password,
isActive: true,
});
console.log("More data:", newUser);
if (!dxUserRes.status)
throw new Error((_a = dxUserRes.messages) === null || _a === void 0 ? void 0 : _a.join("\n"));
if (dxUserRes.data.id) {
newUser = await this.updateOne({ _id: newUser._id }, { dxUserId: dxUserRes.data.id });
}
}
catch (e) {
console.log(`[UserService] create > dxCreateUser :>>`, e);
}
return newUser;
}
async update(filter, data, options) {
if (data.username)
data.slug = data.username;
if (data.slug)
data.username = data.slug;
return super.update(filter, data, options);
}
async assignRole(role, user, options) {
// validate
if (!user.activeRole || !user.activeWorkspace)
throw new Error(`Permissions denied.`);
const activeWorkspace = await this.getActiveWorkspace(user);
if (!activeWorkspace)
throw new Error(`Permissions denied.`);
const activeRole = await this.getActiveRole(user);
if (!activeRole || activeRole.type === "member")
throw new Error(`Permissions denied.`);
// remove old roles
const roles = (user.roles || [])
.filter((_role) => mongodb_1.MongoDB.toString(_role.workspace) !== mongodb_1.MongoDB.toString(activeWorkspace._id))
.map((_role) => _role._id);
// push a new role
roles.push(role._id);
// update database
const updateData = { roles };
if (options === null || options === void 0 ? void 0 : options.makeActive)
updateData.activeRole = role;
user = await this.updateOne({ _id: user._id }, { roles });
// return
return { user, role };
}
async assignRoleByRoleID(roleId, user, options) {
const roleSvc = new RoleService_1.RoleService();
const role = await roleSvc.findOne({ _id: roleId });
if (!role)
throw new Error(`Role not found.`);
return this.assignRole(role, user, options);
}
async assignRoleByUserID(role, userId, options) {
const user = await this.findOne({ _id: userId });
if (!user)
throw new Error(`User not found.`);
return this.assignRole(role, user, options);
}
async assignRoleByID(roleId, userId, options) {
const roleSvc = new RoleService_1.RoleService();
const role = await roleSvc.findOne({ _id: roleId });
if (!role)
throw new Error(`Role not found.`);
const user = await this.findOne({ _id: userId });
if (!user)
throw new Error(`User not found.`);
return this.assignRole(role, user, options);
}
async updateAccessPermissions(userSlug, resource) {
// validation
if (!userSlug)
throw new Error(`Param "userSlug" is required.`);
if (!resource)
throw new Error(`Param "resource" is required.`);
// process
const updateData = {};
Object.entries(resource).forEach(([key, val]) => {
let resourceIds = !val ? [] : val.length > 0 && val.indexOf(",") > -1 ? val.split(",") : [val];
resourceIds.map((id) => {
if (!mongodb_1.MongoDB.isValidObjectId(id))
throw new Error(`Invalid "resource" data, "${id}" is not a valid MongoDB ObjectID.`);
return id;
});
updateData[`allowAccess.${key}`] = resourceIds;
});
const updatedUser = this.updateOne({ slug: userSlug }, updateData);
if (!updatedUser)
throw new Error(`Unable to update user's access permissions.`);
// result
return updatedUser;
}
async joinWorkspace(data, options) {
const { userId: uid, workspace: workspaceIdOrSlug } = data;
if (!uid)
throw new Error(`Param "userId" (User ID) is required.`);
if (!workspaceIdOrSlug)
throw new Error(`Param "workspace" (Workspace ID or slug) is required.`);
// parse input params
const userId = uid;
// workspace in query could be "_id" and also "slug":
let workspaceId = mongodb_1.MongoDB.isValidObjectId(workspaceIdOrSlug) || mongodb_1.MongoDB.isObjectId(workspaceIdOrSlug) ? workspaceIdOrSlug : undefined;
// return undefined if can't convert to "ObjectId" -> it's a "slug" !!! (lol)
let workspaceSlug = !workspaceId ? workspaceIdOrSlug : undefined;
if (!workspaceId && !workspaceSlug)
throw new Error(`Param "workspace" (ID or SLUG) is invalid`);
const wsFilter = {};
if (workspaceId)
wsFilter._id = workspaceId;
if (workspaceSlug)
wsFilter.slug = workspaceSlug;
// find the workspace
const { WorkspaceService } = await Promise.resolve().then(() => __importStar(require("./WorkspaceService")));
const workspaceSvc = new WorkspaceService(this.ownership);
const workspace = await workspaceSvc.findOne(wsFilter);
if (!workspace)
throw new Error(`Workspace not found.`);
console.log("workspace", workspace);
if (!workspace.dx_key)
throw new Error(`Workspace is invalid (missing "dx_key").`);
if (!workspace.dx_id)
throw new Error(`Workspace is invalid (missing "dx_id").`);
workspaceId = mongodb_1.MongoDB.toString(workspace._id);
// find the user
let user = await this.findOne({ _id: userId }, { populate: ["roles"] });
if (!user)
throw new Error(`User not found.`);
// console.dir(user, { depth: 10 });
// create user on "dxup.dev" via "dxApi"
if (user.dxUserId) {
try {
const dxUserRes = await (0, dx_user_1.dxCreateUser)({
name: user.name,
username: user.username || user.slug,
email: user.email,
password: user.password,
isActive: true,
});
if (!dxUserRes.status)
throw new Error(dxUserRes.messages.join("\n"));
if (dxUserRes.data.id) {
const userSvc = new UserService(this.ownership);
user = await userSvc.updateOne({ _id: user._id }, { dxUserId: dxUserRes.data.id });
}
}
catch (e) {
console.log(`[WorkspaceService] create > dxCreateUser :>>`, e);
}
}
const wsId = workspaceId;
const workspaceIds = user.workspaces || [];
const isUserInWorkspace = workspaceIds.includes(wsId);
// check if this is a private workspace:
if (!workspace.public) {
// if this user hasn't joined yet:
if (!isUserInWorkspace)
throw new Error(`Missing access to this private workspace, contact workspace admin for an invitation.`);
}
// add this workspace to user's workspace list
if (!isUserInWorkspace)
workspaceIds.push(workspaceId);
// set active workspace of this user -> this workspace
user = await this.updateOne({ _id: userId }, { activeWorkspace: workspaceId, workspaces: workspaceIds }, options);
// set active role
const activeRole = await (0, user_utils_1.getActiveRole)(user, workspace, { makeActive: true, assignMember: true });
user.activeRole = activeRole;
return user;
}
}
exports.UserService = UserService;