You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					126 lines
				
				5.8 KiB
			
		
		
			
		
	
	
					126 lines
				
				5.8 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								"use strict";
							 | 
						||
| 
								 | 
							
								Object.defineProperty(exports, "__esModule", { value: true });
							 | 
						||
| 
								 | 
							
								exports.MongoCredentials = void 0;
							 | 
						||
| 
								 | 
							
								const error_1 = require("../../error");
							 | 
						||
| 
								 | 
							
								const gssapi_1 = require("./gssapi");
							 | 
						||
| 
								 | 
							
								const providers_1 = require("./providers");
							 | 
						||
| 
								 | 
							
								// https://github.com/mongodb/specifications/blob/master/source/auth/auth.rst
							 | 
						||
| 
								 | 
							
								function getDefaultAuthMechanism(hello) {
							 | 
						||
| 
								 | 
							
								    if (hello) {
							 | 
						||
| 
								 | 
							
								        // If hello contains saslSupportedMechs, use scram-sha-256
							 | 
						||
| 
								 | 
							
								        // if it is available, else scram-sha-1
							 | 
						||
| 
								 | 
							
								        if (Array.isArray(hello.saslSupportedMechs)) {
							 | 
						||
| 
								 | 
							
								            return hello.saslSupportedMechs.includes(providers_1.AuthMechanism.MONGODB_SCRAM_SHA256)
							 | 
						||
| 
								 | 
							
								                ? providers_1.AuthMechanism.MONGODB_SCRAM_SHA256
							 | 
						||
| 
								 | 
							
								                : providers_1.AuthMechanism.MONGODB_SCRAM_SHA1;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        // Fallback to legacy selection method. If wire version >= 3, use scram-sha-1
							 | 
						||
| 
								 | 
							
								        if (hello.maxWireVersion >= 3) {
							 | 
						||
| 
								 | 
							
								            return providers_1.AuthMechanism.MONGODB_SCRAM_SHA1;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    // Default for wireprotocol < 3
							 | 
						||
| 
								 | 
							
								    return providers_1.AuthMechanism.MONGODB_CR;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * A representation of the credentials used by MongoDB
							 | 
						||
| 
								 | 
							
								 * @public
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class MongoCredentials {
							 | 
						||
| 
								 | 
							
								    constructor(options) {
							 | 
						||
| 
								 | 
							
								        this.username = options.username;
							 | 
						||
| 
								 | 
							
								        this.password = options.password;
							 | 
						||
| 
								 | 
							
								        this.source = options.source;
							 | 
						||
| 
								 | 
							
								        if (!this.source && options.db) {
							 | 
						||
| 
								 | 
							
								            this.source = options.db;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        this.mechanism = options.mechanism || providers_1.AuthMechanism.MONGODB_DEFAULT;
							 | 
						||
| 
								 | 
							
								        this.mechanismProperties = options.mechanismProperties || {};
							 | 
						||
| 
								 | 
							
								        if (this.mechanism.match(/MONGODB-AWS/i)) {
							 | 
						||
| 
								 | 
							
								            if (!this.username && process.env.AWS_ACCESS_KEY_ID) {
							 | 
						||
| 
								 | 
							
								                this.username = process.env.AWS_ACCESS_KEY_ID;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (!this.password && process.env.AWS_SECRET_ACCESS_KEY) {
							 | 
						||
| 
								 | 
							
								                this.password = process.env.AWS_SECRET_ACCESS_KEY;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            if (this.mechanismProperties.AWS_SESSION_TOKEN == null &&
							 | 
						||
| 
								 | 
							
								                process.env.AWS_SESSION_TOKEN != null) {
							 | 
						||
| 
								 | 
							
								                this.mechanismProperties = {
							 | 
						||
| 
								 | 
							
								                    ...this.mechanismProperties,
							 | 
						||
| 
								 | 
							
								                    AWS_SESSION_TOKEN: process.env.AWS_SESSION_TOKEN
							 | 
						||
| 
								 | 
							
								                };
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        Object.freeze(this.mechanismProperties);
							 | 
						||
| 
								 | 
							
								        Object.freeze(this);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /** Determines if two MongoCredentials objects are equivalent */
							 | 
						||
| 
								 | 
							
								    equals(other) {
							 | 
						||
| 
								 | 
							
								        return (this.mechanism === other.mechanism &&
							 | 
						||
| 
								 | 
							
								            this.username === other.username &&
							 | 
						||
| 
								 | 
							
								            this.password === other.password &&
							 | 
						||
| 
								 | 
							
								            this.source === other.source);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * If the authentication mechanism is set to "default", resolves the authMechanism
							 | 
						||
| 
								 | 
							
								     * based on the server version and server supported sasl mechanisms.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param hello - A hello response from the server
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    resolveAuthMechanism(hello) {
							 | 
						||
| 
								 | 
							
								        // If the mechanism is not "default", then it does not need to be resolved
							 | 
						||
| 
								 | 
							
								        if (this.mechanism.match(/DEFAULT/i)) {
							 | 
						||
| 
								 | 
							
								            return new MongoCredentials({
							 | 
						||
| 
								 | 
							
								                username: this.username,
							 | 
						||
| 
								 | 
							
								                password: this.password,
							 | 
						||
| 
								 | 
							
								                source: this.source,
							 | 
						||
| 
								 | 
							
								                mechanism: getDefaultAuthMechanism(hello),
							 | 
						||
| 
								 | 
							
								                mechanismProperties: this.mechanismProperties
							 | 
						||
| 
								 | 
							
								            });
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return this;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    validate() {
							 | 
						||
| 
								 | 
							
								        if ((this.mechanism === providers_1.AuthMechanism.MONGODB_GSSAPI ||
							 | 
						||
| 
								 | 
							
								            this.mechanism === providers_1.AuthMechanism.MONGODB_CR ||
							 | 
						||
| 
								 | 
							
								            this.mechanism === providers_1.AuthMechanism.MONGODB_PLAIN ||
							 | 
						||
| 
								 | 
							
								            this.mechanism === providers_1.AuthMechanism.MONGODB_SCRAM_SHA1 ||
							 | 
						||
| 
								 | 
							
								            this.mechanism === providers_1.AuthMechanism.MONGODB_SCRAM_SHA256) &&
							 | 
						||
| 
								 | 
							
								            !this.username) {
							 | 
						||
| 
								 | 
							
								            throw new error_1.MongoMissingCredentialsError(`Username required for mechanism '${this.mechanism}'`);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (providers_1.AUTH_MECHS_AUTH_SRC_EXTERNAL.has(this.mechanism)) {
							 | 
						||
| 
								 | 
							
								            if (this.source != null && this.source !== '$external') {
							 | 
						||
| 
								 | 
							
								                // TODO(NODE-3485): Replace this with a MongoAuthValidationError
							 | 
						||
| 
								 | 
							
								                throw new error_1.MongoAPIError(`Invalid source '${this.source}' for mechanism '${this.mechanism}' specified.`);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (this.mechanism === providers_1.AuthMechanism.MONGODB_PLAIN && this.source == null) {
							 | 
						||
| 
								 | 
							
								            // TODO(NODE-3485): Replace this with a MongoAuthValidationError
							 | 
						||
| 
								 | 
							
								            throw new error_1.MongoAPIError('PLAIN Authentication Mechanism needs an auth source');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (this.mechanism === providers_1.AuthMechanism.MONGODB_X509 && this.password != null) {
							 | 
						||
| 
								 | 
							
								            if (this.password === '') {
							 | 
						||
| 
								 | 
							
								                Reflect.set(this, 'password', undefined);
							 | 
						||
| 
								 | 
							
								                return;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            // TODO(NODE-3485): Replace this with a MongoAuthValidationError
							 | 
						||
| 
								 | 
							
								            throw new error_1.MongoAPIError(`Password not allowed for mechanism MONGODB-X509`);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        const canonicalization = this.mechanismProperties.CANONICALIZE_HOST_NAME ?? false;
							 | 
						||
| 
								 | 
							
								        if (!Object.values(gssapi_1.GSSAPICanonicalizationValue).includes(canonicalization)) {
							 | 
						||
| 
								 | 
							
								            throw new error_1.MongoAPIError(`Invalid CANONICALIZE_HOST_NAME value: ${canonicalization}`);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    static merge(creds, options) {
							 | 
						||
| 
								 | 
							
								        return new MongoCredentials({
							 | 
						||
| 
								 | 
							
								            username: options.username ?? creds?.username ?? '',
							 | 
						||
| 
								 | 
							
								            password: options.password ?? creds?.password ?? '',
							 | 
						||
| 
								 | 
							
								            mechanism: options.mechanism ?? creds?.mechanism ?? providers_1.AuthMechanism.MONGODB_DEFAULT,
							 | 
						||
| 
								 | 
							
								            mechanismProperties: options.mechanismProperties ?? creds?.mechanismProperties ?? {},
							 | 
						||
| 
								 | 
							
								            source: options.source ?? options.db ?? creds?.source ?? 'admin'
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								exports.MongoCredentials = MongoCredentials;
							 | 
						||
| 
								 | 
							
								//# sourceMappingURL=mongo_credentials.js.map
							 |