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
36 changes: 33 additions & 3 deletions src/services/organization/register.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { Resources } from "@tago-io/sdk";
import { DeviceCreateInfo } from "@tago-io/sdk/lib/types";
import { parseTagoObject } from "../../lib/data.logic";
import { getDashboardByTagID } from "../../lib/find-resource";
import { initializeValidation } from "../../lib/validation";
import { EntityData, RouterConstructorEntity } from "../../types";
Expand All @@ -23,7 +21,39 @@ async function installEntity({ new_org_name, new_org_plan_id }: installEntityPar
//structuring data
const entity = {
name: new_org_name,
}
schema: {
user_id: {
type: "string",
required: true,
},
user_name: {
type: "string",
required: true,
},
user_email: {
type: "string",
required: true,
},
user_phone: {
type: "string",
required: false,
},
user_access: {
type: "string",
required: true,
},
user_access_label: {
type: "string",
required: true,
},
},
index: {
user_id_index: {
action: "create",
fields: ["user_id"]
}
}
};

//creating new device
const new_org = await Resources.entities.create(entity);
Expand Down
53 changes: 33 additions & 20 deletions src/services/user/edit.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
import { Resources } from "@tago-io/sdk";
import { UserListScope } from "@tago-io/sdk/lib/modules/Utils/router/router.types";

import { RouterConstructorData } from "../../types";
import { getAccessLabel } from "./register";

async function editOrgUserInfo(user_id: string, userField: string, fieldValue: string, organization_id: string) {
const [userData] = await Resources.entities.getEntityData(organization_id, {
filter: {
user_id: user_id,
},
index: "user_id_index",
amount: 1,
});

if (!userData) {
throw "User does not exist";
}

await Resources.entities.editEntityData(organization_id, {
...userData,
[userField]: fieldValue,
});
}

/**
* Function that edit user information
Expand All @@ -20,38 +39,32 @@ async function userEdit({ scope, environment }: RouterConstructorData & { scope:

const user_id = scope[0].user;

const user_active = scope[0]?.["tags.active"];
const user_name = scope[0]?.name as string;
const user_phone = scope[0]?.phone as string;
const user_access = scope[0]?.["tags.access"] as string;

const user_exists = await Resources.run.userInfo(user_id);
if (!user_exists) {
throw "User does not exist";
}

const new_user_info: any = {};

if (user_active) {
await Resources.run.userEdit(user_id, { active: JSON.parse(user_active) });
const organization_id = user_exists.tags.find((tag) => tag.key === "organization_id")?.value;
if (!organization_id) {
throw "Organization ID not found";
}

if (user_name) {
//fetching prev data
const [user_name_config_dev] = await Resources.devices.getDeviceData(config_id, { variables: "user_name", qty: 1, groups: user_id });

await Resources.devices.editDeviceData(config_id, { ...user_name_config_dev, value: user_name });

new_user_info.name = user_name;
await Resources.run.userEdit(user_id, new_user_info);
await editOrgUserInfo(user_id, "user_name", user_name, organization_id);
await Resources.run.userEdit(user_id, { name: user_name });
}
if (user_phone) {
//fetching prev data
const [user_phone_config_dev] = await Resources.devices.getDeviceData(config_id, { variables: "user_phone", qty: 1, groups: user_id });

await Resources.devices.editDeviceData(config_id, { ...user_phone_config_dev, value: user_phone });

new_user_info.phone = user_phone;
await Resources.run.userEdit(user_id, new_user_info);
await editOrgUserInfo(user_id, "user_phone", user_phone, organization_id);
await Resources.run.userEdit(user_id, { phone: user_phone });
}
if (user_access) {
await editOrgUserInfo(user_id, "user_access", user_access, organization_id);
const user_access_label = getAccessLabel(user_access);
await editOrgUserInfo(user_id, "user_access_label", user_access_label, organization_id);
}
return console.debug("User edited!");
}
Expand Down
155 changes: 102 additions & 53 deletions src/services/user/register.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import { TagsObj } from "@tago-io/sdk/lib/types";
import { parseTagoObject } from "../../lib/data.logic";
import { inviteUser } from "../../lib/register-user";
import { initializeValidation } from "../../lib/validation";
import { RouterConstructorData } from "../../types";

import { EntityData } from "../../types";
import { RouterConstructor } from "@tago-io/sdk/lib/modules/Utils/router/router.types";
import { userModel } from "./user.model";
import { getZodError } from "../../lib/get-zod-error";
interface UserData {
name: string;
email: string;
Expand All @@ -16,6 +18,27 @@ interface UserData {
id?: string;
}

/**
* Determines the display label for a user's access level based on their access type
*
* @param formFields - Object containing user form data
* @param formFields.name - User's full name
* @param formFields.email - User's email address
* @param formFields.access - User's access level, one of: "admin", "orgadmin", or "guest"
* @param formFields.phone - Optional user phone number
* @param user_access_label - Current access label value to be updated
* @returns The display label string for the user's access level
*/
function getAccessLabel(access: string) {
if (access === "admin") {
return "Administrator";
} else if (access === "orgadmin") {
return "Organization Admin";
}

return "Guest";
}

/**
* Function that handle phone number
* @param phone_number Phone number
Expand All @@ -37,6 +60,40 @@ function phoneNumberHandler(phone_number: string) {
return resulted_phone_number;
}

/**
* Retrieves and validates user form fields from the provided data scope.
*
* @param {EntityData[]} scope - An array of data objects containing user form field information
* @returns {Promise<IUser>} A promise that resolves to the validated user data
*
* @throws {ZodError} If validation of the form fields fails
*
* @example
* const scope = [
* { new_user_name: "John Doe" },
* { new_user_email: "john@example.com" },
* { new_user_phone: "+1234567890" },
* { new_user_access: "admin" }
* ];
* const userData = await getFormFields(scope);
*/
async function getFormFields(scope: EntityData[]) {
//Collecting data
const name = scope.find((x) => x.new_user_name)?.new_user_name as string;
const email = scope.find((x) => x.new_user_email)?.new_user_email as string;
const phone = scope.find((x) => x.new_user_phone)?.new_user_phone as string;
const access = scope.find((x) => x.new_user_access)?.new_user_access as string;

const result = await userModel.parseAsync({
name: name,
email: email,
phone: phoneNumberHandler(phone),
access: access,
});

return result;
}

//registered by admin Resources.

/**
Expand All @@ -45,7 +102,7 @@ function phoneNumberHandler(phone_number: string) {
* @param scope Scope is a variable sent by the analysis
* @param environment Environment Variable is a resource to send variables values to the context of your script
*/
async function userAdd({ context, scope, environment }: RouterConstructorData) {
async function userAdd({ context, scope, environment }: RouterConstructor) {
if (!environment || !scope || !context) {
throw new Error("Missing parameters");
}
Expand All @@ -55,37 +112,29 @@ async function userAdd({ context, scope, environment }: RouterConstructorData) {
throw "[Error] No config device ID: config_id.";
}

const org_id = scope[0].device;

//Collecting data
const new_user_name = scope.find((x) => x.variable === "new_user_name" || x.variable === "new_orgadmin_name");
const new_user_email = scope.find((x) => x.variable === "new_user_email" || x.variable === "new_orgadmin_email");
const new_user_access = scope.find((x) => x.variable === "new_user_access" || x.variable === "new_orgadmin_access");
const new_user_phone = scope.find((x) => x.variable === "new_user_phone" || x.variable === "new_orgadmin_phone");
const org_id = scope[0].entity;

//validation
const validate = initializeValidation("user_validation", org_id);

if (!new_user_name?.value) {
throw await validate("Name field is empty", "danger").catch((error) => console.log(error));
}
if ((new_user_name.value as string).length < 3) {
throw await validate("Name field is smaller than 3 character", "danger").catch((error) => console.log(error));
}
if (!new_user_email?.value) {
throw await validate("Email field is empty", "danger").catch((error) => console.log(error));
}
if (!new_user_access?.value) {
throw await validate("Access field is empty", "danger").catch((error) => console.log(error));
}
if (new_user_phone?.value) {
new_user_phone.value = phoneNumberHandler(new_user_phone.value as string);
const validate = initializeValidation("user_validation", config_id);
await validate("#VAL.RESGISTERING#", "warning").catch((error) => console.log(error));

const formFields = await getFormFields(scope)
.catch(getZodError)
.catch(async (error) => {
await validate(error, "danger");
throw error;
});

if (!formFields) {
const error = "Form fields are required.";
await validate(error, "danger").catch((error) => console.log(error));
throw new Error(error);
}

const [user_exists] = await Resources.run.listUsers({
page: 1,
amount: 1,
filter: { email: new_user_email.value as string },
filter: { email: formFields.email },
});

if (user_exists) {
Expand All @@ -97,9 +146,9 @@ async function userAdd({ context, scope, environment }: RouterConstructorData) {
const { timezone } = await resources_with_account_token.account.info();

const new_user_data: UserData = {
name: new_user_name.value as string,
email: (new_user_email.value as string).trim(),
phone: (new_user_phone?.value as string) || "",
name: formFields.name,
email: formFields.email,
phone: formFields.phone,
timezone: timezone,
tags: [
{
Expand All @@ -108,7 +157,7 @@ async function userAdd({ context, scope, environment }: RouterConstructorData) {
},
{
key: "access",
value: new_user_access.value as string,
value: formFields.access,
},
{
key: "active",
Expand All @@ -124,40 +173,40 @@ async function userAdd({ context, scope, environment }: RouterConstructorData) {
throw await validate(error, "danger").catch((error) => console.log(error));
});

let user_access_label: string | undefined = "";
const user_access_label = getAccessLabel(formFields.access);

if (new_user_access.value === "admin") {
user_access_label = "Administrator";
} else if (new_user_access.value === "orgadmin") {
user_access_label = "Organization Admin";
} else if (new_user_access.value === "guest") {
user_access_label = "Guest";
} else {
user_access_label = new_user_access?.metadata?.label;
}
const userDataEntity = {
user_id: new_user_id,
user_name: formFields.name,
user_email: formFields.email,
user_phone: formFields.phone,
user_access: formFields.access,
user_access_label: user_access_label,
};

let user_data = parseTagoObject(
let userData = parseTagoObject(
{
user_id: { value: new_user_id, metadata: { label: `${new_user_name.value} (${new_user_email.value})` } },
user_name: new_user_name.value as string,
user_email: (new_user_email.value as string).trim(),
user_phone: (new_user_phone?.value as string) || "",
user_access: { value: new_user_access.value as string, metadata: { label: user_access_label } },
user_id: new_user_id,
user_name: formFields.name,
user_email: formFields.email,
user_phone: formFields.phone,
user_access: formFields.access,
user_access_label: user_access_label,
},
new_user_id
);

if (new_user_access.value === "admin") {
user_data = user_data.concat([{ variable: "user_admin", value: new_user_id, group: new_user_id, metadata: { label: new_user_name.value as string } }]);
}
// if (new_user_access.value === "admin") {
// user_data = user_data.concat([{ variable: "user_admin", value: new_user_id, group: new_user_id, metadata: { label: new_user_name.value as string } }]);
// }

//sending to org device
await Resources.devices.sendDeviceData(org_id, user_data);
await Resources.entities.sendEntityData(org_id, [userDataEntity]);

//sending to admin device (settings_device)
await Resources.devices.sendDeviceData(config_id, user_data);
await Resources.devices.sendDeviceData(config_id, userData);

return validate("#VAL.USER_SUCCESSFULLY_INVITED_AN_EMAIL_WILL_BE_SENT_WITH_THE_CREDENTIALS_TO_THE_NEW_USER#", "success");
}

export { userAdd };
export { userAdd, getAccessLabel };
Loading