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
						
					
					
				"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
 |