text: const Promise = require('bluebird');
  const common = require('../../lib/common');
  const models = require('../../models');
  const permissionsService = require('../../services/permissions');
  const ALLOWED_INCLUDES = ['count.posts', 'permissions', 'roles', 'roles.permissions'];
  const UNSAFE_ATTRS = ['status', 'roles'];
  
  module.exports = {
      docName: 'users',
  
      browse: {
          options: [
              'include',
              'filter',
              'fields',
              'limit',
              'status',
              'order',
              'page',
              'debug'
          ],
          validation: {
              options: {
                  include: {
                      values: ALLOWED_INCLUDES
                  }
              }
          },
          permissions: true,
          query(frame) {
              return models.User.findPage(frame.options);
          }
      },
  
      read: {
          options: [
              'include',
              'filter',
              'fields',
              'debug'
          ],
          data: [
              'id',
              'slug',
              'status',
              'email',
              'role'
          ],
          validation: {
              options: {
                  include: {
                      values: ALLOWED_INCLUDES
                  }
              }
          },
          permissions: true,
          query(frame) {
              return models.User.findOne(frame.data, frame.options)
                  .then((model) => {
                      if (!model) {
                          return Promise.reject(new common.errors.NotFoundError({
                              message: common.i18n.t('errors.api.users.userNotFound')
                          }));
                      }
  
                      return model;
                  });
          }
      },
  
      edit: {
          headers: {
              cacheInvalidate: true
          },
          options: [
              'id',
              'include'
          ],
          validation: {
              options: {
                  include: {
                      values: ALLOWED_INCLUDES
                  },
                  id: {
                      required: true
                  }
              }
          },
          permissions: {
              unsafeAttrs: UNSAFE_ATTRS
          },
          query(frame) {
              return models.User.edit(frame.data.users[0], frame.options)
                  .then((model) => {
                      if (!model) {
                          return Promise.reject(new common.errors.NotFoundError({
                              message: common.i18n.t('errors.api.users.userNotFound')
                          }));
                      }
  
                      return model;
                  });
          }
      },
  
      destroy: {
          statusCode: 204,
          headers: {
              cacheInvalidate: true
          },
          options: [
              'id'
          ],
          validation: {
              options: {
                  id: {
                      required: true
                  }
              }
          },
          permissions: true,
          query(frame) {
              return models.Base.transaction((t) => {
                  frame.options.transacting = t;
  
                  return Promise.all([
                      models.Accesstoken.destroyByUser(frame.options),
                      models.Refreshtoken.destroyByUser(frame.options),
                      models.Post.destroyByAuthor(frame.options)
                  ]).then(() => {
                      return models.User.destroy(Object.assign({status: 'all'}, frame.options));
                  }).return(null);
              }).catch((err) => {
                  return Promise.reject(new common.errors.NoPermissionError({
                      err: err
                  }));
              });
          }
      },
  
      changePassword: {
          validation: {
              docName: 'password',
              data: {
                  newPassword: {required: true},
                  ne2Password: {required: true},
                  oldPassword: {required: true},
                  user_id: {required: true}
              }
          },
          permissions: {
              docName: 'user',
              method: 'edit',
              identifier(frame) {
                  return frame.data.password[0].user_id;
              }
          },
          query(frame) {
              return models.User.changePassword(frame.data.password[0], frame.options);
          }
      },
  
      transferOwnership: {
          permissions(frame) {
              return models.Role.findOne({name: 'Owner'})
                  .then((ownerRole) => {
                      return permissionsService.canThis(frame.options.context).assign.role(ownerRole);
                  });
          },
          query(frame) {
              return models.User.transferOwnership(frame.data.owner[0], frame.options);
          }
      }
  };
  