Skip to content
Snippets Groups Projects
UserService.ts 11 KiB
Newer Older
Ramiro's avatar
Ramiro committed
import bcrypt from 'bcrypt';
import { Op, where } from 'sequelize';
Ramiro's avatar
Ramiro committed
import { profiles, status } from '../enums/index.enum';
import Paginator from '../interfaces/paginator.interface';
import { User } from '../models/users.model';

import { UserCreateDTO, UserLoginDTO, UserUpdateDTO } from '../DTOs/UserDTO';
Ramiro's avatar
Ramiro committed

const listPending = async (limit: number, offset: number,
  search: string): Promise<Paginator<User>> => {
Ramiro's avatar
Ramiro committed
  let options = {};
  if (limit >= 1 && offset >= 0) {
    if (search && search !== '') {
      options = {
        where: {
          status: status.pending,
          [Op.or]: [
            { name: { [Op.substring]: search } },
            { email: { [Op.substring]: search } },
          ],
        },
        limit,
        offset,
      };
    } else {
      options = {
        where: {
          status: status.pending,
        },
        limit,
        offset,
      };
    }
  }
  return User.findAndCountAll({
    attributes: [
      'id', 'name', 'email', 'organization', 'type', 'status', 'active', 'createdAt',
    ],
    order: [
      ['createdAt', 'ASC'],
    ],
    ...options,
  });
};

const listApproved = async (limit: number, offset: number,
  search: string): Promise<Paginator<User>> => {
  let options = {};
  if (limit >= 1 && offset >= 0) {
    if (search && search !== '') {
      options = {
        where: {
          status: status.approved,
          [Op.or]: [
            { name: { [Op.substring]: search } },
            { email: { [Op.substring]: search } },
          ],
        },
        limit,
        offset,
      };
    } else {
      options = {
        where: {
          status: status.approved,
        },
        limit,
        offset,
      };
    }
  }
  return User.findAndCountAll({
    attributes: [
      'id', 'name', 'email', 'organization', 'type', 'status', 'active', 'createdAt',
    ],
    order: [
      ['createdAt', 'ASC'],
    ],
    ...options,
  });
};

const listClients = async (limit: number, offset: number,
  search: string): Promise<Paginator<User>> => {
  let options = {};
  if (limit >= 1 && offset >= 0) {
    if (search && search !== '') {
      options = {
        where: {
          status: status.approved,
          type: profiles.client,
          [Op.or]: [
            { name: { [Op.substring]: search } },
            { email: { [Op.substring]: search } },
          ],
        },
        limit,
        offset,
      };
    } else {
      options = {
        where: {
          status: status.approved,
          type: profiles.client,
        },
        limit,
        offset,
      };
    }
  }
  return User.findAndCountAll({
    attributes: [
      'id', 'name', 'email', 'organization', 'type', 'status', 'active', 'createdAt',
    ],
    order: [
      ['createdAt', 'ASC'],
    ],
    ...options,
  });
};

const listAdmins = async (limit: number, offset: number,
  search: string): Promise<Paginator<User>> => {
  let options = {};
  if (limit >= 1 && offset >= 0) {
    if (search && search !== '') {
      options = {
        where: {
          status: status.approved,
          type: profiles.administrator,
          [Op.or]: [
            { name: { [Op.substring]: search } },
            { email: { [Op.substring]: search } },
          ],
        },
        limit,
        offset,
      };
    } else {
      options = {
        where: {
          status: status.approved,
          type: profiles.administrator,
        },
        limit,
        offset,
      };
    }
  }
  return User.findAndCountAll({
    attributes: [
      'id', 'name', 'email', 'organization', 'type', 'status', 'active', 'createdAt',
    ],
    order: [
      ['createdAt', 'ASC'],
    ],
    ...options,
  });
};

const listAll = async (limit: number, offset: number): Promise<Paginator<User>> => {
  let options = {};
  if (limit >= 1 && offset >= 0) {
Ramiro's avatar
Ramiro committed
    options = {
      limit,
      offset,
    };
  }
  return User.findAndCountAll({
    attributes: [
Ignacio Otero's avatar
Ignacio Otero committed
      'id', 'name', 'email', 'organization', 'type', 'status', 'active', 'createdAt',
Ramiro's avatar
Ramiro committed
    ],
    order: [
Ignacio Otero's avatar
Ignacio Otero committed
      ['createdAt', 'ASC'],
Ramiro's avatar
Ramiro committed
    ],
    ...options,
  });
};

const create = async (userDTO: UserCreateDTO): Promise<User> => User.findOne({
  where: {
    email: userDTO.email,
  },
}).then(async (user: User) => {
  if (user) {
Ignacio Otero's avatar
Ignacio Otero committed
    throw new Error('email is taken');
Ramiro's avatar
Ramiro committed
  } else {
Ignacio Otero's avatar
Ignacio Otero committed
    // se hace el checkeo antes porque luego se encripta
    if (userDTO.password.length >= 6) {
      const newUser: User = await User.create({
Ramiro's avatar
Ramiro committed
        name: userDTO.name,
        email: userDTO.email,
Ignacio Otero's avatar
Ignacio Otero committed
        organization: userDTO.organization,
        password: bcrypt.hashSync(userDTO.password, 10),
        type: profiles.client,
        status: status.pending,
Ramiro's avatar
Ramiro committed
        createdBy: 1,
        createdAt: new Date(),
      }).catch((error: Error) => {
        console.log(error);
        throw new Error('create user error');
      });
Ignacio Otero's avatar
Ignacio Otero committed
      newUser.toJSON();
      return newUser;
Ramiro's avatar
Ramiro committed
    }
Ignacio Otero's avatar
Ignacio Otero committed
    throw new Error('password too short');
Ramiro's avatar
Ramiro committed
  }
}).catch((error: Error) => {
  console.log(error);
Ignacio Otero's avatar
Ignacio Otero committed
  throw error;
Ramiro's avatar
Ramiro committed
});

const update = async (userId: number, userDTO: UserUpdateDTO): Promise<User> => User.findOne({
Ramiro's avatar
Ramiro committed
  attributes: [
    'id', 'name', 'email',
  ],
  where: {
    id: userId,
  },
}).then(async (user: User) => {
  if (!user) {
    throw new Error('user not found');
Ramiro's avatar
Ramiro committed
  } else if (userDTO.password && userDTO.password.length >= 6) {
    if (userDTO.password === userDTO.repeat) {
Ramiro's avatar
Ramiro committed
      return user.update({
        name: userDTO.name,
Ignacio Otero's avatar
Ignacio Otero committed
        organization: userDTO.organization,
        password: bcrypt.hashSync(userDTO.password, 10),
Ramiro's avatar
Ramiro committed
        updatedAt: new Date(),
      }).catch((error: Error) => {
        console.log(error);
        throw new Error('user update error');
      });
    }
    throw new Error('passwords dont match');
  } else {
    return user.update({
      name: userDTO.name,
      organization: userDTO.organization,
      updatedAt: new Date(),
    }).catch((error: Error) => {
      console.log(error);
      throw new Error('user update error');
    });
Ramiro's avatar
Ramiro committed
  }
}).catch((error: Error) => {
  console.log(error);
  throw new Error('find user error');
});

const password = async (userId: number, userDTO: UserCreateDTO): Promise<User> => User.findOne({
  attributes: [
    'id', 'name', 'email',
  ],
  where: {
    id: userId,
  },
}).then(async (user: User) => {
  if (!user) {
    throw new Error('user not found');
  } else {
Ignacio Otero's avatar
Ignacio Otero committed
    return user.update({
      password: bcrypt.hashSync(userDTO.password, 10),
      updatedAt: new Date(),
    }).catch((error: Error) => {
      console.log(error);
      throw new Error('user update error');
    });
  }
}).catch((error: Error) => {
  console.log(error);
  throw new Error('find user error');
});

const approve = async (userId: number): Promise<User> => User.findOne({
  attributes: [
    'id', 'name',
    'email', 'type',
    'createdAt',
  ],
  where: {
    id: userId,
  },
}).then(async (user: User) => {
  if (!user) {
    throw new Error('user not found');
  } else {
    return user.update({
      status: status.approved,
      updatedAt: new Date(),
    }).catch((error: Error) => {
      console.log(error);
      throw new Error('user update error');
    });
Ramiro's avatar
Ramiro committed
  }
}).catch((error: Error) => {
  console.log(error);
  throw new Error('find user error');
});

Ignacio Otero's avatar
Ignacio Otero committed
const cancel = async (userId: number): Promise<User> => User.findOne({
Ramiro's avatar
Ramiro committed
  attributes: [
    'id', 'name',
    'email', 'type',
    'createdAt',
  ],
  where: {
    id: userId,
  },
}).then(async (user: User) => {
  if (!user) {
    throw new Error('user not found');
  } else {
    return user.update({
Ignacio Otero's avatar
Ignacio Otero committed
      status: status.pending,
      type: profiles.client,
      updatedAt: new Date(),
    }).catch((error: Error) => {
      console.log(error);
      throw new Error('user update error');
    });
  }
}).catch((error: Error) => {
  console.log(error);
  throw new Error('find user error');
});

const giveAdminPermission = async (userId: number): Promise<User> => User.findOne({
  attributes: [
    'id', 'name',
    'email', 'type',
    'createdAt',
  ],
  where: {
    id: userId,
  },
}).then(async (user: User) => {
  if (!user) {
    throw new Error('user not found');
  } else {
    return user.update({
      type: profiles.administrator,
      updatedAt: new Date(),
    }).catch((error: Error) => {
      console.log(error);
      throw new Error('user update error');
    });
  }
}).catch((error: Error) => {
  console.log(error);
  throw new Error('find user error');
});

const removeAdminPermission = async (userId: number): Promise<User> => User.findOne({
  attributes: [
    'id', 'name',
    'email', 'type',
    'createdAt',
  ],
  where: {
    id: userId,
  },
}).then(async (user: User) => {
  if (!user) {
    throw new Error('user not found');
  } else {
    return user.update({
      type: profiles.client,
Ramiro's avatar
Ramiro committed
      updatedAt: new Date(),
    }).catch((error: Error) => {
      console.log(error);
      throw new Error('user update error');
    });
  }
}).catch((error: Error) => {
  console.log(error);
  throw new Error('find user error');
});

const active = async (userId: number): Promise<User> => User.findOne({
  where: {
    id: userId,
  },
}).then(async (user: User) => {
  if (!user) {
    throw new Error('user not found');
  } else {
    return user.update({
      active: !user.get('active'),
      updatedAt: new Date(),
    }).catch((error: Error) => {
      throw new Error('user update error');
    });
  }
}).catch((error: Error) => {
  console.log(error);
  throw new Error('find user error');
});

const login = async (userDTO: UserLoginDTO): Promise<User> => User.findOne({
  attributes: [
    'id', 'name', 'email', 'organization', 'password',
    'type', 'status', 'active', 'createdAt',
  ],
  where: {
    email: userDTO.email,
  },
}).then((user: User) => {
  if (!user) {
    throw new Error('user not found');
  } else if (user.get('status') === status.pending || user.get('active') === false) {
    throw new Error('user not accepted');
  } else if (user && bcrypt.compareSync(userDTO.password, String(user.get('password')))) {
    return user;
  } else {
    throw new Error('auth failed');
  }
}).catch((error: Error) => {
  throw error;
Renzo Beux's avatar
Renzo Beux committed
const listUsersById = async (ids: number[]): Promise<User[]> => {
  const users = User.findAll({
    attributes: [
      'id', 'name', 'email', 'organization', 'type',
    ],
    where: { id: { [Op.in]: ids } },
  });
  return users;
};
const getUser = async (id: number): Promise<User> => User.findOne({
  attributes: ['id', 'name', 'organization'],
  where: {
    id,
    deletedAt: null,
  },
});

Ramiro's avatar
Ramiro committed
export default {
  listAll,
  listPending,
  listApproved,
Ramiro's avatar
Ramiro committed
  create,
  update,
  password,
  approve,
Ignacio Otero's avatar
Ignacio Otero committed
  cancel,
Ramiro's avatar
Ramiro committed
  active,
  giveAdminPermission,
  removeAdminPermission,
Ramiro's avatar
Ramiro committed
};