diff --git a/README.md b/README.md
index 4092473..f57a431 100644
--- a/README.md
+++ b/README.md
@@ -150,6 +150,8 @@ NOTE: The test suite requires an active kerberos deployment.
GSS_MECH_OID_SPNEGO
+version
+
## Functions
@@ -295,6 +297,9 @@ Processes a single kerberos server-side step using the supplied client data.
## GSS_MECH_OID_SPNEGO
+
+
+## version
## checkPassword(username, password, service, [defaultRealm])
diff --git a/lib/index.js b/lib/index.js
index d3b3fd2..6ba3cbf 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -1,11 +1,250 @@
'use strict';
-const kerberos = require('./kerberos');
+const { promisify } = require('util');
+const { loadBindings } = require('./util');
-// Get the Kerberos library
-module.exports = kerberos;
+const kerberos = loadBindings();
+const KerberosClient = kerberos.KerberosClient;
+const KerberosServer = kerberos.KerberosServer;
-// Support legacy versions of the mongodb driver which expect this export
-module.exports.Kerberos = kerberos;
+// GSS Flags
+/** @kind constant */
+const GSS_C_DELEG_FLAG = 1;
+/** @kind constant */
+const GSS_C_MUTUAL_FLAG = 2;
+/** @kind constant */
+const GSS_C_REPLAY_FLAG = 4;
+/** @kind constant */
+const GSS_C_SEQUENCE_FLAG = 8;
+/** @kind constant */
+const GSS_C_CONF_FLAG = 16;
+/** @kind constant */
+const GSS_C_INTEG_FLAG = 32;
+/** @kind constant */
+const GSS_C_ANON_FLAG = 64;
+/** @kind constant */
+const GSS_C_PROT_READY_FLAG = 128;
+/** @kind constant */
+const GSS_C_TRANS_FLAG = 256;
-module.exports.version = require('../package.json').version;
+// GSS_OID
+/** @kind constant */
+const GSS_C_NO_OID = 0;
+/** @kind constant */
+const GSS_MECH_OID_KRB5 = 9;
+/** @kind constant */
+const GSS_MECH_OID_SPNEGO = 6;
+
+/** @kind constant */
+const version = require('../package.json').version;
+
+/**
+ * @class KerberosClient
+ *
+ * @property {string} username The username used for authentication
+ * @property {string} response The last response received during authentication steps
+ * @property {string} responseConf Indicates whether confidentiality was applied or not (GSSAPI only)
+ * @property {boolean} contextComplete Indicates that authentication has successfully completed or not
+ */
+
+const promisifiedStep = promisify(KerberosClient.prototype.step);
+/**
+ * Processes a single kerberos client-side step using the supplied server challenge.
+ *
+ * @kind function
+ * @memberof KerberosClient
+ * @param {string} challenge A string containing the base64-encoded server data (which may be empty for the first step)
+ * @return {Promise}
+ */
+KerberosClient.prototype.step = async function step(challenge) {
+ if (typeof challenge !== 'string') {
+ throw new TypeError('parameter `challenge` must be a string.');
+ }
+ return await promisifiedStep.call(this, challenge);
+};
+
+const promsifiedWrap = promisify(KerberosClient.prototype.wrap);
+/**
+ * Perform the client side kerberos wrap step.
+ *
+ * @kind function
+ * @memberof KerberosClient
+ * @param {string} challenge The response returned after calling `unwrap`
+ * @param {object} [options] Options
+ * @param {string} [options.user] The user to authorize
+ * @param {boolean} [options.protect] Indicates if the wrap should request message confidentiality
+ * @return {Promise}
+ */
+KerberosClient.prototype.wrap = async function wrap(challenge, options = {}) {
+ if (typeof challenge !== 'string') {
+ throw new TypeError('parameter `challenge` must be a string.');
+ }
+
+ return await promsifiedWrap.call(this, challenge, options);
+};
+
+const promisifiedUnwrap = promisify(KerberosClient.prototype.unwrap);
+/**
+ * Perform the client side kerberos unwrap step
+ *
+ * @kind function
+ * @memberof KerberosClient
+ * @param {string} challenge A string containing the base64-encoded server data
+ * @return {Promise}
+ */
+KerberosClient.prototype.unwrap = async function unwrap(challenge) {
+ if (typeof challenge !== 'string') {
+ throw new TypeError('parameter `challenge` must be a string.');
+ }
+ return await promisifiedUnwrap.call(this, challenge);
+};
+
+const promisifiedServerStep = promisify(KerberosServer.prototype.step);
+/**
+ * @class KerberosServer
+ *
+ * @property {string} username The username used for authentication
+ * @property {string} response The last response received during authentication steps
+ * @property {string} targetName The target used for authentication
+ * @property {boolean} contextComplete Indicates that authentication has successfully completed or not
+ */
+
+/**
+ * Processes a single kerberos server-side step using the supplied client data.
+ *
+ * @kind function
+ * @memberof KerberosServer
+ * @param {string} challenge A string containing the base64-encoded client data
+ * @return {Promise}
+ */
+KerberosServer.prototype.step = async function step(challenge) {
+ if (typeof challenge !== 'string') {
+ throw new TypeError('parameter `challenge` must be a string.');
+ }
+ return await promisifiedServerStep.call(this, challenge);
+};
+
+const promisifiedCheckPassword = promisify(kerberos.checkPassword);
+
+/**
+ * This function provides a simple way to verify that a user name and password
+ * match those normally used for Kerberos authentication.
+ * It does this by checking that the supplied user name and password can be
+ * used to get a ticket for the supplied service.
+ * If the user name does not contain a realm, then the default realm supplied
+ * is used.
+ *
+ * For this to work properly the Kerberos must be configured properly on this
+ * machine.
+ * That will likely mean ensuring that the edu.mit.Kerberos preference file
+ * has the correct realms and KDCs listed.
+ *
+ * IMPORTANT: This method is vulnerable to KDC spoofing attacks and it should
+ * only be used for testing. Do not use this in any production system - your
+ * security could be compromised if you do.
+ *
+ * @kind function
+ * @param {string} username The Kerberos user name. If no realm is supplied, then the `defaultRealm` will be used.
+ * @param {string} password The password for the user.
+ * @param {string} service The Kerberos service to check access for.
+ * @param {string} [defaultRealm] The default realm to use if one is not supplied in the user argument.
+ * @return {Promise} returns Promise that rejects if the password is invalid
+ */
+async function checkPassword(username, password, service, defaultRealm) {
+ if (typeof username !== 'string') {
+ throw new TypeError('parameter `username` must be a string.');
+ }
+ if (typeof password !== 'string') {
+ throw new TypeError('parameter `password` must be a string.');
+ }
+ if (typeof service !== 'string') {
+ throw new TypeError('parameter `service` must be a string.');
+ }
+ if (defaultRealm && typeof defaultRealm !== 'string') {
+ throw new TypeError('if specified, parameter `defaultRealm` must be a string.');
+ }
+ return await promisifiedCheckPassword.call(this, username, password, service, defaultRealm);
+}
+
+const promisifiedPrincipalDetails = promisify(kerberos.principalDetails);
+/**
+ * This function returns the service principal for the server given a service type and hostname.
+ *
+ * Details are looked up via the `/etc/keytab` file.
+ *
+ * @kind function
+ * @param {string} service The Kerberos service type for the server.
+ * @param {string} hostname The hostname of the server.
+ * @return {Promise} returns Promise
+ */
+async function principalDetails(service, hostname) {
+ if (typeof service !== 'string') {
+ throw new TypeError('parameter `service` must be a string.');
+ }
+ if (typeof hostname !== 'string') {
+ throw new TypeError('parameter `hostname` must be a string.');
+ }
+ return await promisifiedPrincipalDetails.call(this, service, hostname);
+}
+
+const promisifiedInitializeClient = promisify(kerberos.initializeClient);
+/**
+ * Initializes a context for client-side authentication with the given service principal.
+ *
+ * @kind function
+ * @param {string} service A string containing the service principal in the form 'type@fqdn' (e.g. 'imap@mail.apple.com').
+ * @param {object} [options] Optional settings
+ * @param {string} [options.principal] Optional string containing the client principal in the form 'user@realm' (e.g. 'jdoe@example.com').
+ * @param {number} [options.flags] Optional integer used to set GSS flags. (e.g. `GSS_C_DELEG_FLAG\|GSS_C_MUTUAL_FLAG\|GSS_C_SEQUENCE_FLAG` will allow for forwarding credentials to the remote host)
+ * @param {number} [options.mechOID] Optional GSS mech OID. Defaults to None (GSS_C_NO_OID). Other possible values are `GSS_MECH_OID_KRB5`, `GSS_MECH_OID_SPNEGO`.
+ * @param {string} [options.user] The username with which to authenticate. Only used on Windows.
+ * @param {string} [options.pass] The password with which to authenticate. Only used on Windows.
+ * @return {Promise} returns Promise
+ */
+async function initializeClient(service, options = { mechOID: GSS_C_NO_OID }) {
+ if (typeof service !== 'string') {
+ throw new TypeError('parameter `service` must be a string.');
+ }
+ return await promisifiedInitializeClient.call(this, service, options);
+}
+
+const promisifiedInitializeServer = promisify(kerberos.initializeServer);
+
+/**
+ * Initializes a context for server-side authentication with the given service principal.
+ *
+ * @kind function
+ * @param {string} service A string containing the service principal in the form 'type@fqdn' (e.g. 'imap@mail.apple.com').
+ * @return {Promise} returns Promise
+ */
+async function initializeServer(service) {
+ if (typeof service !== 'string') {
+ throw new TypeError('parameter `service` must be a string.');
+ }
+ return await promisifiedInitializeServer.call(this, service);
+}
+
+module.exports = {
+ initializeClient,
+ initializeServer,
+ principalDetails,
+ checkPassword,
+
+ // gss flags
+ GSS_C_DELEG_FLAG,
+ GSS_C_MUTUAL_FLAG,
+ GSS_C_REPLAY_FLAG,
+ GSS_C_SEQUENCE_FLAG,
+ GSS_C_CONF_FLAG,
+ GSS_C_INTEG_FLAG,
+ GSS_C_ANON_FLAG,
+ GSS_C_PROT_READY_FLAG,
+ GSS_C_TRANS_FLAG,
+ GSS_C_NO_OID,
+
+ // mechanism OIDs
+ GSS_MECH_OID_KRB5,
+ GSS_MECH_OID_SPNEGO,
+
+ version
+};
diff --git a/lib/kerberos.js b/lib/kerberos.js
deleted file mode 100644
index 316f013..0000000
--- a/lib/kerberos.js
+++ /dev/null
@@ -1,245 +0,0 @@
-'use strict';
-
-const { promisify } = require('util');
-const { loadBindings } = require('./util');
-
-const kerberos = loadBindings();
-const KerberosClient = kerberos.KerberosClient;
-const KerberosServer = kerberos.KerberosServer;
-
-// GSS Flags
-/** @kind constant */
-const GSS_C_DELEG_FLAG = 1;
-/** @kind constant */
-const GSS_C_MUTUAL_FLAG = 2;
-/** @kind constant */
-const GSS_C_REPLAY_FLAG = 4;
-/** @kind constant */
-const GSS_C_SEQUENCE_FLAG = 8;
-/** @kind constant */
-const GSS_C_CONF_FLAG = 16;
-/** @kind constant */
-const GSS_C_INTEG_FLAG = 32;
-/** @kind constant */
-const GSS_C_ANON_FLAG = 64;
-/** @kind constant */
-const GSS_C_PROT_READY_FLAG = 128;
-/** @kind constant */
-const GSS_C_TRANS_FLAG = 256;
-
-// GSS_OID
-/** @kind constant */
-const GSS_C_NO_OID = 0;
-/** @kind constant */
-const GSS_MECH_OID_KRB5 = 9;
-/** @kind constant */
-const GSS_MECH_OID_SPNEGO = 6;
-
-/**
- * @class KerberosClient
- *
- * @property {string} username The username used for authentication
- * @property {string} response The last response received during authentication steps
- * @property {string} responseConf Indicates whether confidentiality was applied or not (GSSAPI only)
- * @property {boolean} contextComplete Indicates that authentication has successfully completed or not
- */
-
-const promisifiedStep = promisify(KerberosClient.prototype.step);
-/**
- * Processes a single kerberos client-side step using the supplied server challenge.
- *
- * @kind function
- * @memberof KerberosClient
- * @param {string} challenge A string containing the base64-encoded server data (which may be empty for the first step)
- * @return {Promise}
- */
-KerberosClient.prototype.step = async function step(challenge) {
- if (typeof challenge !== 'string') {
- throw new TypeError('parameter `challenge` must be a string.');
- }
- return await promisifiedStep.call(this, challenge);
-};
-
-const promsifiedWrap = promisify(KerberosClient.prototype.wrap);
-/**
- * Perform the client side kerberos wrap step.
- *
- * @kind function
- * @memberof KerberosClient
- * @param {string} challenge The response returned after calling `unwrap`
- * @param {object} [options] Options
- * @param {string} [options.user] The user to authorize
- * @param {boolean} [options.protect] Indicates if the wrap should request message confidentiality
- * @return {Promise}
- */
-KerberosClient.prototype.wrap = async function wrap(challenge, options = {}) {
- if (typeof challenge !== 'string') {
- throw new TypeError('parameter `challenge` must be a string.');
- }
-
- return await promsifiedWrap.call(this, challenge, options);
-};
-
-const promisifiedUnwrap = promisify(KerberosClient.prototype.unwrap);
-/**
- * Perform the client side kerberos unwrap step
- *
- * @kind function
- * @memberof KerberosClient
- * @param {string} challenge A string containing the base64-encoded server data
- * @return {Promise}
- */
-KerberosClient.prototype.unwrap = async function unwrap(challenge) {
- if (typeof challenge !== 'string') {
- throw new TypeError('parameter `challenge` must be a string.');
- }
- return await promisifiedUnwrap.call(this, challenge);
-};
-
-const promisifiedServerStep = promisify(KerberosServer.prototype.step);
-/**
- * @class KerberosServer
- *
- * @property {string} username The username used for authentication
- * @property {string} response The last response received during authentication steps
- * @property {string} targetName The target used for authentication
- * @property {boolean} contextComplete Indicates that authentication has successfully completed or not
- */
-
-/**
- * Processes a single kerberos server-side step using the supplied client data.
- *
- * @kind function
- * @memberof KerberosServer
- * @param {string} challenge A string containing the base64-encoded client data
- * @return {Promise}
- */
-KerberosServer.prototype.step = async function step(challenge) {
- if (typeof challenge !== 'string') {
- throw new TypeError('parameter `challenge` must be a string.');
- }
- return await promisifiedServerStep.call(this, challenge);
-};
-
-const promisifiedCheckPassword = promisify(kerberos.checkPassword);
-
-/**
- * This function provides a simple way to verify that a user name and password
- * match those normally used for Kerberos authentication.
- * It does this by checking that the supplied user name and password can be
- * used to get a ticket for the supplied service.
- * If the user name does not contain a realm, then the default realm supplied
- * is used.
- *
- * For this to work properly the Kerberos must be configured properly on this
- * machine.
- * That will likely mean ensuring that the edu.mit.Kerberos preference file
- * has the correct realms and KDCs listed.
- *
- * IMPORTANT: This method is vulnerable to KDC spoofing attacks and it should
- * only be used for testing. Do not use this in any production system - your
- * security could be compromised if you do.
- *
- * @kind function
- * @param {string} username The Kerberos user name. If no realm is supplied, then the `defaultRealm` will be used.
- * @param {string} password The password for the user.
- * @param {string} service The Kerberos service to check access for.
- * @param {string} [defaultRealm] The default realm to use if one is not supplied in the user argument.
- * @return {Promise} returns Promise that rejects if the password is invalid
- */
-async function checkPassword(username, password, service, defaultRealm) {
- if (typeof username !== 'string') {
- throw new TypeError('parameter `username` must be a string.');
- }
- if (typeof password !== 'string') {
- throw new TypeError('parameter `password` must be a string.');
- }
- if (typeof service !== 'string') {
- throw new TypeError('parameter `service` must be a string.');
- }
- if (defaultRealm && typeof defaultRealm !== 'string') {
- throw new TypeError('if specified, parameter `defaultRealm` must be a string.');
- }
- return await promisifiedCheckPassword.call(this, username, password, service, defaultRealm);
-}
-
-const promisifiedPrincipalDetails = promisify(kerberos.principalDetails);
-/**
- * This function returns the service principal for the server given a service type and hostname.
- *
- * Details are looked up via the `/etc/keytab` file.
- *
- * @kind function
- * @param {string} service The Kerberos service type for the server.
- * @param {string} hostname The hostname of the server.
- * @return {Promise} returns Promise
- */
-async function principalDetails(service, hostname) {
- if (typeof service !== 'string') {
- throw new TypeError('parameter `service` must be a string.');
- }
- if (typeof hostname !== 'string') {
- throw new TypeError('parameter `hostname` must be a string.');
- }
- return await promisifiedPrincipalDetails.call(this, service, hostname);
-}
-
-const promisifiedInitializeClient = promisify(kerberos.initializeClient);
-/**
- * Initializes a context for client-side authentication with the given service principal.
- *
- * @kind function
- * @param {string} service A string containing the service principal in the form 'type@fqdn' (e.g. 'imap@mail.apple.com').
- * @param {object} [options] Optional settings
- * @param {string} [options.principal] Optional string containing the client principal in the form 'user@realm' (e.g. 'jdoe@example.com').
- * @param {number} [options.flags] Optional integer used to set GSS flags. (e.g. `GSS_C_DELEG_FLAG\|GSS_C_MUTUAL_FLAG\|GSS_C_SEQUENCE_FLAG` will allow for forwarding credentials to the remote host)
- * @param {number} [options.mechOID] Optional GSS mech OID. Defaults to None (GSS_C_NO_OID). Other possible values are `GSS_MECH_OID_KRB5`, `GSS_MECH_OID_SPNEGO`.
- * @param {string} [options.user] The username with which to authenticate. Only used on Windows.
- * @param {string} [options.pass] The password with which to authenticate. Only used on Windows.
- * @return {Promise} returns Promise
- */
-async function initializeClient(service, options = { mechOID: GSS_C_NO_OID }) {
- if (typeof service !== 'string') {
- throw new TypeError('parameter `service` must be a string.');
- }
- return await promisifiedInitializeClient.call(this, service, options);
-}
-
-const promisifiedInitializeServer = promisify(kerberos.initializeServer);
-
-/**
- * Initializes a context for server-side authentication with the given service principal.
- *
- * @kind function
- * @param {string} service A string containing the service principal in the form 'type@fqdn' (e.g. 'imap@mail.apple.com').
- * @return {Promise} returns Promise
- */
-async function initializeServer(service) {
- if (typeof service !== 'string') {
- throw new TypeError('parameter `service` must be a string.');
- }
- return await promisifiedInitializeServer.call(this, service);
-}
-
-module.exports = {
- initializeClient,
- initializeServer,
- principalDetails,
- checkPassword,
-
- // gss flags
- GSS_C_DELEG_FLAG,
- GSS_C_MUTUAL_FLAG,
- GSS_C_REPLAY_FLAG,
- GSS_C_SEQUENCE_FLAG,
- GSS_C_CONF_FLAG,
- GSS_C_INTEG_FLAG,
- GSS_C_ANON_FLAG,
- GSS_C_PROT_READY_FLAG,
- GSS_C_TRANS_FLAG,
- GSS_C_NO_OID,
-
- // mechanism OIDs
- GSS_MECH_OID_KRB5,
- GSS_MECH_OID_SPNEGO
-};
diff --git a/package.json b/package.json
index 9af360e..bdadc51 100644
--- a/package.json
+++ b/package.json
@@ -60,7 +60,7 @@
"format-js": "ESLINT_USE_FLAT_CONFIG=false eslint lib test --fix",
"check:lint": "ESLINT_USE_FLAT_CONFIG=false eslint lib test index.d.ts",
"precommit": "check-clang-format",
- "docs": "jsdoc2md --template etc/README.hbs --plugin dmd-clear --files lib/kerberos.js > README.md",
+ "docs": "jsdoc2md --template etc/README.hbs --plugin dmd-clear --files lib/index.js > README.md",
"test": "mocha 'test/*_tests.js'",
"prebuild": "prebuild --runtime napi --strip --verbose --all"
},
diff --git a/test/exports_tests.js b/test/exports_tests.js
index 8d648fb..6783acd 100644
--- a/test/exports_tests.js
+++ b/test/exports_tests.js
@@ -33,8 +33,4 @@ describe('module', function () {
expect(api.principalDetails).to.be.a('function');
expect(api.checkPassword).to.be.a('function');
});
-
- it('should export Kerberos', () => {
- expect(api.Kerberos).to.be.an('object');
- });
});