123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- "use strict";
- const ldapjs = require('ldapjs');
- const Parse = require('parse/node').Parse;
- function validateAuthData(authData, options) {
- if (!optionsAreValid(options)) {
- return new Promise((_, reject) => {
- reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP auth configuration missing'));
- });
- }
- const clientOptions = options.url.startsWith('ldaps://') ? {
- url: options.url,
- tlsOptions: options.tlsOptions
- } : {
- url: options.url
- };
- const client = ldapjs.createClient(clientOptions);
- const userCn = typeof options.dn === 'string' ? options.dn.replace('{{id}}', authData.id) : `uid=${authData.id},${options.suffix}`;
- return new Promise((resolve, reject) => {
- client.bind(userCn, authData.password, ldapError => {
- delete authData.password;
- if (ldapError) {
- let error;
- switch (ldapError.code) {
- case 49:
- error = new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'LDAP: Wrong username or password');
- break;
- case 'DEPTH_ZERO_SELF_SIGNED_CERT':
- error = new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'LDAPS: Certificate mismatch');
- break;
- default:
- error = new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'LDAP: Somthing went wrong (' + ldapError.code + ')');
- }
- reject(error);
- client.destroy(ldapError);
- return;
- }
- if (typeof options.groupCn === 'string' && typeof options.groupFilter === 'string') {
- searchForGroup(client, options, authData.id, resolve, reject);
- } else {
- client.unbind();
- client.destroy();
- resolve();
- }
- });
- });
- }
- function optionsAreValid(options) {
- return typeof options === 'object' && typeof options.suffix === 'string' && typeof options.url === 'string' && (options.url.startsWith('ldap://') || options.url.startsWith('ldaps://') && typeof options.tlsOptions === 'object');
- }
- function searchForGroup(client, options, id, resolve, reject) {
- const filter = options.groupFilter.replace(/{{id}}/gi, id);
- const opts = {
- scope: 'sub',
- filter: filter
- };
- let found = false;
- client.search(options.suffix, opts, (searchError, res) => {
- if (searchError) {
- client.unbind();
- client.destroy();
- return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP group search failed'));
- }
- res.on('searchEntry', entry => {
- if (entry.pojo.attributes.find(obj => obj.type === 'cn').values.includes(options.groupCn)) {
- found = true;
- client.unbind();
- client.destroy();
- return resolve();
- }
- });
- res.on('end', () => {
- if (!found) {
- client.unbind();
- client.destroy();
- return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP: User not in group'));
- }
- });
- res.on('error', () => {
- client.unbind();
- client.destroy();
- return reject(new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'LDAP group search failed'));
- });
- });
- }
- function validateAppId() {
- return Promise.resolve();
- }
- module.exports = {
- validateAppId,
- validateAuthData
- };
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJsZGFwanMiLCJyZXF1aXJlIiwiUGFyc2UiLCJ2YWxpZGF0ZUF1dGhEYXRhIiwiYXV0aERhdGEiLCJvcHRpb25zIiwib3B0aW9uc0FyZVZhbGlkIiwiUHJvbWlzZSIsIl8iLCJyZWplY3QiLCJFcnJvciIsIklOVEVSTkFMX1NFUlZFUl9FUlJPUiIsImNsaWVudE9wdGlvbnMiLCJ1cmwiLCJzdGFydHNXaXRoIiwidGxzT3B0aW9ucyIsImNsaWVudCIsImNyZWF0ZUNsaWVudCIsInVzZXJDbiIsImRuIiwicmVwbGFjZSIsImlkIiwic3VmZml4IiwicmVzb2x2ZSIsImJpbmQiLCJwYXNzd29yZCIsImxkYXBFcnJvciIsImVycm9yIiwiY29kZSIsIk9CSkVDVF9OT1RfRk9VTkQiLCJkZXN0cm95IiwiZ3JvdXBDbiIsImdyb3VwRmlsdGVyIiwic2VhcmNoRm9yR3JvdXAiLCJ1bmJpbmQiLCJmaWx0ZXIiLCJvcHRzIiwic2NvcGUiLCJmb3VuZCIsInNlYXJjaCIsInNlYXJjaEVycm9yIiwicmVzIiwib24iLCJlbnRyeSIsInBvam8iLCJhdHRyaWJ1dGVzIiwiZmluZCIsIm9iaiIsInR5cGUiLCJ2YWx1ZXMiLCJpbmNsdWRlcyIsInZhbGlkYXRlQXBwSWQiLCJtb2R1bGUiLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL0FkYXB0ZXJzL0F1dGgvbGRhcC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBsZGFwanMgPSByZXF1aXJlKCdsZGFwanMnKTtcbmNvbnN0IFBhcnNlID0gcmVxdWlyZSgncGFyc2Uvbm9kZScpLlBhcnNlO1xuXG5mdW5jdGlvbiB2YWxpZGF0ZUF1dGhEYXRhKGF1dGhEYXRhLCBvcHRpb25zKSB7XG4gIGlmICghb3B0aW9uc0FyZVZhbGlkKG9wdGlvbnMpKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChfLCByZWplY3QpID0+IHtcbiAgICAgIHJlamVjdChuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuSU5URVJOQUxfU0VSVkVSX0VSUk9SLCAnTERBUCBhdXRoIGNvbmZpZ3VyYXRpb24gbWlzc2luZycpKTtcbiAgICB9KTtcbiAgfVxuICBjb25zdCBjbGllbnRPcHRpb25zID0gb3B0aW9ucy51cmwuc3RhcnRzV2l0aCgnbGRhcHM6Ly8nKVxuICAgID8geyB1cmw6IG9wdGlvbnMudXJsLCB0bHNPcHRpb25zOiBvcHRpb25zLnRsc09wdGlvbnMgfVxuICAgIDogeyB1cmw6IG9wdGlvbnMudXJsIH07XG5cbiAgY29uc3QgY2xpZW50ID0gbGRhcGpzLmNyZWF0ZUNsaWVudChjbGllbnRPcHRpb25zKTtcbiAgY29uc3QgdXNlckNuID1cbiAgICB0eXBlb2Ygb3B0aW9ucy5kbiA9PT0gJ3N0cmluZydcbiAgICAgID8gb3B0aW9ucy5kbi5yZXBsYWNlKCd7e2lkfX0nLCBhdXRoRGF0YS5pZClcbiAgICAgIDogYHVpZD0ke2F1dGhEYXRhLmlkfSwke29wdGlvbnMuc3VmZml4fWA7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBjbGllbnQuYmluZCh1c2VyQ24sIGF1dGhEYXRhLnBhc3N3b3JkLCBsZGFwRXJyb3IgPT4ge1xuICAgICAgZGVsZXRlIGF1dGhEYXRhLnBhc3N3b3JkO1xuICAgICAgaWYgKGxkYXBFcnJvcikge1xuICAgICAgICBsZXQgZXJyb3I7XG4gICAgICAgIHN3aXRjaCAobGRhcEVycm9yLmNvZGUpIHtcbiAgICAgICAgICBjYXNlIDQ5OlxuICAgICAgICAgICAgZXJyb3IgPSBuZXcgUGFyc2UuRXJyb3IoXG4gICAgICAgICAgICAgIFBhcnNlLkVycm9yLk9CSkVDVF9OT1RfRk9VTkQsXG4gICAgICAgICAgICAgICdMREFQOiBXcm9uZyB1c2VybmFtZSBvciBwYXNzd29yZCdcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdERVBUSF9aRVJPX1NFTEZfU0lHTkVEX0NFUlQnOlxuICAgICAgICAgICAgZXJyb3IgPSBuZXcgUGFyc2UuRXJyb3IoUGFyc2UuRXJyb3IuT0JKRUNUX05PVF9GT1VORCwgJ0xEQVBTOiBDZXJ0aWZpY2F0ZSBtaXNtYXRjaCcpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGVycm9yID0gbmV3IFBhcnNlLkVycm9yKFxuICAgICAgICAgICAgICBQYXJzZS5FcnJvci5PQkpFQ1RfTk9UX0ZPVU5ELFxuICAgICAgICAgICAgICAnTERBUDogU29tdGhpbmcgd2VudCB3cm9uZyAoJyArIGxkYXBFcnJvci5jb2RlICsgJyknXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIGNsaWVudC5kZXN0cm95KGxkYXBFcnJvcik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLmdyb3VwQ24gPT09ICdzdHJpbmcnICYmIHR5cGVvZiBvcHRpb25zLmdyb3VwRmlsdGVyID09PSAnc3RyaW5nJykge1xuICAgICAgICBzZWFyY2hGb3JHcm91cChjbGllbnQsIG9wdGlvbnMsIGF1dGhEYXRhLmlkLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2xpZW50LnVuYmluZCgpO1xuICAgICAgICBjbGllbnQuZGVzdHJveSgpO1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBvcHRpb25zQXJlVmFsaWQob3B0aW9ucykge1xuICByZXR1cm4gKFxuICAgIHR5cGVvZiBvcHRpb25zID09PSAnb2JqZWN0JyAmJlxuICAgIHR5cGVvZiBvcHRpb25zLnN1ZmZpeCA9PT0gJ3N0cmluZycgJiZcbiAgICB0eXBlb2Ygb3B0aW9ucy51cmwgPT09ICdzdHJpbmcnICYmXG4gICAgKG9wdGlvbnMudXJsLnN0YXJ0c1dpdGgoJ2xkYXA6Ly8nKSB8fFxuICAgICAgKG9wdGlvbnMudXJsLnN0YXJ0c1dpdGgoJ2xkYXBzOi8vJykgJiYgdHlwZW9mIG9wdGlvbnMudGxzT3B0aW9ucyA9PT0gJ29iamVjdCcpKVxuICApO1xufVxuXG5mdW5jdGlvbiBzZWFyY2hGb3JHcm91cChjbGllbnQsIG9wdGlvbnMsIGlkLCByZXNvbHZlLCByZWplY3QpIHtcbiAgY29uc3QgZmlsdGVyID0gb3B0aW9ucy5ncm91cEZpbHRlci5yZXBsYWNlKC97e2lkfX0vZ2ksIGlkKTtcbiAgY29uc3Qgb3B0cyA9IHtcbiAgICBzY29wZTogJ3N1YicsXG4gICAgZmlsdGVyOiBmaWx0ZXIsXG4gIH07XG4gIGxldCBmb3VuZCA9IGZhbHNlO1xuICBjbGllbnQuc2VhcmNoKG9wdGlvbnMuc3VmZml4LCBvcHRzLCAoc2VhcmNoRXJyb3IsIHJlcykgPT4ge1xuICAgIGlmIChzZWFyY2hFcnJvcikge1xuICAgICAgY2xpZW50LnVuYmluZCgpO1xuICAgICAgY2xpZW50LmRlc3Ryb3koKTtcbiAgICAgIHJldHVybiByZWplY3QobmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUiwgJ0xEQVAgZ3JvdXAgc2VhcmNoIGZhaWxlZCcpKTtcbiAgICB9XG4gICAgcmVzLm9uKCdzZWFyY2hFbnRyeScsIGVudHJ5ID0+IHtcbiAgICAgIGlmIChlbnRyeS5wb2pvLmF0dHJpYnV0ZXMuZmluZChvYmogPT4gb2JqLnR5cGUgPT09ICdjbicpLnZhbHVlcy5pbmNsdWRlcyhvcHRpb25zLmdyb3VwQ24pKSB7XG4gICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgY2xpZW50LnVuYmluZCgpO1xuICAgICAgICBjbGllbnQuZGVzdHJveSgpO1xuICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJlcy5vbignZW5kJywgKCkgPT4ge1xuICAgICAgaWYgKCFmb3VuZCkge1xuICAgICAgICBjbGllbnQudW5iaW5kKCk7XG4gICAgICAgIGNsaWVudC5kZXN0cm95KCk7XG4gICAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgICAgbmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUiwgJ0xEQVA6IFVzZXIgbm90IGluIGdyb3VwJylcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXMub24oJ2Vycm9yJywgKCkgPT4ge1xuICAgICAgY2xpZW50LnVuYmluZCgpO1xuICAgICAgY2xpZW50LmRlc3Ryb3koKTtcbiAgICAgIHJldHVybiByZWplY3QobmV3IFBhcnNlLkVycm9yKFBhcnNlLkVycm9yLklOVEVSTkFMX1NFUlZFUl9FUlJPUiwgJ0xEQVAgZ3JvdXAgc2VhcmNoIGZhaWxlZCcpKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlQXBwSWQoKSB7XG4gIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlQXBwSWQsXG4gIHZhbGlkYXRlQXV0aERhdGEsXG59O1xuIl0sIm1hcHBpbmdzIjoiOztBQUFBLE1BQU1BLE1BQU0sR0FBR0MsT0FBTyxDQUFDLFFBQVEsQ0FBQztBQUNoQyxNQUFNQyxLQUFLLEdBQUdELE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQ0MsS0FBSztBQUV6QyxTQUFTQyxnQkFBZ0JBLENBQUNDLFFBQVEsRUFBRUMsT0FBTyxFQUFFO0VBQzNDLElBQUksQ0FBQ0MsZUFBZSxDQUFDRCxPQUFPLENBQUMsRUFBRTtJQUM3QixPQUFPLElBQUlFLE9BQU8sQ0FBQyxDQUFDQyxDQUFDLEVBQUVDLE1BQU0sS0FBSztNQUNoQ0EsTUFBTSxDQUFDLElBQUlQLEtBQUssQ0FBQ1EsS0FBSyxDQUFDUixLQUFLLENBQUNRLEtBQUssQ0FBQ0MscUJBQXFCLEVBQUUsaUNBQWlDLENBQUMsQ0FBQztJQUMvRixDQUFDLENBQUM7RUFDSjtFQUNBLE1BQU1DLGFBQWEsR0FBR1AsT0FBTyxDQUFDUSxHQUFHLENBQUNDLFVBQVUsQ0FBQyxVQUFVLENB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
|