diff --git a/docs/branding/media/css/restdown.css b/docs/branding/media/css/restdown.css
new file mode 100644
index 0000000..c5477d6
--- /dev/null
+++ b/docs/branding/media/css/restdown.css
@@ -0,0 +1,325 @@
+
+/* ---- general styles */
+
+body {
+ font: 13px "Lucida Grande", "Lucida Sans Unicode", arial, sans-serif;
+ line-height: 1.53846; /* 20px */
+ color: #4a3f2d;
+}
+
+:focus {
+ outline: 0;
+}
+
+h1,h2,h3 {
+ font-weight:normal;
+}
+
+h3{
+ margin-bottom:0;
+}
+
+ul, li {
+ margin:0px;
+ padding:0px;
+}
+
+ul {
+ margin-left:40px;
+}
+
+ul > li {
+ list-style:disc;
+ list-style-position:inside;
+ margin:10px 0px;
+}
+
+hr {
+ border:none;
+ width:98%;
+ margin-left:-10px;
+ border-top:1px solid #CCCCCC;
+ border-bottom:1px solid #FFFFFF;
+}
+
+code,
+pre {
+ border:1px solid #CCCCCC;
+ background:#F2F0EE;
+ -webkit-border-radius:2px;
+ -moz-border-radius:2px;
+ border-radius:2px;
+ white-space:pre-wrap;
+}
+code {
+ padding: 0 0.2em;
+}
+pre {
+ margin: 1em 0;
+ padding: .75em;
+ overflow: auto;
+ padding:10px 1.2em;
+ margin-top:0;
+ margin-bottom:20px;
+}
+pre code {
+ border: medium none;
+ padding: 0;
+}
+a code {
+ text-decoration: underline;
+}
+
+a {
+ color:#FD6512;
+ text-decoration:none;
+}
+
+h4 {
+ font-size: 85%;
+ margin: 0;
+ padding: 0;
+ line-height: 1em;
+ display: inline;
+}
+
+
+
+/* ---- custom classes */
+
+pre.shell,
+pre.shell code {
+ background:#444;
+ color:#fff;
+ border-width:0px;
+}
+pre.shell code::before {
+ content: '$ ';
+ display: inline;
+}
+
+
+/* ---- header and sidebar */
+
+#header {
+ background:#C3BDB3;
+ background:#1C313C;
+ height:66px;
+ left:0px;
+ position:absolute;
+ top:0px;
+ width:100%;
+ z-index:1;
+ font-size:0.7em;
+}
+
+#header h1 {
+ width: 424px;
+ height: 35px;
+ display:block;
+ background: url(../img/logo.svg) no-repeat;
+ line-height:2.1em;
+ padding:0;
+ padding-left:140px;
+ margin-top:18px;
+ margin-left:20px;
+ color:white;
+ text-transform: uppercase;
+}
+
+#sidebar {
+ background-color:#EDEBEA;
+ bottom:0px;
+ left:0px;
+ overflow:auto;
+ padding:20px 0px 0px 15px;
+ position:absolute;
+ top:66px;
+ width:265px;
+ z-index:1;
+}
+
+#content {
+ top:64px;
+ bottom:0px;
+ right:0px;
+ left:290px;
+ padding:20px 30px 400px;
+ position:absolute;
+ overflow:auto;
+ z-index:0;
+}
+
+#sidebar .vertical_divider {
+ background-color:#FFFFFF;
+ bottom:0px;
+ position:absolute;
+ top:0px;
+ right:0px;
+ width:1px;
+}
+
+#sidebar h1 {
+ font-size:1.2em;
+ padding:0px;
+ margin-top:15px;
+ margin-bottom:3px;
+}
+
+#sidebar ul {
+ margin:3px 0 10px 0;
+}
+
+#sidebar ul ul {
+ margin:3px 0 5px 10px;
+}
+
+#sidebar li {
+ margin:0;
+ padding:0;
+ font-size:0.9em;
+}
+
+#sidebar li,
+#sidebar li a {
+ color:#5C5954;
+ list-style:none;
+ padding:1px 0px 1px 2px;
+}
+
+#sidebar li span.verb {
+ color:#aaa;
+ padding:2px 3px 0px;
+ width:30px;
+ display:block;
+ float:left;
+ font-size:9px;
+ font-family:verdana;
+ -moz-border-radius:3px;
+ -webkit-border-radius:3px;
+ margin-left:0px;
+ margin-right:5px;
+}
+
+#sidebar li.current {
+ background-repeat: no-repeat;
+ background-position:right;
+}
+
+
+/* ---- intro */
+
+.intro {
+ color:#29231A;
+ padding: 22px 25px;
+ background: #EDEBEA;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ -o-border-radius: 5px;
+ border-radius: 5px;
+ margin-bottom:40px;
+}
+.intro pre.base {
+ background:#444;
+ color:#29231A;
+ color:#fff;
+ border-color:#fff;
+ font-size:1.5em;
+}
+.intro h1 {
+ color: #1C313C;
+}
+.intro h3 {
+ margin: 5px 0px 3px;
+ font-size: 100%;
+ font-weight: bold;
+}
+.intro ul {
+ list-style-type:disc;
+ padding-left:20px;
+ margin-left:0;
+}
+.intro ul li{
+ margin:0;
+}
+.intro p {
+ padding-left:20px;
+ margin: 5px 0px 3px;
+}
+
+
+
+h2 {
+ overflow: auto;
+ margin-top: 60px;
+ border-top: 2px solid #979592;
+ z-index: 3;
+}
+h1 + h2 {
+ margin-top: 0px;
+}
+
+h2.fixed {
+ position:fixed;
+ margin-top: 0;
+ border-top:none;
+ right:45px;
+ top:66px;
+}
+
+h2 span {
+ background: #979592;
+ float:right;
+ color:#fff;
+ margin:0;
+ margin-left:3px;
+ padding:0.3em 0.7em;
+ font-size: 0.55em;
+ word-spacing: 0.8em; /* separate verb from path */
+ color:#fff;
+}
+
+
+
+
+/*---- print media */
+
+@media print {
+ body { background:white; color:black; margin:0; }
+ #sidebar {
+ display: none;
+ }
+ #content {
+ position: relative;
+ padding: 5px;
+ left: 0px;
+ top: 0px;
+ }
+ h1, h2, h4 {
+ page-break-after: avoid;
+ }
+ pre {
+ page-break-inside: avoid;
+ }
+}
+
+/* tables still need cellspacing="0" in the markup */
+table {
+ border-collapse:collapse; border-spacing:0;
+ margin: 20px 0;
+}
+th,
+td {
+ border: solid #aaa;
+ border-width: 1px 0;
+ line-height: 23px;
+ padding: 0 12px;
+ text-align: left;
+ vertical-align: text-bottom;
+}
+th {
+ border-collapse: separate;
+}
+tbody tr:nth-child(odd) {
+ background-color: #f2f0ee;
+}
diff --git a/docs/branding/media/img/logo.svg b/docs/branding/media/img/logo.svg
new file mode 100644
index 0000000..8246eb8
--- /dev/null
+++ b/docs/branding/media/img/logo.svg
@@ -0,0 +1 @@
+
diff --git a/docs/client.md b/docs/client.md
index 9917e72..75ef783 100644
--- a/docs/client.md
+++ b/docs/client.md
@@ -1,15 +1,12 @@
---
title: Client API | ldapjs
-markdown2extras: wiki-tables
-logo-color: green
-logo-font-family: google:Aldrich, Verdana, sans-serif
-header-font-family: google:Aldrich, Verdana, sans-serif
+markdown2extras: tables
---
# ldapjs Client API
This document covers the ldapjs client API and assumes that you are familiar
-with LDAP. If you're not, read the [guide](http://ldapjs.org/guide.html) first.
+with LDAP. If you're not, read the [guide](guide.html) first.
# Create a client
@@ -25,18 +22,22 @@ that this will not use the LDAP TLS extended operation, but literally an SSL
connection to port 636, as in LDAP v2). The full set of options to create a
client is:
-||url|| a valid LDAP url.||
-||socketPath|| If you're running an LDAP server over a Unix Domain Socket, use this.||
-||log|| You can optionally pass in a bunyan instance the client will use to acquire a logger. The client logs all messages at the `trace` level.||
-||timeout||How long the client should let operations live for before timing out. Default is Infinity.||
-||connectTimeout||How long the client should wait before timing out on TCP connections. Default is up to the OS.||
-||tlsOptions||Additional [options](http://nodejs.org/api/tls.html#tls_tls_connect_port_host_options_callback) passed to the TLS connection layer when connecting via `ldaps://`||
-
+|Attribute |Description |
+|---------------|-----------------------------------------------------------|
+|url |A valid LDAP URL (proto/host/port only) |
+|socketPath |Socket path if using AF\_UNIX sockets |
+|log |Bunyan logger instance (Default: built-in instance) |
+|timeout |How long the client should let operations live for before timing out (Default: Infinity)|
+|connectTimeout |How long the client should wait before timing out on TCP connections (Default: OS default)|
+|tlsOptions |Additional options passed to the TLS connection layer when connecting via `ldaps://` (See: The TLS docs for node.js)|
+|idleTimeout |Seconds after last activity before client emits idle event|
+|strictDN |Force strict DN parsing for client methods (Default is true)|
## Connection management
As LDAP is a stateful protocol (as opposed to HTTP), having connections torn
-down from underneath you is difficult to deal with.
+down from underneath you is can be difficult to deal with. Several mechanisms
+have been provided to mitigate this trouble.
## Common patterns
@@ -49,8 +50,11 @@ Almost every operation has the callback form of `function(err, res)` where err
will be an instance of an `LDAPError` (you can use `instanceof` to switch).
You probably won't need to check the `res` parameter, but it's there if you do.
+
+
+
# bind
-`bind(dn, password, controls,callback)`
+`bind(dn, password, controls, callback)`
Performs a bind operation against the LDAP server.
@@ -166,7 +170,7 @@ server. A couple points with this client API:
* There is no ability to set "keep old dn." It's always going to flag the old
dn to be purged.
-* The client code will automagically figure out if the request is a "new
+* The client code will automatically figure out if the request is a "new
superior" request ("new superior" means move to a different part of the tree,
as opposed to just renaming the leaf).
@@ -192,12 +196,14 @@ Like every other operation, `base` is a DN string.
Options can be a string representing a valid LDAP filter or an object
containing the following fields:
-||scope||One of `base`, `one`, or `sub`. Defaults to `base`.||
-||filter||A string version of an LDAP filter (see below), or a programatically constructed `Filter` object. Defaults to `(objectclass=*)`.||
-||attributes||attributes to select and return (if these are set, the server will return *only* these attributes). Defaults to the empty set, which means all attributes. You can provide a string if you want a single attribute or an array of string for one or many.||
-||attrsOnly||boolean on whether you want the server to only return the names of the attributes, and not their values. Borderline useless. Defaults to false.||
-||sizeLimit||the maximum number of entries to return. Defaults to 0 (unlimited).||
-||timeLimit||the maximum amount of time the server should take in responding, in seconds. Defaults to 10. Lots of servers will ignore this.||
+|Attribute |Description |
+|-----------|---------------------------------------------------|
+|scope |One of `base`, `one`, or `sub`. Defaults to `base`.|
+|filter |A string version of an LDAP filter (see below), or a programatically constructed `Filter` object. Defaults to `(objectclass=*)`.|
+|attributes |attributes to select and return (if these are set, the server will return *only* these attributes). Defaults to the empty set, which means all attributes. You can provide a string if you want a single attribute or an array of string for one or many.|
+|attrsOnly |boolean on whether you want the server to only return the names of the attributes, and not their values. Borderline useless. Defaults to false.|
+|sizeLimit |the maximum number of entries to return. Defaults to 0 (unlimited).|
+|timeLimit |the maximum amount of time the server should take in responding, in seconds. Defaults to 10. Lots of servers will ignore this.|
Responses from the `search` method are an `EventEmitter` where you will get a
notification for each `searchEntry` that comes back from the server. You will
@@ -271,6 +277,24 @@ The `not` character is represented as a `!`, the `or` as a single pipe `|`.
It gets a little bit complicated, but it's actually quite powerful, and lets you
find almost anything you're looking for.
+# starttls
+`starttls(options, controls, callback)`
+
+Attempt to secure existing LDAP connection via STARTTLS.
+
+Example:
+
+ var opts = {
+ ca: [fs.readFileSync('mycacert.pem')]
+ };
+
+ client.starttls(opts, function(err, res) {
+ assert.ifError(err);
+
+ // Client communication now TLS protected
+ });
+
+
# unbind
`unbind(callback)`
diff --git a/docs/dn.md b/docs/dn.md
index ba311ac..de1463e 100644
--- a/docs/dn.md
+++ b/docs/dn.md
@@ -1,15 +1,11 @@
---
title: DN API | ldapjs
-markdown2extras: wiki-tables
-logo-color: green
-logo-font-family: google:Aldrich, Verdana, sans-serif
-header-font-family: google:Aldrich, Verdana, sans-serif
---
# ldapjs DN API
This document covers the ldapjs DN API and assumes that you are familiar
-with LDAP. If you're not, read the [guide](http://ldapjs.org/guide.html) first.
+with LDAP. If you're not, read the [guide](guide.html) first.
DNs are LDAP distinguished names, and are composed of a set of RDNs (relative
distinguished names). [RFC2253](http://www.ietf.org/rfc/rfc2253.txt) has the
@@ -81,6 +77,33 @@ argument. `dn` can be a string or a DN.
Returns a DN object that is the direct parent of `this`. If there is no parent
this can return `null` (e.g. `parseDN('o=example').parent()` will return null).
+
+## format(options)
+
+Convert a DN object to string according to specified formatting options. These
+options are divided into two types. Preservation Options use data recorded
+during parsing to preserve details of the original DN. Modification options
+alter string formatting defaults. Preservation options _always_ take
+precedence over Modification Options.
+
+Preservation Options:
+
+ - `keepOrder`: Order of multi-value RDNs.
+ - `keepQuote`: RDN values which were quoted will remain so.
+ - `keepSpace`: Leading/trailing spaces will be output.
+ - `keepCase`: Parsed attribute name will be output instead of lowercased version.
+
+Modification Options:
+
+- `upperName`: RDN names will be uppercased instead of lowercased.
+- `skipSpace`: Disable trailing space after RDN separators
+
+## setFormat(options)
+
+Sets the default `options` for string formatting when `toString` is called.
+It accepts the same parameters as `format`.
+
+
## toString()
Returns the string representation of `this`.
diff --git a/docs/errors.md b/docs/errors.md
index 554db56..6c6b5ba 100644
--- a/docs/errors.md
+++ b/docs/errors.md
@@ -1,15 +1,11 @@
---
title: Errors API | ldapjs
-markdown2extras: wiki-tables
-logo-color: green
-logo-font-family: google:Aldrich, Verdana, sans-serif
-header-font-family: google:Aldrich, Verdana, sans-serif
---
# ldapjs Errors API
This document covers the ldapjs errors API and assumes that you are familiar
-with LDAP. If you're not, read the [guide](http://ldapjs.org/guide.html) first.
+with LDAP. If you're not, read the [guide](guide.html) first.
All errors in the ldapjs framework extend from an abstract error type called
`LDAPError`. In addition to the properties listed below, all errors will have
diff --git a/docs/examples.md b/docs/examples.md
index b124fc6..71881ef 100644
--- a/docs/examples.md
+++ b/docs/examples.md
@@ -1,9 +1,5 @@
---
title: Examples | ldapjs
-markdown2extras: wiki-tables
-logo-color: green
-logo-font-family: google:Aldrich, Verdana, sans-serif
-header-font-family: google:Aldrich, Verdana, sans-serif
---
# ldapjs Examples
diff --git a/docs/filters.md b/docs/filters.md
index e4a6e0c..c810dc2 100644
--- a/docs/filters.md
+++ b/docs/filters.md
@@ -1,15 +1,11 @@
---
title: Filters API | ldapjs
-markdown2extras: wiki-tables
-logo-color: green
-logo-font-family: google:Aldrich, Verdana, sans-serif
-header-font-family: google:Aldrich, Verdana, sans-serif
---
# ldapjs Filters API
This document covers the ldapjs filters API and assumes that you are familiar
-with LDAP. If you're not, read the [guide](http://ldapjs.org/guide.html) first.
+with LDAP. If you're not, read the [guide](guide.html) first.
LDAP search filters are really the backbone of LDAP search operations, and
ldapjs tries to get you in "easy" with them if your dataset is small, and also
@@ -28,17 +24,6 @@ All Filters in the ldapjs framework extend from `Filter`, which wil have the
property `type` available; this will return a string name for the filter, and
will be one of:
-||equal||an `EqualityFilter`||
-||present||a `PresenceFilter`||
-||substring||a `SubstringFilter`||
-||ge||a `GreaterThanEqualsFilter`||
-||le||a `LessThanEqualsFilter`||
-||and||an `AndFilter`||
-||or||an `OrFilter`||
-||not||a `NotFilter`||
-||approx||an `ApproximateMatchFilter` (quasi-supported in ldapjs)||
-||ext||an `ExtensibleMatchFilter` (not supported in ldapjs)||
-
# parseFilter(filterString)
Parses an [RFC2254](http://www.ietf.org/rfc/rfc2254.txt) filter string into an
diff --git a/docs/guide.md b/docs/guide.md
index afd5fff..6fb056c 100644
--- a/docs/guide.md
+++ b/docs/guide.md
@@ -1,9 +1,6 @@
---
title: LDAP Guide | ldapjs
-markdown2extras: wiki-tables
-logo-color: green
-logo-font-family: google:Aldrich, Verdana, sans-serif
-header-font-family: google:Aldrich, Verdana, sans-serif
+markdown2extras: tables
---
# LDAP Guide
@@ -135,7 +132,7 @@ since we haven't added any support in yet, but go ahead and try it anyway:
$ ldapsearch -H ldap://localhost:1389 -x -b "o=myhost" objectclass=*
Before we go any further, note that the complete code for the server we are
-about to build up is on the [examples](http://ldapjs.org/examples.html) page.
+about to build up is on the [examples](examples.html) page.
## Bind
@@ -237,13 +234,15 @@ for a moment to explain an /etc/passwd record.
The sample record above maps to:
-||jsmith||user name.||
-||x||historically this contained the password hash, but that's usually in /etc/shadow now, so you get an 'x'.||
-||1001||the unix numeric user id.||
-||1000||the unix numeric group id. (primary).||
-||'Joe Smith,...'||the "gecos," which is a description, and is usually a comma separated list of contact details.||
-||/home/jsmith||the user's home directory.||
-||/bin/sh||the user's shell.||
+|Field |Description |
+|-------------------|-----------------------------------|
+|jsmith |Username |
+|x |Placeholder for password hash |
+|1001 |Numeric UID |
+|1000 |Numeric Primary GID |
+|'Joe Smith,...' |DisplayName |
+|/home/jsmith |Home directory |
+|/bin/sh |Shell |
Let's write some handlers to parse that and transform it into an LDAP search
record (note, you'll need to add `var fs = require('fs');` at the top of the
@@ -629,8 +628,8 @@ And then run the following command:
# Where to go from here
The complete source code for this example server is available in
-[examples](/examples.html). Make sure to read up on the [server](/server.html)
-and [client](/client.html) APIs. If you're looking for a "drop in" solution,
+[examples](examples.html). Make sure to read up on the [server](server.html)
+and [client](client.html) APIs. If you're looking for a "drop in" solution,
take a look at [ldapjs-riak](https://github.com/mcavage/node-ldapjs-riak).
[Mozilla](https://wiki.mozilla.org/Mozilla_LDAP_SDK_Programmer%27s_Guide/Understanding_LDAP)
diff --git a/docs/index.md b/docs/index.md
index bd7a0a0..e8c05db 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -1,9 +1,6 @@
---
title: ldapjs
-markdown2extras: wiki-tables
-logo-color: green
-logo-font-family: google:Aldrich, Verdana, sans-serif
-header-font-family: google:Aldrich, Verdana, sans-serif
+markdown2extras: tables
---