npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

zimbra-admin-api-js

v0.3.15

Published

## Table of Contents - [Example](#example) - [Install](#install) - [Callback](#callback) - [Errors](#errors) - [Zimbra Resources](#zimbra-resources) - [Common Functions](#common-functions) - [Server Operations](#server-operations) - [Batch Request Functio

Downloads

66

Readme

Zimbra Admin Api Javascript

Table of Contents

Example

First, instantiate the wrapper.

As an Admin Account

var client = new ZimbraAdminApi({
  'url': 'http://zimbra.zboxapp.dev:8000/service/admin/soap',
  'user': '[email protected]',
  'password':'12345678'
});

var callback = function(err, data) {
  if (err) return console.log(err);
  console.log(data);
};

client.getAllDomains(callback);

ZimbraAdminApi.version();
// "version"

As a Normal Account

You must use the correct url.

var client = new ZimbraAdminApi({
  'url': 'http://zimbra.zboxapp.dev:8000/service/soap',
  'user': '[email protected]',
  'password':'12345678',
  'isAdmin': false
});

Install

$ npm install --save zimbra-admin-api-js

Callback

You have to pass a callback to all the functions, that receives to params:

  1. error, if any
  2. data, if any

For this documentations callback will always be:

function(err, data) {
  if (err) return console.log(err);
  console.log(data);
};

Errors

If Zimbra returns an Error, the library returns an Error Object with the Zimbra Error information. For example, if you look for a non existing Domain:

client.getDomain('example.com', callback);

// Error: {status: 500, title: "Internal Server Error", extra: Object}
// Error.extra: {
//   code: "account.NO_SUCH_DOMAIN",
//   reason: "no such domain: example.com"
// }

Zimbra Resources

Zimbra Resources are the things you can manage, like:

  • Accounts, the email users,
  • Domains,
  • Distribution Lists,
  • CoS, Class of services
  • Servers, Zimbra servers

Common Functions

This are similar functions that you can call for all the Resources, so we grouped here for brevity:

Get a Resource

You can use the resource name or zimbraId:

client.getAccount('[email protected]', callback);
// Account {name: "[email protected]", id: "eda93f93-ba26-4344-8ae0-1d03964b612a", attrs: Object}

client.getAccount('eda93f93-ba26-4344-8ae0-1d03964b612a', callback);
// Account {name: "[email protected]", id: "eda93f93-ba26-4344-8ae0-1d03964b612a", attrs: Object}


client.getDomain('domain.com', callback);
// Domain {name: "domain.com", id: "cc0fd82b-7833-4de2-8954-88eb97fb81e9", attrs: Object}

client.getDistributionList('[email protected]', callback);
// DistributionList {name: "[email protected]", id: "747972ab-a410-4f17-8d5e-db7be21d75e9", attrs: Object, members: Array[4]}

A successful response will always return a Object named after the Resource your are requesting.

GetAll and Search

You have the following functions:

  • getAllAccounts(query_object, callback),
  • getAllDomains(query_object, callback),
  • getAllDistributionLists(query_object, callback),

query_object is an optional Object that accept the following attributes:

  • query: An LDAP query or null for everything,
  • maxResults: Maximum results that the backend will attempt to fetch from the directory before returning an account.TOO_MANY_SEARCH_RESULTS error.,
  • limit: the maximum number of accounts to return ,
  • offset: The starting offset (0, 25, etc),
  • domain: The domain name to limit the search to,
  • sortBy: Name of attribute to sort on. Default is the account name.,
  • sortAscending: Whether to sort in ascending order. Default is 1 (true)
  • countOnly: Whether response should be count only. Default is 0 (false),
  • attrs: Comma separated list of attributes to ask for

Result as Object

If you need to get the result as an Object with the resource id or name as the Key of the object you need to initialize the Api like this:

var client = new ZimbraAdminApi({
  'url': 'http://zimbra.zboxapp.dev:8000/service/admin/soap',
  'user': '[email protected]',
  'password':'12345678',
  'arrayAsObject': true,
  'arrayAsObjectKey': 'name' // By default is 'id';
});

var callback = function(err, data) {
  if (err) return console.log(err);
  console.log(data);
};

client.getAllDomains(callback);
// Object {total: 261, more: false, domain: Object} <== Object!!

Examples

1. Get All Accounts without a query_object
client.getAllAccounts(callback);
// Object {total: 261, more: false, account: Array[261]}

The Result Object has the following information:

  • total: The total quantity of resources that you request can return,
  • account, An array with all the Accounts objects,
  • more: true if there are more results that.
2. Get All Accounts with limit and offset

This is useful if you are doing pagination.

var query_object = { limit: 10, offset: 2 }
client.getAllAccounts(callback);
// Object {total: 261, more: true, account: Array[10]}
3. Get All DistributionList for the example.com Domain
var query_object = { domain: 'example.com' }
client.getAllDistributionLists(query_object, callback);
// Object {total: 6, more: false, dl: Array[6]}
4. Get All Accounts with an email containing 'basic'
var query_object = { query: 'mail=*basic*' }
client.getAllAccounts(query_object, callback);
// Object {total: 29, more: false, account: Array[29]}

Server Operations

Backup

Do a backup <account> elements are required when method=full and server is running in standard backup mode. If server is running in auto-grouped backup mode, omit the account list in full backup request to trigger auto-grouped backup. If account list is specified, only those accounts will be backed up.

Full documentation: https://files.zimbra.com/docs/soap_api/8.7.0/api-reference/zimbraAdmin/Backup.html

The first param is the Mailbox Server. You need direct access to the 7071 port on this server.

const backupRequest = {blobs: 'exclude', secondaryBlobs: 'exclude', searchIndex: 'exclude'};
const accounts = ['[email protected]', '[email protected]'];
api.backup("localhost", backupRequest, null, accounts, callback);
// {label: "full-20160830.222823.315"}

Get All Volumes

Get All Volumes from the server. This link has full documentation

The server param is the hostname or ip address of the Mailbox Server. You need direct access to the 7071 port on this server.

api.getAllVolumes("localhost", callback);
// { message1:
//    { id: 1,
//      name: 'message1',
//      type: 1,
//      compressBlobs: false,
//      compressionThreshold: 4096,
//      mgbits: 8,
//      mbits: 12,
//      fgbits: 8,
//      fbits: 12,
//      rootpath: '/opt/zimbra/store',
//      isCurrent: true },
//   index1:
//    { id: 2,
//      name: 'index1',
//      type: 10,
//      compressBlobs: false,
//      compressionThreshold: 4096,
//      mgbits: 8,
//      mbits: 12,
//      fgbits: 8,
//      fbits: 12,
//      rootpath: '/opt/zimbra/index',
//      isCurrent: true },
// }

Move Blobs

Moves blobs between volumes. Unlike HsmRequest, this request is synchronous, and reads parameters from the request attributes instead of zimbraHsmPolicy.

Takes the following parameters:

  • server, IP or hostname of the mailbox server. You need direct access to the 7071 port on this server,
  • request_object, Object with attributes to make the request.

The request_object has the following attributes:

  • types: Comma separated list of search types. Legal values are: conversation|message|contact|appointment|task|wiki|document,
  • sourceVolumeIds: A comma separated list of source volume IDs
  • destVolumeId: Destination volume ID
  • maxBytes: Limit for the total number of bytes of data to move. Blob move will abort if this threshold is exceeded.
  • query: An optional query to move only Blobs that match this query. For query syntax check this documentation.
const request_object = {
  types: 'all', sourceVolumeIds: '1',
  destVolumeId: '3', maxBytes: 100000
};
api.moveBlobs("192.168.0.272", request_object, callback);
// {
//  numBlobsMoved: 0,
//  numBytesMoved: 0,
//  totalMailboxes: 376
// }

Batch Request Functions

With BatchRequest you can ask Zimbra to run multiple requests in just one call, and get the result in just one answer.

Every function here works for BatchRequest if you do not pass a callback. For example:

var allAccounts = client.getAllAccounts();
var allDomains = client.getAllDomains();
client.makeBatchRequest([allAccounts, allDomains], callback);
// Object {SearchDirectoryResponse: Array[2], _jsns: "urn:zimbra"}
// SearchDirectoryResponse[0].account, SearchDirectoryResponse[1].domain

client.makeBatchRequest([allAccounts, allDomains], callback, {onError: 'continue'});
// By default is {onError: 'stop'}

Count Accounts for several Domains

Pass an array of domains ids or names and you get back an array of countAccounts responses objects. The response arrays has the same order of the request array:

var domains = ['zboxapp.com', 'example.com', 'zboxnow.com'];
client.batchCountAccounts(domains, callback);
// [Object, Object];

Creating Resources

The methods are:

  • createAccount('email_address', password, zimbra_attributes, callback),
  • createDomain('domain_name', zimbra_attributes, callback),
  • createDistributionList('email_address', zimbra_attributes, callback)

Examples

1. Create an account

Always have to pass an email_address and a password:

var zimbra_attributes = {};
client.createAccount('[email protected]', 'SuP3rS3cur3P4ss', zimbra_attributes, callback);
// Account {name: "[email protected]", id: "1919c856-08cc-43c9-b927-0c4cf88f50c7", attrs: Object}

We are making zimbra_attributes and empty object, because we are not passing any attributes. If everything goes OK you get the created Object as a result.

2. Create an account with a invalid Email Address

Check the space between user and [email protected]

var zimbra_attributes = {};
client.createAccount('user [email protected]', 'SuP3rS3cur3P4ss', zimbra_attributes, callback);
// Error {status: 500, title: "Internal Server Error", extra: Object}
// Error.extra {
//  code: "service.INVALID_REQUEST",
//  reason: "invalid request: invalid email address"
// }

You get an Error Object with the reason of the failure.

3. Create an Account with some attributes

zimbra_attributes must be an Object, that can be empty, that should have valid Zimbra attributes for the Resource being created.

In this example we are creating an account with the following attributes:

  • First Name (givenName),
  • Last Name (sn), and
  • A Mail Quota of 50GB (zimbraMailQuota)
var zimbra_attributes = {
  givenName: 'John',
  sn: 'Smith',
  zimbraMailQuota: 53687091200
}
client.createAccount('[email protected]', 'SuP3rS3cur3P4ss', zimbra_attributes, callback);
// Account {name: "[email protected]", id: "1919c856-08cc-43c9-b927-0c4cf88f50c7", attrs: Object}

Modify Resources

For updating resources you have to use the ZimbraId

  • modifyAccount(zimbra_id, attributes, callback),
  • modifyDomain(zimbra_id, attributes, callback),
  • modifyDistributionList(zimbra_id, attributes, callback)

For example:

// Attributes to modify
var zimbra_attributes = {
  givenName: 'Tom',
  sn: 'Hanks'
}

// [email protected]
var zimbraId = "1919c856-08cc-43c9-b927-0c4cf88f50c7";

client.modifyAccount(zimbraId, zimbra_attributes, callback);
// Account {name: "[email protected]", id: "1919c856-08cc-43c9-b927-0c4cf88f50c7", attrs: Object}
// attrs.sn = 'Hanks'
// attrs.givenName = 'Tom'

Remove Resources

For deleting resources you have to use the ZimbraId

  • removeAccount(zimbra_id, callback),
  • removeDomain(zimbra_id, callback),
  • removeDistributionList(zimbra_id, callback)

For example:

// [email protected]
var zimbraId = "1919c856-08cc-43c9-b927-0c4cf88f50c7";
client.removeAccount(zimbraId, callback);
  • If everything goes OK you receive nothing as result.
  • You can't delete a Domain that is not empty. If it has any Account or DistributionList, You have to delete those first.

Accounts

Set Password

account.setPassword(password, callback);
// {} if OK
// Error if not OK

Enable and Disable Archive

Only Zimbra Network Edition

You must pass a COS Name or CosID as firt params

account.enableArchiving('default', callback);
// Account {}
// account.archiveEnabled === true;

account.disableArchiving(callback);
// Account {}
// account.archiveEnabled === false;

Get Account Membership

Get distribution lists an account is a member of.

client.getAccountMembership(account, callback);
// [DistributionList, DistributionList, ...]

// Or as a method of the account
account.getAccountMembership(callback);
// [DistributionList, DistributionList, ...]

Get Mailbox

account.getMailbox(callback);
// Object { mbxid: Mailbox ID, size: Quota Used}
//

Get Mailbox Size

account.getMailboxSize(callback);
// Returns a Integer represeting Bytes
//

Rename

account.rename('[email protected]', callback);
// account Object

Account Alias

The alias must be an email with Domain in Zimbra.

account.addAccountAlias(alias, callback);
// Empty {} if everything goes Ok

account.removeAccountAlias(alias, callback);
// Empty {} if everything goes Ok

View Mail Path

This return an URL PATH to access the account Webmail as an administrator. The first parameter is the lifetime of the Token in seconds.

client.getAccountViewMailPath(account.name, 3600, callback);
// OR
account.viewMailPath(3600, callback);
// /service/preauth?authtoken=0_8c671f3146....&isredirect=1&adminPreAuth=1

Cos Name

The account only has the Id of the Cos, zimbraCOSId, but not the name. To get the name you call zimbraCosName on the Account:

// account is a Account, you got it from client.getAccount....
account.cosName(callback);
// professional

// An account without Cos
no_cos_account.cosName(callback);
// null

Cos

This are functions especifics to Cos.

Get All Cos

client.getAllCos(callback);

Create / Delete Cos

To create a Cos

//Simple, without attributes
var attributes = {};
client.createCos("cos_name", attributes, callback);
// With attributes
var attributes = {'zimbraFeatureContactsEnabled' : 'FALSE'};
client.createCos("cos_name", attributes, callback)

To delete a Cos

client.deleteCos("cos_Id", callback)

Get Cos

client.getCos(name|id, callback);

Modify Cos

var attributes = {'zimbraDumpsterEnabled' : 'TRUE'};
client.modifyCos("cos_Id", attributes, callback);

Rename Cos

var newName = "basicv2"
client.renameCos("cos_Id", newName, callback);

Copy Cos

To copy a Cos with other name

var newCos = "Pro2";
client.copyCos(nameCos|idCos, newCos, callback);

Domains

This are functions especifics to Domains.

isAliasDomain & masterDomainName

These are properties, not functions.

  • isAliasDomain, return if a Domain is an Alias Domain.
  • masterDomainName, return the name of the master domain.
domain.isAliasDomain
// true || false

domain.masterDomainName
// example.com

Count Accounts

Count number of accounts by CoS in a domain.

client.countAccounts('example.com', callback);

// Object { premium: Object, professional: Object}
// premium: {
//   id: _COSId_,
//   used: 50
// }
}

If you have a Domain you can call countAccounts(callback) on it and it will returns the Limit of Accounts for the Domain:

// domain is a Domain, you got it from client.getDomain....
domain.countAccounts(callback);
// Object { premium: Object, professional: Object}
// premium: {
//   id: _COSId_,
//   used: 50,
//   limit: 28
// }
}

If the Domain is empty, no 'Accounts', the result will be a {}.

CheckDomainMXRecord

client.checkDomainMxRecord(domain.name, callback);
// OR
domain.checkMxRecord(callback);
// Object {entry: "5 mailcleaner.zboxapp.com.", code: "Failed",
// message: "Domain is configured to use SMTP host: zimbra.zboxapp.dev. None of the MX records match this name."}

Add / Remove Admin

To add or remove a Domain Admin you must use the account.id. You should also specify the coses the Domain Admin can assign to the accounts of his domains.

const coses = ['default', 'test', 'professional'];
api.addDomainAdmin(domain.name, account.id, coses, callback);
// OR
domain.addAdmin(account.id, coses, callback);
// {} if Success

api.removeDomainAdmin(domain.name, account.id, coses, callback);
// OR
domain.removeAdmin(account.id, coses, callback);
// {} if Success

Domain Admins

Return an Array of the Domain Admins Accounts.

// domain is a Domain, you got it from client.getDomain....
api.getDomainAdmins(domain.name, callback);
// OR
domain.getAdmins(callback);
// [Account, Account]

Distribution Lists

Return an Array of the Domain DistributionLists.

// domain is a Domain, you got it from client.getDomain....
domain.getAllDistributionLists(callback);
// [DistributionList, DistributionList]

Distribution Lists

Rename

dl.rename('[email protected]', callback);
// dl Object

Add / Remove Members

dl.addMembers('[email protected]', callback);
// {} if Success

dl.addMembers(['[email protected]', '[email protected]'], callback);

dl.removeMembers('[email protected]', callback);
// {} if Success

dl.removeMembers(['[email protected]', '[email protected]'], callback);
// Return Error if any of the emails isn't a member

Add / Remove Owner

client.addDistributionListOwner(dl.name, '[email protected]', callback);
// OR
dl.addOwner('[email protected]', callback);
// {} if Success

client.removeDistributionListOwner(dl.name, '[email protected]', callback);
// OR
dl.removeOwner('[email protected]', callback);
// {} if Success

Get Owners

Owners are the Zimbra emails addresses that are allowed to send emails to the DL. If a DL has at least one Owener is a Private DL.

client.getDistributionListOwners(dl.name, callback);
// OR
dl.getOwners(callback);
// Array of Objects
// {name: 'email_address', id: 'ZimbraId', type: 'usr|grp'}

Add / Remove Alias

To set alias at DL .

client.addDistributionListAlias(dl.id, alias, callback);

To delete alias of DL.

api.removeDistributionListAlias(dl.id, alias, callback);

Contributing

  1. Fork the repo on GitHub
  2. Clone the project to your own machine
  3. Commit changes to your own branch
  4. Push your work back up to your fork
  5. Submit a Pull request so that we can review your changes

NOTE: Be sure to merge the latest from "upstream" before making a pull request!

Developer Machine

This repo include a Vagrantfile that setups a VM ready for development. This VM provision a Zimbra server with all the resources needed. So you need to install Vagrant if you haven't.

Also you need to install Ansible because we use it to provision the VM.

Once you have everything in place just run:

$ vagrant up
$ vagrant provision

And wait for it to finish.

Test

You must write test for every feature that you add, otherwise we wont accept your Pull Request.

We are using Mocha and Chai for testing. To run the test just execute:

$ npm run test

Also we have Travis-CI that run the test for every Pull Request.