libmongocrypt-1.3.0/000077500000000000000000000000001414105245100144005ustar00rootroot00000000000000libmongocrypt-1.3.0/.clang-format000066400000000000000000000020101414105245100167440ustar00rootroot00000000000000--- AlignAfterOpenBracket: Align AlignConsecutiveAssignments: 'false' AlignConsecutiveDeclarations: 'false' AlignEscapedNewlinesLeft: 'true' AllowAllParametersOfDeclarationOnNextLine: 'true' AllowShortBlocksOnASingleLine: 'false' AllowShortCaseLabelsOnASingleLine: 'false' AllowShortFunctionsOnASingleLine: None AllowShortIfStatementsOnASingleLine: 'false' AllowShortLoopsOnASingleLine: 'false' AlwaysBreakAfterReturnType: All BinPackArguments: 'false' BinPackParameters: 'false' BreakBeforeBraces: Linux ColumnLimit: '80' ContinuationIndentWidth: '3' IndentCaseLabels: 'false' IndentWidth: '3' KeepEmptyLinesAtTheStartOfBlocks: 'false' Language: Cpp MaxEmptyLinesToKeep: '2' SortIncludes: 'false' SpaceAfterCStyleCast: 'true' SpaceBeforeAssignmentOperators: 'true' SpaceBeforeParens: Always SpaceInEmptyParentheses: 'false' SpacesInAngles: 'false' SpacesInCStyleCastParentheses: 'false' SpacesInContainerLiterals: 'true' SpacesInParentheses: 'false' SpacesInSquareBrackets: 'false' Standard: Cpp11 TabWidth: '3' UseTab: Never ... libmongocrypt-1.3.0/.clang-tidy000066400000000000000000000005161414105245100164360ustar00rootroot00000000000000# Older clang-tidy gives a warning for an uninitialized va_args, # even on the test case that they assert should not produce that warning: # https://github.com/llvm-mirror/clang/blob/59207d134acb8a1c6cb9974c32c1c04bd31f8f7b/test/Analysis/valist-uninitialized.c#L30 Checks: "-clang-analyzer-valist.Uninitialized" WarningsAsErrors: "*" libmongocrypt-1.3.0/.evergreen/000077500000000000000000000000001414105245100164405ustar00rootroot00000000000000libmongocrypt-1.3.0/.evergreen/build_all.sh000077500000000000000000000066041414105245100207340ustar00rootroot00000000000000#!/bin/bash # Compiles libmongocrypt dependencies and targets. # # Assumes the current working directory contains libmongocrypt. # So script should be called like: ./libmongocrypt/.evergreen/build_all.sh # The current working directory should be empty aside from 'libmongocrypt' # since this script creates new directories/files (e.g. mongo-c-driver, venv). # # Set extra cflags for libmongocrypt variables by setting LIBMONGOCRYPT_EXTRA_CFLAGS. # set -o xtrace set -o errexit echo "Begin compile process" evergreen_root="$(pwd)" . ${evergreen_root}/libmongocrypt/.evergreen/setup-env.sh if [ "$PPA_BUILD_ONLY" ]; then # Clean-up from previous build iteration cd $evergreen_root rm -rf libmongocrypt/cmake-build* "${MONGOCRYPT_INSTALL_PREFIX}" ADDITIONAL_CMAKE_FLAGS="${ADDITIONAL_CMAKE_FLAGS} -DENABLE_BUILD_FOR_PPA=ON" fi . ${evergreen_root}/libmongocrypt/.evergreen/build_install_bson.sh cd $evergreen_root # CMAKE should be set in build_install_bson.sh; this error should not occur command -v $CMAKE || (echo "CMake could not be found...aborting!"; exit 1) # Build and install libmongocrypt. cd libmongocrypt mkdir cmake-build cd cmake-build $CMAKE -DCMAKE_BUILD_TYPE=RelWithDebInfo $ADDITIONAL_CMAKE_FLAGS "${LIBMONGOCRYPT_EXTRA_CMAKE_FLAGS}" -DCMAKE_C_FLAGS="${LIBMONGOCRYPT_EXTRA_CFLAGS}" -DCMAKE_PREFIX_PATH="${BSON_INSTALL_PREFIX}" "-DCMAKE_INSTALL_PREFIX=${MONGOCRYPT_INSTALL_PREFIX}" -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ../ if [ "$CONFIGURE_ONLY" ]; then echo "Only running cmake"; exit 0; fi echo "Installing libmongocrypt" $CMAKE --build . --target install --config RelWithDebInfo # CDRIVER-3187, ensure the final distributed tarball contains the libbson static # library to support consumers that static link to libmongocrypt find ${BSON_INSTALL_PREFIX} \( -name libbson-static-1.0.a -o -name bson-1.0.lib -o -name bson-static-1.0.lib \) -execdir cp {} $(dirname $(find ${MONGOCRYPT_INSTALL_PREFIX} -name libmongocrypt-static.a -o -name mongocrypt-static.lib)) \; $CMAKE --build . --target test-mongocrypt --config RelWithDebInfo $CMAKE --build ./kms-message --target test_kms_request --config RelWithDebInfo cd $evergreen_root if [ "$PPA_BUILD_ONLY" ]; then echo "Only building/installing for PPA"; exit 0; fi # Build and install libmongocrypt with no native crypto. cd libmongocrypt mkdir cmake-build-nocrypto cd cmake-build-nocrypto $CMAKE -DDISABLE_NATIVE_CRYPTO=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo $ADDITIONAL_CMAKE_FLAGS "${LIBMONGOCRYPT_EXTRA_CMAKE_FLAGS}" -DCMAKE_C_FLAGS="${LIBMONGOCRYPT_EXTRA_CFLAGS}" -DCMAKE_PREFIX_PATH="${BSON_INSTALL_PREFIX}" "-DCMAKE_INSTALL_PREFIX=${MONGOCRYPT_INSTALL_PREFIX}/nocrypto" ../ echo "Installing libmongocrypt with no crypto" $CMAKE --build . --target install --config RelWithDebInfo echo "Building test-mongocrypt with no crypto" $CMAKE --build . --target test-mongocrypt --config RelWithDebInfo cd $evergreen_root # Build and install libmongocrypt without statically linking libbson cd libmongocrypt mkdir cmake-build-sharedbson cd cmake-build-sharedbson $CMAKE -DENABLE_SHARED_BSON=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo $ADDITIONAL_CMAKE_FLAGS "${LIBMONGOCRYPT_EXTRA_CMAKE_FLAGS}" -DCMAKE_C_FLAGS="${LIBMONGOCRYPT_EXTRA_CFLAGS}" -DCMAKE_PREFIX_PATH="${BSON_INSTALL_PREFIX}" "-DCMAKE_INSTALL_PREFIX=${MONGOCRYPT_INSTALL_PREFIX}/sharedbson" ../ echo "Installing libmongocrypt with shared libbson" $CMAKE --build . --target install --config RelWithDebInfo libmongocrypt-1.3.0/.evergreen/build_install_bson.sh000066400000000000000000000017611414105245100226470ustar00rootroot00000000000000#!/bin/bash set -o xtrace set -o errexit evergreen_root="$(pwd)" pushd $evergreen_root . ${evergreen_root}/libmongocrypt/.evergreen/setup-env.sh # Build and install libbson. pushd mongo-c-driver # Use C driver helper script to find cmake binary, stored in $CMAKE. if [ "$OS" == "Windows_NT" ]; then CMAKE=/cygdrive/c/cmake/bin/cmake ADDITIONAL_CMAKE_FLAGS="-Thost=x64 -A x64" else chmod u+x ./.evergreen/find-cmake.sh . ./.evergreen/find-cmake.sh fi $CMAKE --version # Remove remnants of any earlier build [ -d cmake-build ] && rm -rf cmake-build mkdir cmake-build pushd cmake-build $CMAKE -DENABLE_MONGOC=OFF ${ADDITIONAL_CMAKE_FLAGS} ${BSON_EXTRA_CMAKE_FLAGS} -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_EXTRA_ALIGNMENT=OFF -DCMAKE_C_FLAGS="${BSON_EXTRA_CFLAGS}" -DCMAKE_INSTALL_PREFIX="${BSON_INSTALL_PREFIX}" ../ echo "Installing libbson" # TODO - Upgrade to cmake 3.12 and use "-j" to increase parallelism $CMAKE --build . --target install --config RelWithDebInfo popd popd popd libmongocrypt-1.3.0/.evergreen/clang-tidy.sh000077500000000000000000000007021414105245100210310ustar00rootroot00000000000000#!/bin/bash # Run after running "CONFIGURE_ONLY=ON compile.sh" to run the clang-tidy # static analyzer. # set -o xtrace set -o errexit echo "Begin compile process" evergreen_root="$(pwd)" . ${evergreen_root}/libmongocrypt/.evergreen/setup-env.sh cd $evergreen_root CLANG_TIDY=/opt/mongodbtoolchain/v3/bin/clang-tidy $CLANG_TIDY --version cd libmongocrypt python ./etc/list-compile-files.py ./cmake-build/ | xargs $CLANG_TIDY -p ./cmake-buildlibmongocrypt-1.3.0/.evergreen/compile.sh000077500000000000000000000013451414105245100204320ustar00rootroot00000000000000#!/bin/bash # Downloads and prepares the C driver source, then compiles libmongocrypt's # dependencies and targets. # # Assumes the current working directory contains libmongocrypt. # So script should be called like: ./libmongocrypt/.evergreen/compile.sh # The current working directory should be empty aside from 'libmongocrypt' # since this script creates new directories/files (e.g. mongo-c-driver, venv). # # NOTE: This script is not meant to be invoked for Evergreen builds. It is a # convenience script for users of libmongocrypt set -o xtrace set -o errexit save_pwd="$(pwd)" . ./libmongocrypt/.evergreen/setup-env.sh . ./libmongocrypt/.evergreen/prep_c_driver_source.sh . ./libmongocrypt/.evergreen/build_all.sh cd ${save_pwd} libmongocrypt-1.3.0/.evergreen/compile_cs.sh000066400000000000000000000017401414105245100211130ustar00rootroot00000000000000# Compiles libmongocrypt dependencies and targets. # # Set extra cflags for libmongocrypt variables by setting LIBMONGOCRYPT_EXTRA_CFLAGS. # set -o xtrace set -o errexit echo "Begin compile process" evergreen_root="$(pwd)" . ${evergreen_root}/libmongocrypt/.evergreen/setup-env.sh cd $evergreen_root if [ "$OS" == "Windows_NT" ]; then # Make sure libbson.dll is in the path on Windows export PATH=${INSTALL_PREFIX}/mongo-c-driver/bin:$PATH for var in TMP TEMP NUGET_PACKAGES NUGET_HTTP_CACHE_PATH APPDATA; do export $var=z:\\data\\tmp; done # Make dotnet happy over ssh export DOTNET_CLI_HOME=$(cygpath -w "${evergreen_root}/dotnet_home") else export PATH=$PATH:/usr/share/dotnet fi dotnet_tool=$(which dotnet) "$dotnet_tool" build -c Release libmongocrypt/cmake-build/bindings/cs/cs.sln "$dotnet_tool" test -c Release libmongocrypt/cmake-build/bindings/cs/MongoDB.Libmongocrypt.Test/MongoDB.Libmongocrypt.Test.csproj -- RunConfiguration.TargetPlatform=x64 libmongocrypt-1.3.0/.evergreen/config.yml000077500000000000000000000753241414105245100204460ustar00rootroot00000000000000# Welcome. Evergreen configuration can be time consuming to modify and test. # So each script has a header comment describing how to run it locally. # # Some environment variables are hidden in the evergreen project config. # View this in Evergreen => Projects => libmongocrypt. # functions: "cleanup environment": - command: shell.exec params: script: | set -o verbose rm -rf ~/.aws ~/.notary_env.sh exit 0 "fetch source": - command: git.get_project params: {directory: libmongocrypt} - command: shell.exec params: script: |- set -o errexit chmod u+x libmongocrypt/.evergreen/*.sh ./libmongocrypt/.evergreen/print-env-info.sh - command: s3.get params: aws_key: '${aws_key}' aws_secret: '${aws_secret}' remote_file: '${project}/${branch_name}/${libmongocrypt_s3_suffix}/mongo-c-driver-src.tar.gz' bucket: mciuploads extract_to: mongo-c-driver "tar and upload libmongocrypt libraries": - command: archive.targz_pack params: target: libmongocrypt.tar.gz source_dir: install/libmongocrypt include: [./**] - command: s3.put params: aws_key: '${aws_key}' aws_secret: '${aws_secret}' remote_file: '${project}/${build_variant}/${branch_name}/${libmongocrypt_s3_suffix}/libmongocrypt.tar.gz' bucket: mciuploads permissions: public-read local_file: 'libmongocrypt.tar.gz' content_type: '${content_type|application/x-gzip}' - command: s3.put params: aws_key: '${aws_key}' aws_secret: '${aws_secret}' remote_file: '${project}/${build_variant}/${branch_name}/${libmongocrypt_s3_suffix_copy}/libmongocrypt.tar.gz' bucket: mciuploads permissions: public-read local_file: 'libmongocrypt.tar.gz' content_type: '${content_type|application/x-gzip}' "build and test": - command: "shell.exec" params: script: |- set -o errexit set -o xtrace ${compile_env|} ./libmongocrypt/.evergreen/build_all.sh ${test_env|} ./libmongocrypt/.evergreen/test.sh cd libmongocrypt ./.evergreen/linker-tests.sh ./.evergreen/pkgconfig-tests.sh "create packages and repos": - command: "shell.exec" params: script: |- set -o xtrace set -o errexit # Find cmake. if [ "$OS" == "Windows_NT" ]; then CMAKE=/cygdrive/c/cmake/bin/cmake else chmod u+x ./mongo-c-driver/.evergreen/find-cmake.sh . ./mongo-c-driver/.evergreen/find-cmake.sh fi # Get current version of libmongocrypt. cd libmongocrypt mongocrypt_version="$($CMAKE -P ./cmake/GetVersion.cmake 2>&1)" cd .. if [ "${has_packages|}" != "true" ] ; then echo "'has_packages' is not 'true', skipping package build" exit 0 fi # check if virtualenv is set up if [ -d "${workdir}/venv" ]; then if [ "Windows_NT" = "$OS" ]; then # Need to quote the path on Windows to preserve the separator. . "${workdir}/venv/Scripts/activate" 2> /tmp/activate_error.log else . ${workdir}/venv/bin/activate 2> /tmp/activate_error.log fi if [ $? -ne 0 ]; then echo "Failed to activate virtualenv: $(cat /tmp/activate_error.log)" fi python=python else python=${python|/opt/mongodbtoolchain/v3/bin/python3} fi if [ "Windows_NT" = "$OS" ]; then export PYTHONPATH="$PYTHONPATH;$(cygpath -w ${workdir}/src)" else export PYTHONPATH="$PYTHONPATH:${workdir}/src" fi PPA_BUILD_ONLY=1 ${compile_env|} ./libmongocrypt/.evergreen/build_all.sh pkg_version=$mongocrypt_version tar -zcv -C install --transform="s|^libmongocrypt/|libmongocrypt-$pkg_version/|" --exclude=nocrypto --exclude=sharedbson -f libmongocrypt-$pkg_version.tar.gz libmongocrypt cd libmongocrypt/etc/ # The files from libmongocrypt/debian/ are the official maintainer scripts, # but libmongocrypt/etc/debian/ contains a few custom scripts that are # meant to support the packager.py workflow. This step "fills in" around # those custom scripts. cp -nr ../debian/* debian/ $python ./packager.py --prefix `pwd`/.. --distros ${packager_distro} --tarball `pwd`/../../libmongocrypt-$pkg_version.tar.gz --library-version $pkg_version --metadata-gitspec HEAD --arches ${packager_arch} cd ../.. - command: archive.targz_pack params: target: libmongocrypt-distro-packages.tar.gz source_dir: libmongocrypt/repo include: [./**] - command: s3.put params: aws_key: '${aws_key}' aws_secret: '${aws_secret}' remote_file: '${project}/${build_variant}/${branch_name}/${libmongocrypt_s3_suffix}/libmongocrypt-distro-packages.tar.gz' bucket: mciuploads permissions: public-read local_file: 'libmongocrypt-distro-packages.tar.gz' content_type: '${content_type|application/x-gzip}' optional: true "run clang-tidy": - command: "shell.exec" params: script: |- ${compile_env|} CONFIGURE_ONLY=ON ./libmongocrypt/.evergreen/build_all.sh ./libmongocrypt/.evergreen/clang-tidy.sh "build and test java": - command: "shell.exec" params: script: |- ${compile_env|} ./libmongocrypt/.evergreen/build_all.sh cd ./libmongocrypt/bindings/java/mongocrypt && ${test_env|} ./.evergreen/test.sh "test python": - command: "shell.exec" params: script: |- export MONGOCRYPT_DIR="$(pwd)/all/${variant_name}" cd ./libmongocrypt/bindings/python && ${test_env|} ./.evergreen/test.sh "build and test node": - command: "subprocess.exec" params: binary: bash working_dir: "./libmongocrypt/bindings/node" args: - "./.evergreen/test.sh" env: PROJECT_DIRECTORY: ${project_directory} NODE_GITHUB_TOKEN: ${node_github_token} DISTRO_ID: ${distro_id} BUILD_VARIANT: ${build_variant} "publish snapshot": - command: shell.exec params: script: |- if [ "${is_patch}" = "true" ]; then echo "Patch build detected, skipping" fi - command: shell.exec params: silent: true script: |- if [ "${is_patch}" = "true" ]; then exit 0 fi cd ./libmongocrypt/bindings/java/mongocrypt && PROJECT_DIRECTORY=${project_directory} NEXUS_USERNAME=${nexus_username} NEXUS_PASSWORD=${nexus_password} SIGNING_PASSWORD=${signing_password} SIGNING_KEY_ID=${signing_keyId} RING_FILE_GPG_BASE64=${ring_file_gpg_base64} ./.evergreen/publish.sh "download tarball": - command: s3.get params: aws_key: '${aws_key}' aws_secret: '${aws_secret}' remote_file: '${project}/${variant_name}/${branch_name}/${libmongocrypt_s3_suffix}/libmongocrypt.tar.gz' bucket: mciuploads extract_to: all/${variant_name} "download distro package tarball": - command: s3.get params: aws_key: '${aws_key}' aws_secret: '${aws_secret}' remote_file: '${project}/${build_variant}/${branch_name}/${libmongocrypt_s3_suffix}/libmongocrypt-distro-packages.tar.gz' bucket: mciuploads extract_to: libmongocrypt/repo "setup packaging credentials": - command: shell.exec params: silent: true script: | set -o errexit if [ "${is_patch}" = "true" ]; then exit 0 fi # set AWS credentials rm -rf ~/.aws mkdir -p ~/.aws cat <> ~/.aws/config [default] region = us-east-1 EOF cat <> ~/.aws/credentials [default] aws_access_key_id = ${repo_aws_key} aws_secret_access_key = ${repo_aws_secret} EOF # set notary credentials rm -f ~/.notary_env.sh cat < ~/.notary_env.sh export NOTARY_TOKEN=${repo_notary_secret} export NOTARY_KEY_NAME=${repo_notary_name} EOF "build csharp and test": - command: "shell.exec" params: script: |- ${compile_env|} ./libmongocrypt/.evergreen/build_all.sh ${test_env|} ./libmongocrypt/.evergreen/test.sh ${compile_env|} ./libmongocrypt/.evergreen/compile_cs.sh tasks: - name: prep-c-driver-source # clone C driver source and calculate build version on a platform with a # recent version of 'git'; the resultant prepared tarball will be used by # build tasks that must build the C driver commands: - command: git.get_project params: {directory: libmongocrypt} - command: "shell.exec" params: script: |- ${compile_env|} ./libmongocrypt/.evergreen/prep_c_driver_source.sh - command: archive.targz_pack params: target: mongo-c-driver-src.tar.gz source_dir: mongo-c-driver include: [./**] - command: s3.put params: aws_key: '${aws_key}' aws_secret: '${aws_secret}' remote_file: '${project}/${branch_name}/${libmongocrypt_s3_suffix}/mongo-c-driver-src.tar.gz' bucket: mciuploads permissions: public-read local_file: 'mongo-c-driver-src.tar.gz' content_type: '${content_type|application/x-gzip}' - name: build-and-test-and-upload depends_on: - variant: ubuntu2004-64 name: prep-c-driver-source commands: - func: "fetch source" - func: "build and test" - func: "tar and upload libmongocrypt libraries" - func: "create packages and repos" - name: clang-tidy depends_on: - variant: ubuntu2004-64 name: prep-c-driver-source commands: - func: "fetch source" - func: "run clang-tidy" - name: build-and-test-shared-bson depends_on: - variant: ubuntu2004-64 name: prep-c-driver-source commands: - func: "fetch source" - func: "build and test" vars: compile_env: LIBMONGOCRYPT_EXTRA_CMAKE_FLAGS="-DENABLE_SHARED_BSON=ON" - name: build-and-test-asan depends_on: - variant: ubuntu2004-64 name: prep-c-driver-source commands: - func: "fetch source" - func: "build and test" vars: compile_env: LIBMONGOCRYPT_EXTRA_CFLAGS="-fsanitize=address -pthread" test_env: ASAN_OPTIONS="detect_leaks=1" LSAN_OPTIONS="suppressions=.lsan-suppressions" - name: build-and-test-asan-mac depends_on: - variant: ubuntu2004-64 name: prep-c-driver-source commands: - func: "fetch source" - func: "build and test" vars: compile_env: LIBMONGOCRYPT_EXTRA_CFLAGS="-fsanitize=address" test_env: LSAN_OPTIONS="suppressions=.lsan-suppressions" - name: build-and-test-asan-s390x depends_on: - variant: ubuntu2004-64 name: prep-c-driver-source commands: - func: "fetch source" - func: "build and test" vars: compile_env: LIBMONGOCRYPT_EXTRA_CFLAGS="-fsanitize=address" test_env: LSAN_OPTIONS="suppressions=.lsan-suppressions" - name: build-and-test-valgrind depends_on: - variant: ubuntu2004-64 name: prep-c-driver-source commands: - func: "fetch source" - func: "build and test" vars: test_env: VALGRIND="valgrind --leak-check=full --error-exitcode=1" - name: build-and-test-java depends_on: - variant: ubuntu2004-64 name: prep-c-driver-source commands: - func: "fetch source" - func: "build and test java" vars: test_env: PROJECT_DIRECTORY=${project_directory} - name: test-python depends_on: - build-and-test-and-upload commands: - func: "fetch source" - func: "download tarball" vars: { variant_name: "${build_variant}" } - func: "test python" vars: { variant_name: "${build_variant}" } - name: test-python-windows depends_on: # Depends on the windows-64-vs2017-test upload. - variant: windows-test name: build-and-test-and-upload commands: - func: "fetch source" - func: "download tarball" vars: { variant_name: windows-test } - func: "test python" vars: { variant_name: windows-test } - name: build-and-test-csharp depends_on: - variant: ubuntu2004-64 name: prep-c-driver-source commands: - func: "fetch source" - func: "build csharp and test" vars: test_env: PROJECT_DIRECTORY=${project_directory} - name: build-and-test-node depends_on: - variant: ubuntu2004-64 name: prep-c-driver-source commands: - func: "fetch source" - func: "build and test node" # Note: keep this disabled unless you want master to force-push - name: build-and-test-node-force-publish depends_on: - variant: ubuntu2004-64 name: prep-c-driver-source commands: - func: "fetch source" - func: "build and test node" - name: publish-snapshot depends_on: - variant: ubuntu2004-64 name: prep-c-driver-source - variant: rhel-62-64-bit name: build-and-test-java - variant: rhel-67-s390x name: build-and-test-and-upload - variant: ubuntu1604-arm64 name: build-and-test-java - variant: macos name: build-and-test-java - variant: windows-test name: build-and-test-and-upload # Todo update once java build passing on windows commands: - func: "fetch source" - func: "publish snapshot" - name: upload-all depends_on: - variant: ubuntu1604 name: build-and-test-and-upload - variant: macos name: build-and-test-and-upload - variant: rhel72-zseries-test name: build-and-test-and-upload - variant: windows-test name: build-and-test-and-upload - variant: linux-64-amazon-ami name: build-and-test-and-upload - variant: amazon2 name: build-and-test-and-upload - variant: debian10 name: build-and-test-and-upload - variant: debian92 name: build-and-test-and-upload - variant: rhel-62-64-bit name: build-and-test-and-upload - variant: rhel-67-s390x name: build-and-test-and-upload - variant: rhel-70-64-bit name: build-and-test-and-upload - variant: rhel-71-ppc64el name: build-and-test-and-upload - variant: rhel-80-64-bit name: build-and-test-and-upload - variant: suse12-64 name: build-and-test-and-upload - variant: suse15-64 name: build-and-test-and-upload - variant: ubuntu1604-arm64 name: build-and-test-and-upload - variant: ubuntu1804-64 name: build-and-test-and-upload - variant: ubuntu1804-arm64 name: build-and-test-and-upload - variant: ubuntu2004-64 name: build-and-test-and-upload - variant: ubuntu2004-arm64 name: build-and-test-and-upload commands: - command: shell.exec params: script: mkdir all - func: "download tarball" vars: { variant_name: ubuntu1604 } - func: "download tarball" vars: { variant_name: "macos" } - func: "download tarball" vars: { variant_name: "rhel72-zseries-test" } - func: "download tarball" vars: { variant_name: "windows-test" } - func: "download tarball" vars: { variant_name: "linux-64-amazon-ami" } - func: "download tarball" vars: { variant_name: "amazon2" } - func: "download tarball" vars: { variant_name: "debian10" } - func: "download tarball" vars: { variant_name: "debian92" } - func: "download tarball" vars: { variant_name: "rhel-62-64-bit" } - func: "download tarball" vars: { variant_name: "rhel-67-s390x" } - func: "download tarball" vars: { variant_name: "rhel-70-64-bit" } - func: "download tarball" vars: { variant_name: "rhel-71-ppc64el" } - func: "download tarball" vars: { variant_name: "rhel-80-64-bit" } - func: "download tarball" vars: { variant_name: "suse12-64" } - func: "download tarball" vars: { variant_name: "suse15-64" } - func: "download tarball" vars: { variant_name: "ubuntu1604-arm64" } - func: "download tarball" vars: { variant_name: "ubuntu1804-64" } - func: "download tarball" vars: { variant_name: "ubuntu1804-arm64" } - func: "download tarball" vars: { variant_name: "ubuntu2004-64" } - func: "download tarball" vars: { variant_name: "ubuntu2004-arm64" } - command: archive.targz_pack params: target: libmongocrypt-all.tar.gz source_dir: all include: [./**] - command: s3.put params: aws_key: '${aws_key}' aws_secret: '${aws_secret}' remote_file: '${project}/all/${branch_name}/${libmongocrypt_s3_suffix}/libmongocrypt-all.tar.gz' bucket: mciuploads permissions: public-read local_file: 'libmongocrypt-all.tar.gz' content_type: '${content_type|application/x-gzip}' - command: s3.put params: aws_key: '${aws_key}' aws_secret: '${aws_secret}' remote_file: '${project}/all/${branch_name}/${libmongocrypt_s3_suffix_copy}/libmongocrypt-all.tar.gz' bucket: mciuploads permissions: public-read local_file: 'libmongocrypt-all.tar.gz' content_type: '${content_type|application/x-gzip}' - name: publish-packages depends_on: build-and-test-and-upload commands: - func: "fetch source" - func: "download distro package tarball" - func: "setup packaging credentials" - command: shell.exec params: working_dir: libmongocrypt script: |- [ -f ~/.notary_env.sh ] && . ~/.notary_env.sh set -o xtrace set -o errexit set -o verbose # Find cmake. if [ "$OS" == "Windows_NT" ]; then CMAKE=/cygdrive/c/cmake/bin/cmake else chmod u+x ../mongo-c-driver/.evergreen/find-cmake.sh . ../mongo-c-driver/.evergreen/find-cmake.sh fi # Get the current version of libmongocrypt. mongocrypt_version="$($CMAKE -P ./cmake/GetVersion.cmake 2>&1)" if [ "${is_patch}" = "true" ]; then echo "patch build, skipping packaging publication" exit 0 fi if [ "${has_packages|}" != "true" ] ; then echo "'has_packages' is not 'true', skipping package publication" exit 0 fi # Need requests and poster for notary-client.py python -m virtualenv venv cd venv . bin/activate ./bin/pip install requests ./bin/pip install poster ./bin/pip install pycrypto cd .. pkg_version=$mongocrypt_version CURATOR_RELEASE=${curator_release|"latest"} curl -L -O http://boxes.10gen.com/build/curator/curator-dist-rhel70-$CURATOR_RELEASE.tar.gz tar -zxvf curator-dist-rhel70-$CURATOR_RELEASE.tar.gz ./curator repo --config etc/repo_config.yaml --distro ${packager_distro} --edition org --version $pkg_version --arch ${packager_arch} --packages repo - name: windows-upload-check depends_on: build-and-test-and-upload commands: - func: "fetch source" - command: shell.exec params: working_dir: libmongocrypt script: |- set -o xtrace set -o errexit CMAKE=/cygdrive/c/cmake/bin/cmake mongocrypt_version="$($CMAKE -P ./cmake/GetVersion.cmake 2>&1)" case "$mongocrypt_version" in *+*) # Not a tagged release. echo "{}" > ./.evergreen/windows-upload.json ;; *-*) # This is an unstable release, like 1.1.0-beta1 or 1.0.1-rc0 cp ./.evergreen/windows-upload-doit-unstable.json ./.evergreen/windows-upload.json ;; *) # It is a tagged release. cp ./.evergreen/windows-upload-doit.json ./.evergreen/windows-upload.json ;; esac - command: generate.tasks params: files: - libmongocrypt/.evergreen/windows-upload.json - name: windows-upload commands: - command: s3.get params: aws_key: '${aws_key}' aws_secret: '${aws_secret}' remote_file: '${project}/windows-test/${branch_name}/${libmongocrypt_s3_suffix}/libmongocrypt.tar.gz' bucket: mciuploads extract_to: libmongocrypt_download - command: shell.exec params: script: |- set -o xtrace set -o errexit # Move just the mongocrypt files needed into the final upload mkdir libmongocrypt_upload mkdir libmongocrypt_upload/bin mkdir libmongocrypt_upload/include mv libmongocrypt_download/bin/mongocrypt.dll libmongocrypt_upload/bin/mongocrypt.dll mv libmongocrypt_download/include/mongocrypt libmongocrypt_upload/include - command: archive.targz_pack params: target: libmongocrypt_upload.tar.gz source_dir: libmongocrypt_upload include: [./**] - command: s3.put params: aws_key: '${aws_key}' aws_secret: '${aws_secret}' remote_file: '${project}/windows/latest_release/libmongocrypt${upload_suffix}.tar.gz' bucket: mciuploads permissions: public-read local_file: 'libmongocrypt_upload.tar.gz' content_type: '${content_type|application/x-gzip}' - name: debian-package-build depends_on: - variant: ubuntu2004-64 name: prep-c-driver-source commands: - func: "fetch source" - command: shell.exec type: test params: working_dir: "libmongocrypt" shell: bash script: |- set -o errexit set -o xtrace export IS_PATCH="${is_patch}" sh .evergreen/debian_package_build.sh - command: s3.put params: aws_key: ${aws_key} aws_secret: ${aws_secret} local_file: deb.tar.gz remote_file: libmongocrypt/${branch_name}/${revision}/${version_id}/${build_id}/${execution}/debian-packages.tar.gz bucket: mciuploads permissions: public-read content_type: ${content_type|application/x-gzip} display_name: "deb.tar.gz" pre: # Update the evergreen expansion to dynamically set the ${libmongocrypt_s3_suffix} and ${libmongocrypt_s3_suffix_copy} expansions. - command: "shell.exec" params: # Uploads are prefixed with ${project}/${build_variant}/${branch_name|all} script: |- if [ "${is_patch}" = "true" ]; then # patch build. REMOTE_SUFFIX="${revision}/${version_id}" REMOTE_SUFFIX_COPY="latest/${version_id}" else # waterfall build, no tag. REMOTE_SUFFIX="${revision}" REMOTE_SUFFIX_COPY="latest" fi PROJECT_DIRECTORY="$(pwd)" echo "libmongocrypt_s3_suffix: $REMOTE_SUFFIX" echo "libmongocrypt_s3_suffix_copy: $REMOTE_SUFFIX_COPY" echo "project_directory: $PROJECT_DIRECTORY" cat < expansion.yml libmongocrypt_s3_suffix: "$REMOTE_SUFFIX" libmongocrypt_s3_suffix_copy: "$REMOTE_SUFFIX_COPY" project_directory: "$PROJECT_DIRECTORY" EOT - command: expansions.update params: file: expansion.yml - func: "cleanup environment" post: - func: "cleanup environment" # NOTE: When adding a new variant, update the "upload-all" task. buildvariants: - name: ubuntu1604 display_name: "Ubuntu 16.04 64-bit" run_on: ubuntu1604-test expansions: has_packages: true packager_distro: ubuntu1604 packager_arch: x86_64 tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-asan - build-and-test-valgrind - build-and-test-java - build-and-test-node - name: publish-packages distros: - ubuntu2004-small - name: macos display_name: "macOS 10.14" run_on: macos-1014 tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-asan-mac - build-and-test-java - build-and-test-node - build-and-test-csharp - test-python - name: rhel72-zseries-test display_name: "RHEL 7.2 on zSeries" run_on: rhel72-zseries-test expansions: has_packages: true packager_distro: rhel72 packager_arch: s390x tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-java - name: publish-packages distros: - rhel70-small - name: windows-vs2015-compile display_name: "Windows VS 2015 compile" run_on: windows-64-vs2015-test tasks: - build-and-test-and-upload - build-and-test-shared-bson - name: windows-test display_name: "Windows 2016" run_on: windows-64-vs2017-test tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-csharp - build-and-test-node - windows-upload-check - name: windows-test-python display_name: "Windows Python" run_on: windows-64-vsMulti-small tasks: - test-python-windows - name: linux-64-amazon-ami display_name: "Amazon Linux" run_on: amazon1-2018-test expansions: has_packages: true packager_distro: amazon packager_arch: x86_64 tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-java - build-and-test-node - name: publish-packages distros: - rhel70-small - name: amazon2 display_name: "Amazon Linux 2" run_on: amazon2-test expansions: has_packages: true packager_distro: amazon2 packager_arch: x86_64 tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-asan - build-and-test-java - build-and-test-node - name: publish-packages distros: - rhel70-small - name: debian10 display_name: "Debian 10.0" run_on: debian10-test expansions: has_packages: true packager_distro: debian10 packager_arch: x86_64 tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-asan - build-and-test-java - build-and-test-node - name: publish-packages distros: - ubuntu2004-small - name: debian92 display_name: "Debian 9.2" run_on: debian92-test expansions: has_packages: true packager_distro: debian92 packager_arch: x86_64 tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-asan - build-and-test-java - build-and-test-node - name: publish-packages distros: - ubuntu2004-small - name: rhel-62-64-bit display_name: "RHEL 6.2 64-bit" run_on: rhel62-small expansions: has_packages: true packager_distro: rhel62 packager_arch: x86_64 tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-java - test-python - name: publish-packages distros: - rhel70-small - name: rhel-67-s390x display_name: "RHEL 6.7 s390x" run_on: rhel67-zseries-test expansions: has_packages: true packager_distro: rhel67 packager_arch: s390x tasks: - build-and-test-and-upload - build-and-test-shared-bson - name: publish-packages distros: - rhel70-small - name: rhel-70-64-bit display_name: "RHEL 7.0 64-bit" run_on: rhel70-small expansions: has_packages: true packager_distro: rhel70 packager_arch: x86_64 tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-java - build-and-test-node - name: publish-packages distros: - rhel70-small - name: rhel-71-ppc64el display_name: "RHEL 7.1 ppc64el" run_on: rhel71-power8-test expansions: has_packages: true packager_distro: rhel71 packager_arch: ppc64le tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-java - name: publish-packages distros: - rhel70-small - name: rhel-80-64-bit display_name: "RHEL 8.0 64-bit" run_on: rhel80-test expansions: has_packages: true packager_distro: rhel80 packager_arch: x86_64 tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-java - build-and-test-node - name: publish-packages distros: - rhel70-small - name: suse12-64 display_name: "SLES 12 64-bit" run_on: suse12-sp5-small expansions: has_packages: true packager_distro: suse12 packager_arch: x86_64 tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-asan - build-and-test-java - build-and-test-node - name: publish-packages distros: - rhel70-small - name: suse15-64 display_name: "SLES 15 64-bit" run_on: suse15-test expansions: has_packages: true packager_distro: suse15 packager_arch: x86_64 tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-asan - build-and-test-java - build-and-test-node - name: publish-packages distros: - rhel70-small - name: ubuntu1604-arm64 display_name: "Ubuntu 16.04 arm64" run_on: ubuntu1604-arm64-large expansions: has_packages: true packager_distro: ubuntu1604 packager_arch: arm64 tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-asan - build-and-test-java - build-and-test-node - name: publish-packages distros: - ubuntu2004-small - name: ubuntu1804-64 display_name: "Ubuntu 18.04 64-bit" run_on: ubuntu1804-test expansions: has_packages: true packager_distro: ubuntu1804 packager_arch: x86_64 tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-asan - build-and-test-java - build-and-test-node - build-and-test-csharp - name: publish-packages distros: - ubuntu2004-small - name: ubuntu1804-arm64 display_name: "Ubuntu 18.04 arm64" run_on: ubuntu1804-arm64-build expansions: has_packages: true packager_distro: ubuntu1804 packager_arch: arm64 tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-asan - build-and-test-java - build-and-test-node - name: publish-packages distros: - ubuntu2004-small - name: ubuntu2004-64 display_name: "Ubuntu 20.04 64-bit" run_on: ubuntu2004-small expansions: has_packages: true packager_distro: ubuntu2004 packager_arch: x86_64 tasks: - clang-tidy - prep-c-driver-source - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-asan - build-and-test-java - build-and-test-node - build-and-test-csharp - publish-packages - name: ubuntu2004-arm64 display_name: "Ubuntu 20.04 arm64" run_on: ubuntu2004-arm64-small expansions: has_packages: true packager_distro: ubuntu2004 packager_arch: arm64 tasks: - build-and-test-and-upload - build-and-test-shared-bson - build-and-test-asan - build-and-test-java - build-and-test-node - name: publish-packages distros: - ubuntu2004-small - name: publish-snapshot display_name: "Publish" run_on: ubuntu1804-test tasks: - name: "publish-snapshot" - name: "upload-all" - name: packaging display_name: "Linux Distro Packaging" run_on: ubuntu2004-small tasks: - name: debian-package-build libmongocrypt-1.3.0/.evergreen/debian_package_build.sh000066400000000000000000000042661414105245100230600ustar00rootroot00000000000000#!/bin/sh # # Test mongocxx's Debian packaging scripts. # # Supported/used environment variables: # IS_PATCH If "true", this is an Evergreen patch build. set -o xtrace set -o errexit on_exit () { if [ -e ./unstable-chroot/debootstrap/debootstrap.log ]; then echo "Dumping debootstrap.log" cat ./unstable-chroot/debootstrap/debootstrap.log fi } trap on_exit EXIT if [ "${IS_PATCH}" = "true" ]; then git diff HEAD -- . ':!debian' > ../upstream.patch git diff HEAD -- debian > ../debian.patch git clean -fdx git reset --hard HEAD if [ -s ../upstream.patch ]; then [ -d debian/patches ] || mkdir debian/patches mv ../upstream.patch debian/patches/ echo upstream.patch >> debian/patches/series git add debian/patches/* git commit -m 'Evergreen patch build - upstream changes' git log -n1 -p fi if [ -s ../debian.patch ]; then git apply --index ../debian.patch git commit -m 'Evergreen patch build - Debian packaging changes' git log -n1 -p fi fi cd .. git clone https://salsa.debian.org/installer-team/debootstrap.git debootstrap.git export DEBOOTSTRAP_DIR=`pwd`/debootstrap.git sudo -E ./debootstrap.git/debootstrap unstable ./unstable-chroot/ http://cdn-aws.deb.debian.org/debian cp -a libmongocrypt ./unstable-chroot/tmp/ sudo chroot ./unstable-chroot /bin/bash -c "(set -o xtrace && \ apt-get install -y build-essential git-buildpackage fakeroot debhelper cmake curl ca-certificates libssl-dev pkg-config libbson-dev && \ cd /tmp/libmongocrypt && \ git clean -fdx && \ git reset --hard HEAD && \ cmake -P ./cmake/GetVersion.cmake > VERSION_CURRENT 2>&1 && \ git add --force VERSION_CURRENT && \ git commit VERSION_CURRENT -m 'Set current version' && \ LANG=C /bin/bash ./debian/build_snapshot.sh && \ debc ../*.changes && \ dpkg -i ../*.deb && \ /usr/bin/gcc -I/usr/include/mongocrypt -I/usr/include/libbson-1.0 -o example-state-machine test/example-state-machine.c -lmongocrypt -lbson-1.0 )" [ -e ./unstable-chroot/tmp/libmongocrypt/example-state-machine ] || (echo "Example 'example-state-machine' was not built!" ; exit 1) (cd ./unstable-chroot/tmp/ ; tar zcvf ../../deb.tar.gz *.dsc *.orig.tar.gz *.debian.tar.xz *.build *.deb) libmongocrypt-1.3.0/.evergreen/linker-tests.sh000077500000000000000000000066761414105245100214420ustar00rootroot00000000000000#!/bin/bash set -o xtrace set -o errexit system_path () { if [ "$OS" == "Windows_NT" ]; then cygpath -a "$1" -w else echo $1 fi } # Directory layout # .evergreen # -linker_tests_deps # --app # --bson_patches # # linker_tests (created by this script) # -libmongocrypt-cmake-build (for artifacts built from libmongocrypt source) # -app-cmake-build # -mongo-c-driver # --cmake-build # -install # --bson1 # --bson2 # --libmongocrypt # if [ ! -e ./.evergreen ]; then echo "Error: run from libmongocrypt root" exit 1; fi libmongocrypt_root=$(pwd) linker_tests_root=${libmongocrypt_root}/linker_tests linker_tests_deps_root=${libmongocrypt_root}/.evergreen/linker_tests_deps rm -rf linker_tests mkdir -p linker_tests/{install,libmongocrypt-cmake-build,app-cmake-build} cd linker_tests # Make libbson1 and libbson2 $libmongocrypt_root/.evergreen/prep_c_driver_source.sh cd mongo-c-driver # Use C driver helper script to find cmake binary, stored in $CMAKE. if [ "$OS" == "Windows_NT" ]; then CMAKE=/cygdrive/c/cmake/bin/cmake ADDITIONAL_CMAKE_FLAGS="-Thost=x64 -A x64" else chmod u+x ./.evergreen/find-cmake.sh . ./.evergreen/find-cmake.sh fi git apply --ignore-whitespace "$(system_path $linker_tests_deps_root/bson_patches/libbson1.patch)" mkdir cmake-build cd cmake-build INSTALL_PATH="$(system_path $linker_tests_root/install/bson1)" SRC_PATH="$(system_path ../)" $CMAKE -DENABLE_MONGOC=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo $ADDITIONAL_CMAKE_FLAGS -DCMAKE_INSTALL_PREFIX="$INSTALL_PATH" "$SRC_PATH" $CMAKE --build . --target install --config RelWithDebInfo # Make libbson2 cd .. git reset --hard git apply --ignore-whitespace "$(system_path $linker_tests_deps_root/bson_patches/libbson2.patch)" cd cmake-build INSTALL_PATH="$(system_path $linker_tests_root/install/bson2)" SRC_PATH="$(system_path ../)" $CMAKE -DENABLE_MONGOC=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo $ADDITIONAL_CMAKE_FLAGS -DCMAKE_INSTALL_PREFIX="$INSTALL_PATH" "$SRC_PATH" $CMAKE --build . --target install --config RelWithDebInfo # Build libmongocrypt, static linking against libbson2 cd $linker_tests_root/libmongocrypt-cmake-build PREFIX_PATH="$(system_path $linker_tests_root/install/bson2)" INSTALL_PATH="$(system_path $linker_tests_root/install/libmongocrypt)" SRC_PATH="$(system_path $libmongocrypt_root)" $CMAKE -DCMAKE_BUILD_TYPE=RelWithDebInfo $ADDITIONAL_CMAKE_FLAGS -DCMAKE_PREFIX_PATH="$PREFIX_PATH" -DCMAKE_INSTALL_PREFIX="$INSTALL_PATH" "$SRC_PATH" $CMAKE --build . --target install --config RelWithDebInfo echo "Test case: Modelling libmongoc's use" # app links against libbson1.so # app links against libmongocrypt.so cd $linker_tests_root/app-cmake-build PREFIX_PATH="$(system_path $linker_tests_root/install/bson1);$(system_path $linker_tests_root/install/libmongocrypt)" SRC_PATH="$(system_path $linker_tests_deps_root/app)" $CMAKE -DCMAKE_BUILD_TYPE=RelWithDebInfo $ADDITIONAL_CMAKE_FLAGS -DCMAKE_PREFIX_PATH="$PREFIX_PATH" "$SRC_PATH" $CMAKE --build . --target app --config RelWithDebInfo if [ "$OS" == "Windows_NT" ]; then export PATH="$PATH:$linker_tests_root/install/bson1/bin:$linker_tests_root/install/libmongocrypt/bin" APP_CMD="./RelWithDebInfo/app.exe" else APP_CMD="./app" fi check_output () { output="$($APP_CMD)" if [[ "$output" != *"$1"* ]]; then echo "got '$output', expecting '$1'" exit 1; fi echo "ok" } check_output ".calling bson_malloc0..from libbson1..calling mongocrypt_binary_new..from libbson2." exit 0 libmongocrypt-1.3.0/.evergreen/linker_tests_deps/000077500000000000000000000000001414105245100221615ustar00rootroot00000000000000libmongocrypt-1.3.0/.evergreen/linker_tests_deps/app/000077500000000000000000000000001414105245100227415ustar00rootroot00000000000000libmongocrypt-1.3.0/.evergreen/linker_tests_deps/app/CMakeLists.txt000066400000000000000000000005051414105245100255010ustar00rootroot00000000000000cmake_minimum_required (VERSION 3.5) project (app C) add_executable (app app.c) find_package (bson-1.0 1.11 REQUIRED) message ("-- libbson found version \"${bson-1.0_VERSION}\"") target_link_libraries (app PRIVATE mongo::bson_static) find_package (mongocrypt REQUIRED) target_link_libraries (app PRIVATE mongo::mongocrypt)libmongocrypt-1.3.0/.evergreen/linker_tests_deps/app/app.c000066400000000000000000000005111414105245100236620ustar00rootroot00000000000000#include #include int main () { char *a; mongocrypt_binary_t *b; printf(".calling bson_malloc0."); a = bson_malloc0 (1); printf(".calling mongocrypt_binary_new."); b = mongocrypt_binary_new (); bson_free (a); mongocrypt_binary_destroy (b); return 0; }libmongocrypt-1.3.0/.evergreen/linker_tests_deps/bson_patches/000077500000000000000000000000001414105245100246315ustar00rootroot00000000000000libmongocrypt-1.3.0/.evergreen/linker_tests_deps/bson_patches/libbson1.patch000066400000000000000000000012661414105245100273700ustar00rootroot00000000000000Adds a printf to bson_malloc0 to test linking scenarios with two forms of libbson. See linker-tests.sh. If this patch fails to apply, regenerate from libbson's source. diff --git a/src/libbson/src/bson/bson-memory.c b/src/libbson/src/bson/bson-memory.c index 0e1523331..aa7112305 100644 --- a/src/libbson/src/bson/bson-memory.c +++ b/src/libbson/src/bson/bson-memory.c @@ -104,6 +104,7 @@ bson_malloc0 (size_t num_bytes) /* IN */ { void *mem = NULL; + printf (".from libbson1."); if (BSON_LIKELY (num_bytes)) { if (BSON_UNLIKELY (!(mem = gMemVtable.calloc (1, num_bytes)))) { fprintf (stderr, "Failure to allocate memory in bson_malloc0(). errno: %d.\n", errno); libmongocrypt-1.3.0/.evergreen/linker_tests_deps/bson_patches/libbson2.patch000066400000000000000000000012701414105245100273640ustar00rootroot00000000000000Adds a printf to bson_malloc0 to test linking scenarios with two forms of libbson. See linker-tests.sh. If this patch fails to apply, regenerate from libbson's source. diff --git a/src/libbson/src/bson/bson-memory.c b/src/libbson/src/bson/bson-memory.c index 0e1523331..aa7112305 100644 --- a/src/libbson/src/bson/bson-memory.c +++ b/src/libbson/src/bson/bson-memory.c @@ -104,6 +104,7 @@ bson_malloc0 (size_t num_bytes) /* IN */ { void *mem = NULL; + printf (".from libbson2.\n"); if (BSON_LIKELY (num_bytes)) { if (BSON_UNLIKELY (!(mem = gMemVtable.calloc (1, num_bytes)))) { fprintf (stderr, "Failure to allocate memory in bson_malloc0(). errno: %d.\n", errno); libmongocrypt-1.3.0/.evergreen/pkgconfig-tests.sh000077500000000000000000000133741414105245100221160ustar00rootroot00000000000000#!/bin/bash set -o xtrace set -o errexit system_path () { if [ "$OS" == "Windows_NT" ]; then cygpath -a "$1" -w else echo $1 fi } if [ ! -e ./.evergreen ]; then echo "Error: run from libmongocrypt root" exit 1; fi if [ ! $(command -v pkg-config) ]; then echo "pkg-config not present on this platform; skipping test ..." exit 0 fi libmongocrypt_root=$(pwd) pkgconfig_tests_root=${libmongocrypt_root}/pkgconfig_tests rm -rf pkgconfig_tests mkdir -p pkgconfig_tests/{install,libmongocrypt-cmake-build} cd pkgconfig_tests $libmongocrypt_root/.evergreen/prep_c_driver_source.sh cd mongo-c-driver # Use C driver helper script to find cmake binary, stored in $CMAKE. if [ "$OS" == "Windows_NT" ]; then CMAKE=/cygdrive/c/cmake/bin/cmake ADDITIONAL_CMAKE_FLAGS="-Thost=x64 -A x64" else chmod u+x ./.evergreen/find-cmake.sh . ./.evergreen/find-cmake.sh fi mkdir cmake-build cd cmake-build INSTALL_PATH="$(system_path $pkgconfig_tests_root/install)" SRC_PATH="$(system_path ../)" $CMAKE -DENABLE_MONGOC=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo $ADDITIONAL_CMAKE_FLAGS -DCMAKE_INSTALL_PREFIX="$INSTALL_PATH" "$SRC_PATH" $CMAKE --build . --target install --config RelWithDebInfo # Build libmongocrypt, static linking against libbson and configured for the PPA cd $pkgconfig_tests_root/libmongocrypt-cmake-build PREFIX_PATH="$(system_path $pkgconfig_tests_root/install)" INSTALL_PATH="$(system_path $pkgconfig_tests_root/install/libmongocrypt)" SRC_PATH="$(system_path $libmongocrypt_root)" $CMAKE -DENABLE_SHARED_BSON=OFF -DENABLE_BUILD_FOR_PPA=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo $ADDITIONAL_CMAKE_FLAGS -DCMAKE_PREFIX_PATH="$PREFIX_PATH" -DCMAKE_INSTALL_PREFIX="$INSTALL_PATH" "$SRC_PATH" $CMAKE --build . --target install --config RelWithDebInfo find ${PREFIX_PATH} -name libbson-static-1.0.a -execdir cp {} $(dirname $(find ${INSTALL_PATH} -name libmongocrypt-static.a )) \; # To validate the pkg-config scripts, we don't want the libbson script to be visible export PKG_CONFIG_PATH="$(system_path $(/usr/bin/dirname $(/usr/bin/find $pkgconfig_tests_root/install/libmongocrypt -name libmongocrypt.pc)))" echo "Validating pkg-config scripts" pkg-config --debug --print-errors --exists libmongocrypt-static pkg-config --debug --print-errors --exists libmongocrypt export PKG_CONFIG_PATH="$(system_path $(/usr/bin/dirname $(/usr/bin/find $pkgconfig_tests_root/install -name libbson-1.0.pc))):$(system_path $(/usr/bin/dirname $(/usr/bin/find $pkgconfig_tests_root/install/libmongocrypt -name libmongocrypt.pc)))" # Build example-state-machine, static linking against libmongocrypt cd $libmongocrypt_root gcc $(pkg-config --cflags libmongocrypt-static libbson-static-1.0) -o example-state-machine test/example-state-machine.c $(pkg-config --libs libmongocrypt-static) ./example-state-machine # Build example-no-bson, static linking against libmongocrypt gcc $(pkg-config --cflags libmongocrypt-static) -o example-no-bson test/example-no-bson.c $(pkg-config --libs libmongocrypt-static) ./example-no-bson rm -f example-state-machine example-no-bson # Build example-state-machine, dynamic linking against libmongocrypt gcc $(pkg-config --cflags libmongocrypt libbson-static-1.0) -o example-state-machine test/example-state-machine.c $(pkg-config --libs libmongocrypt) # Build example-no-bson, dynamic linking against libmongocrypt gcc $(pkg-config --cflags libmongocrypt) -o example-no-bson test/example-no-bson.c $(pkg-config --libs libmongocrypt) export LD_LIBRARY_PATH="$(system_path $pkgconfig_tests_root/install/libmongocrypt/lib):$(system_path $pkgconfig_tests_root/install/libmongocrypt/lib64)" ./example-state-machine ./example-no-bson unset LD_LIBRARY_PATH rm -f example-state-machine example-no-bson # Clean up prior to next execution cd $pkgconfig_tests_root rm -rf libmongocrypt-cmake-build install/libmongocrypt mkdir -p libmongocrypt-cmake-build # Build libmongocrypt, dynamic linking against libbson cd $pkgconfig_tests_root/libmongocrypt-cmake-build PREFIX_PATH="$(system_path $pkgconfig_tests_root/install)" INSTALL_PATH="$(system_path $pkgconfig_tests_root/install/libmongocrypt)" SRC_PATH="$(system_path $libmongocrypt_root)" $CMAKE -DENABLE_SHARED_BSON=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo $ADDITIONAL_CMAKE_FLAGS -DCMAKE_PREFIX_PATH="$PREFIX_PATH" -DCMAKE_INSTALL_PREFIX="$INSTALL_PATH" "$SRC_PATH" $CMAKE --build . --target install --config RelWithDebInfo # Build example-state-machine, static linking against libmongocrypt cd $libmongocrypt_root gcc $(pkg-config --cflags libmongocrypt-static libbson-static-1.0) -o example-state-machine test/example-state-machine.c $(pkg-config --libs libmongocrypt-static) # Build example-no-bson, static linking against libmongocrypt gcc $(pkg-config --cflags libmongocrypt-static) -o example-no-bson test/example-no-bson.c $(pkg-config --libs libmongocrypt-static) export LD_LIBRARY_PATH="$(system_path $pkgconfig_tests_root/install/lib):$(system_path $pkgconfig_tests_root/install/lib64)" ./example-state-machine ./example-no-bson unset LD_LIBRARY_PATH rm -f example-state-machine example-no-bson # Build example-state-machine, dynamic linking against libmongocrypt gcc $(pkg-config --cflags libmongocrypt libbson-static-1.0) -o example-state-machine test/example-state-machine.c $(pkg-config --libs libmongocrypt) # Build example-no-bson, dynamic linking against libmongocrypt gcc $(pkg-config --cflags libmongocrypt) -o example-no-bson test/example-no-bson.c $(pkg-config --libs libmongocrypt) export LD_LIBRARY_PATH="$(system_path $pkgconfig_tests_root/install/lib):$(system_path $pkgconfig_tests_root/install/lib64):$(system_path $pkgconfig_tests_root/install/libmongocrypt/lib):$(system_path $pkgconfig_tests_root/install/libmongocrypt/lib64)" ./example-state-machine ./example-no-bson unset LD_LIBRARY_PATH rm -f example-state-machine example-no-bson libmongocrypt-1.3.0/.evergreen/prep_c_driver_source.sh000077500000000000000000000006401414105245100232020ustar00rootroot00000000000000#!/bin/bash set -o xtrace set -o errexit # Clone mongo-c-driver and check out to a tagged version. MONGO_C_DRIVER_VERSION=1.17.0 # Force checkout with lf endings since .sh must have lf, not crlf on Windows git clone git@github.com:mongodb/mongo-c-driver.git --config core.eol=lf --config core.autocrlf=false --depth=1 --branch $MONGO_C_DRIVER_VERSION echo $MONGO_C_DRIVER_VERSION > mongo-c-driver/VERSION_CURRENT libmongocrypt-1.3.0/.evergreen/print-env-info.sh000077500000000000000000000003441414105245100216530ustar00rootroot00000000000000#!/bin/bash # Print information about the environment. # set -o xtrace evergreen_root=$(pwd) git --version openssl version python --version if which gcc; then gcc --version fi if which clang; then clang --version filibmongocrypt-1.3.0/.evergreen/requirements.txt000077500000000000000000000000121414105245100217200ustar00rootroot00000000000000virtualenvlibmongocrypt-1.3.0/.evergreen/setup-env.sh000066400000000000000000000006631414105245100207270ustar00rootroot00000000000000#!/bin/bash evergreen_root="$(pwd)" [ -d "${BSON_INSTALL_PREFIX:=${evergreen_root}/install/mongo-c-driver}" ] || mkdir -p "${BSON_INSTALL_PREFIX}" [ -d "${MONGOCRYPT_INSTALL_PREFIX:=${evergreen_root}/install/libmongocrypt}" ] || mkdir -p "${MONGOCRYPT_INSTALL_PREFIX}" if [ "$OS" == "Windows_NT" ]; then BSON_INSTALL_PREFIX=$(cygpath -w $BSON_INSTALL_PREFIX) MONGOCRYPT_INSTALL_PREFIX=$(cygpath -w $MONGOCRYPT_INSTALL_PREFIX) fi libmongocrypt-1.3.0/.evergreen/test.sh000077500000000000000000000026441414105245100177640ustar00rootroot00000000000000#!/bin/bash # # Sets up a testing environment and runs test_kms_request and test-mongocrypt. # # Assumes the current working directory contains libmongocrypt. # So script should be called like: ./libmongocrypt/.evergreen/test.sh # The current working directory should be empty aside from 'libmongocrypt'. # # Set the VALGRIND environment variable to "valgrind " to run through valgrind. # set -o errexit set -o xtrace evergreen_root="$(pwd)" . ${evergreen_root}/libmongocrypt/.evergreen/setup-env.sh BIN_DIR=./cmake-build KMS_BIN_DIR=./cmake-build/kms-message NOCRYPTO_BIN_DIR=./cmake-build-nocrypto if [ "Windows_NT" == "$OS" ]; then BIN_DIR=./cmake-build/RelWithDebInfo KMS_BIN_DIR=./cmake-build/kms-message/RelWithDebInfo NOCRYPTO_BIN_DIR=./cmake-build-nocrypto/RelWithDebInfo # Make sure libbson dll is in the path export PATH=${BSON_INSTALL_PREFIX}/bin:$PATH fi echo "Running kms-message tests." cd libmongocrypt/kms-message $VALGRIND ../${KMS_BIN_DIR}/test_kms_request cd ../.. echo "Running libmongocrypt tests." cd libmongocrypt MONGOCRYPT_TRACE=ON $VALGRIND ${BIN_DIR}/test-mongocrypt echo "Running example state machine." $VALGRIND ${BIN_DIR}/example-state-machine echo "Running example state machine (statically linked)." $VALGRIND ${BIN_DIR}/example-state-machine-static echo "Running libmongocrypt tests with no native crypto" MONGOCRYPT_TRACE=ON $VALGRIND ${NOCRYPTO_BIN_DIR}/test-mongocrypt cd .. libmongocrypt-1.3.0/.evergreen/windows-upload-doit-unstable.json000066400000000000000000000006521414105245100250620ustar00rootroot00000000000000{ "buildvariants": [ { "tasks": [ { "name": "windows-upload" } ], "display_name": "Windows uploader", "run_on": [ "windows-64-vs2017-test" ], "name": "windows-uploader", "expansions": { "upload_suffix": "_unstable" } } ] }libmongocrypt-1.3.0/.evergreen/windows-upload-doit.json000066400000000000000000000005221414105245100232430ustar00rootroot00000000000000{ "buildvariants": [ { "tasks": [ { "name": "windows-upload" } ], "display_name": "Windows uploader", "run_on": [ "windows-64-vs2017-test" ], "name": "windows-uploader" } ] }libmongocrypt-1.3.0/.gitattributes000066400000000000000000000000771414105245100172770ustar00rootroot00000000000000# Shell scripts require lf endings *.sh text eol=lf libmongocrypt-1.3.0/.gitignore000066400000000000000000000010431414105245100163660ustar00rootroot00000000000000doc/html doc/latex test/schema.json .vscode # Default build directories cmake-build cmake-build-nocrypto # CMake generated files *.sln *.vcxproj *.vcxproj.filters *.xcodeproj CMakeCache.txt CTestTestFile.cmake CMakeFiles CMakeScripts Debug/* Makefile Win32/* cmake_install.cmake x64/* Testing/ CPackConfig.cmake CPackSourceConfig.cmake dist_manifest.txt *.sdf .vs install_manifest.txt # Build artifacts. *.a *.dylib *.gcda *.gcno *.gz *.lo *.o *.pc *.so *.so.* # Generated header src/mongocrypt-export.h # IDEs .idea/ VERSION_CURRENT .csflelibmongocrypt-1.3.0/.lsan-suppressions000066400000000000000000000001041414105245100201040ustar00rootroot00000000000000leak:ccrng_cryptographic_init_once leak:ccrng_cryptographic_generatelibmongocrypt-1.3.0/CHANGELOG.md000066400000000000000000000034141414105245100162130ustar00rootroot00000000000000# ChangeLog ## 1.3.0 - Support "kmip" KMS provider. - Add mongocrypt_kms_ctx_get_kms_provider. - Apply default port to endpoints returned in mongocrypt_kms_ctx_endpoint ## 1.2.2 - Fix pkg-config and PPA build dependency on libbson. - Fix JSON schema caching behavior when server reports no JSON schema. ## 1.2.1 ### Fixed - Fix possible crash when oauth credentials expire. ## 1.2.0 ### Added - Support AWS temporary credentials via session token. ### Fixed - Add "=" padding to base64url encoding. ## 1.1.0 ### Added - Add ENABLE_PIC cmake option, set to ON by default, so static libraries build with -fPIC by default on relevant systems. ### Fixed - Errors produced in all crypto callbacks are propagated to user. ## 1.1.0-beta1 ### Deprecated - mongocrypt_setopt_kms_provider_aws and mongocrypt_setopt_kms_provider_local are deprecated in favor of the more flexible mongocrypt_setopt_kms_providers, which supports configuration of all KMS providers. - mongocrypt_ctx_setopt_masterkey_aws, mongocrypt_ctx_setopt_masterkey_aws_endpoint, and mongocrypt_ctx_setopt_masterkey_local are deprecated in favor of the more flexible mongocrypt_ctx_setopt_key_encryption_key, which supports configuration for all KMS providers. ### Added - Introduces a new crypto hook for signing the JSON Web Token (JWT) for Google Cloud Platform (GCP) requests: - mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5 - Introduces a CLI utility `csfle` to test the context state machine against live KMS, mongocryptd, and mongod. See ./test/util/README.md. - Introduces two new functions to the libmongocrypt API. - mongocrypt_setopt_kms_providers To set the KMS providers. - mongocrypt_ctx_setopt_key_encryption_key To set the key encryption key. - Adds support for Azure and GCP KMS providers.libmongocrypt-1.3.0/CMakeLists.txt000066400000000000000000000412231414105245100171420ustar00rootroot00000000000000cmake_minimum_required (VERSION 3.5) if (CMAKE_VERSION VERSION_EQUAL 3.12 OR CMAKE_VERSION VERSION_GREATER 3.12) project (mongocrypt C) else () # GenerateExportHeader only works with C with 3.12 - https://gitlab.kitware.com/cmake/cmake/commit/de348a9638bd51af4523f36c68884b901d4aff18 project (mongocrypt C CXX) endif () set (CMAKE_C_STANDARD 99) option (ENABLE_SHARED_BSON "Dynamically link libbson (default is static)" OFF) option (ENABLE_STATIC "Install static libraries" ON) option (ENABLE_PIC "Enables building of position independent code for static library components." ON ) option (ENABLE_BUILD_FOR_PPA "Maintainer-only option for preparing PPA build" OFF) if (ENABLE_SHARED_BSON AND ENABLE_BUILD_FOR_PPA) message (FATAL_ERROR "PPA build requires static linking to libbson") endif () set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake) # Attempt to find libbson by new package name. find_package (bson-1.0 1.11 QUIET) if (bson-1.0_FOUND) message ("-- libbson found version \"${bson-1.0_VERSION}\"") set (BSON_TARGET mongo::bson_static) if (ENABLE_SHARED_BSON) set (BSON_TARGET mongo::bson_shared) endif () elseif (ENABLE_SHARED_BSON) # Try old package name for libbson. find_package (libbson-1.0 1.11 REQUIRED) message ("-- libbson found version \"${BSON_VERSION}\"") message ("-- libbson include path \"${BSON_INCLUDE_DIRS}\"") message ("-- libbson libraries \"${BSON_LIBRARIES}\"") set (BSON_TARGET ${BSON_LIBRARIES}) set (BSON_INCLUDES ${BSON_INCLUDE_DIRS}) set (BSON_DEFINITIONS ${BSON_DEFINITIONS}) else () # Try old package name for libbson. find_package (libbson-static-1.0 1.11 REQUIRED) message ("-- libbson-static found version \"${BSON_STATIC_VERSION}\"") message ("-- libbson-static include path \"${BSON_STATIC_INCLUDE_DIRS}\"") message ("-- libbson-static libraries \"${BSON_STATIC_LIBRARIES}\"") set (BSON_TARGET ${BSON_STATIC_LIBRARIES}) set (BSON_INCLUDES ${BSON_STATIC_INCLUDE_DIRS}) set (BSON_DEFINITIONS ${BSON_STATIC_DEFINITIONS}) endif () find_package ( Threads REQUIRED ) add_subdirectory (bindings/cs) include (GenerateExportHeader) include (GNUInstallDirs) enable_testing () set (MONGOCRYPT_PUBLIC_HEADERS src/mongocrypt-compat.h ) set (MONGOCRYPT_SOURCES src/crypto/cng.c src/crypto/commoncrypto.c src/crypto/libcrypto.c src/crypto/none.c src/mongocrypt-binary.c src/mongocrypt-buffer.c src/mongocrypt-cache.c src/mongocrypt-cache-collinfo.c src/mongocrypt-cache-key.c src/mongocrypt-cache-oauth.c src/mongocrypt-ciphertext.c src/mongocrypt-crypto.c src/mongocrypt-ctx-datakey.c src/mongocrypt-ctx-decrypt.c src/mongocrypt-ctx-encrypt.c src/mongocrypt-ctx.c src/mongocrypt-endpoint.c src/mongocrypt-kek.c src/mongocrypt-key.c src/mongocrypt-key-broker.c src/mongocrypt-kms-ctx.c src/mongocrypt-log.c src/mongocrypt-marking.c src/mongocrypt-opts.c src/mongocrypt-status.c src/mongocrypt-traverse-util.c src/mongocrypt-util.c src/mongocrypt.c src/os_win/os_mutex.c src/os_win/os_once.c src/os_posix/os_mutex.c src/os_posix/os_once.c ) if ( MSVC ) # W4996 - POSIX name for this item is deprecated set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3 /wd4996 /D_CRT_SECURE_NO_WARNINGS /WX") # TODO: add support for clang-cl which is detected as MSVC else () # GNU, Clang, AppleClang set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wno-missing-braces") endif () # Choose a Crypto provider set (MONGOCRYPT_CRYPTO OpenSSL) if (APPLE) set (MONGOCRYPT_CRYPTO CommonCrypto) elseif (WIN32) set (MONGOCRYPT_CRYPTO CNG) endif () # Otherwise, override with crypto hooks. if (DISABLE_NATIVE_CRYPTO) set (MONGOCRYPT_CRYPTO none) endif () set (MONGOCRYPT_ENABLE_CRYPTO 0) set (MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO 0) set (MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO 0) set (MONGOCRYPT_ENABLE_CRYPTO_CNG 0) if (MONGOCRYPT_CRYPTO STREQUAL CommonCrypto) message ("Building with common crypto") set (MONGOCRYPT_ENABLE_CRYPTO 1) set (MONGOCRYPT_ENABLE_CRYPTO_COMMON_CRYPTO 1) elseif (MONGOCRYPT_CRYPTO STREQUAL CNG) message ("Building with CNG") set (MONGOCRYPT_ENABLE_CRYPTO 1) set (MONGOCRYPT_ENABLE_CRYPTO_CNG 1) elseif (MONGOCRYPT_CRYPTO STREQUAL OpenSSL) message ("Building with OpenSSL") include (FindOpenSSL) message ("Found OpenSSL version ${OPENSSL_VERSION}") set (MONGOCRYPT_ENABLE_CRYPTO 1) set (MONGOCRYPT_ENABLE_CRYPTO_LIBCRYPTO 1) elseif (MONGOCRYPT_CRYPTO STREQUAL none) message ("Building with no native crypto, hooks MUST be supplied with mongocrypt_setopt_crypto_hooks") else () message (FATAL_ERROR "Unknown crypto provider ${MONGOCRYPT_CRYPTO}") endif () set (MONGOCRYPT_ENABLE_TRACE 0) if (ENABLE_TRACE) message (WARNING "Building with trace logging. This is highly insecure. Do not use in a production environment") set (MONGOCRYPT_ENABLE_TRACE 1) endif () configure_file ( "${PROJECT_SOURCE_DIR}/src/mongocrypt-config.h.in" "${PROJECT_BINARY_DIR}/src/mongocrypt-config.h" ) # kms-message add_subdirectory (kms-message) # Define mongocrypt library add_library (mongocrypt SHARED ${MONGOCRYPT_SOURCES}) target_include_directories (mongocrypt PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/kms-message/src") target_include_directories (mongocrypt PUBLIC $) target_include_directories (mongocrypt PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src") target_include_directories (mongocrypt PRIVATE ${BSON_INCLUDES}) target_compile_definitions (mongocrypt PRIVATE ${BSON_DEFINITIONS}) target_link_libraries (mongocrypt PRIVATE ${BSON_TARGET}) target_link_libraries (mongocrypt PRIVATE ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries (mongocrypt PRIVATE kms_message_static) if (NOT ENABLE_SHARED_BSON) if (APPLE) message ("compiling with unexported symbols list to hide bson symbols") set_target_properties (mongocrypt PROPERTIES LINK_FLAGS "-Wl,-unexported_symbols_list,\"${CMAKE_CURRENT_SOURCE_DIR}/cmake/libmongocrypt-hidden-symbols.txt\"") elseif (UNIX) message ("compiling with version map to version and hide bson symbols") set_target_properties (mongocrypt PROPERTIES LINK_FLAGS "-Wl,--version-script=\"${CMAKE_CURRENT_SOURCE_DIR}/cmake/libmongocrypt-hidden-symbols.map\"") endif () endif () generate_export_header (mongocrypt EXPORT_FILE_NAME src/mongocrypt-export.h BASE_NAME mongocrypt ) add_library (mongocrypt_static STATIC ${MONGOCRYPT_SOURCES}) # Checking CMAKE_C_FLAGS for -fPIC is not a foolproof way of checking whether # -fPIC was set as a compiler flag. However, users were instructed before to # pass -fPIC through CMAKE_C_FLAGS. This will prevent redundant output in # the common case that users are setting -DCMAKE_C_FLAGS='-fPIC' string (FIND "${CMAKE_C_FLAGS}" "-fPIC" FPIC_LOCATION) if (NOT WIN32 AND ENABLE_PIC AND "${FPIC_LOCATION}" EQUAL "-1") target_compile_options (mongocrypt_static PUBLIC -fPIC) message ("Adding -fPIC to compilation of mongocrypt_static components") endif () target_include_directories (mongocrypt_static PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/kms-message/src") target_include_directories (mongocrypt_static PUBLIC $) target_include_directories (mongocrypt_static PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src") target_include_directories (mongocrypt_static PRIVATE ${BSON_INCLUDES}) target_compile_definitions (mongocrypt_static PRIVATE ${BSON_DEFINITIONS}) set (PKG_CONFIG_STATIC_LIBS "\${prefix}/${CMAKE_INSTALL_LIBDIR}/libmongocrypt-static.a") target_link_libraries (mongocrypt_static PRIVATE ${BSON_TARGET}) target_link_libraries (mongocrypt_static PRIVATE ${CMAKE_THREAD_LIBS_INIT}) set (PKG_CONFIG_STATIC_LIBS "${PKG_CONFIG_STATIC_LIBS} ${CMAKE_THREAD_LIBS_INIT}") target_link_libraries (mongocrypt_static PRIVATE kms_message_static) set (PKG_CONFIG_STATIC_LIBS "${PKG_CONFIG_STATIC_LIBS} \${prefix}/${CMAKE_INSTALL_LIBDIR}/libkms_message-static.a") if (ENABLE_BUILD_FOR_PPA) set (PKG_CONFIG_STATIC_LIBS "${PKG_CONFIG_STATIC_LIBS} \${prefix}/${CMAKE_INSTALL_LIBDIR}/libbson-static-1.0.a") #librt needed for libbson on linux for clock_gettime find_library (RT_LIBRARY rt) if (RT_LIBRARY) set (PKG_CONFIG_STATIC_LIBS "${PKG_CONFIG_STATIC_LIBS} ${RT_LIBRARY}") endif () set (PKG_CONFIG_STATIC_LIBS "${PKG_CONFIG_STATIC_LIBS} -pthread") endif () target_compile_definitions (mongocrypt_static PUBLIC MONGOCRYPT_STATIC_DEFINE KMS_MSG_STATIC) if (ENABLE_WINDOWS_STATIC_RUNTIME) target_compile_options (mongocrypt_static PUBLIC /MT) target_compile_options (kms_message_static PUBLIC /MT) endif () if (MONGOCRYPT_CRYPTO STREQUAL CommonCrypto) target_link_libraries (mongocrypt PRIVATE "-framework CoreFoundation -framework Security") target_link_libraries (mongocrypt_static PRIVATE "-framework CoreFoundation -framework Security") set (PKG_CONFIG_STATIC_LIBS "${PKG_CONFIG_STATIC_LIBS} -framework CoreFoundation -framework Security") elseif (MONGOCRYPT_CRYPTO STREQUAL CNG) target_link_libraries (mongocrypt PRIVATE "bcrypt") target_link_libraries (mongocrypt_static PRIVATE "bcrypt") set (PKG_CONFIG_STATIC_LIBS "${PKG_CONFIG_STATIC_LIBS} -lbcrypt") elseif (MONGOCRYPT_CRYPTO STREQUAL OpenSSL) target_link_libraries (mongocrypt PRIVATE OpenSSL::SSL OpenSSL::Crypto) target_link_libraries (mongocrypt_static PRIVATE OpenSSL::SSL OpenSSL::Crypto) set (PKG_CONFIG_STATIC_LIBS "${PKG_CONFIG_STATIC_LIBS} -lssl -lcrypto") endif () set_target_properties (mongocrypt PROPERTIES SOVERSION 0 VERSION "0.0.0" OUTPUT_NAME "mongocrypt" ) set_target_properties (mongocrypt_static PROPERTIES SOVERSION 0 VERSION "0.0.0" OUTPUT_NAME "mongocrypt-static" ) set (TEST_MONGOCRYPT_SOURCES test/test-mongocrypt-assert-match-bson.c test/test-mongocrypt-buffer.c test/test-mongocrypt-cache.c test/test-mongocrypt-cache-oauth.c test/test-mongocrypt-ciphertext.c test/test-mongocrypt-crypto.c test/test-mongocrypt-crypto-hooks.c test/test-mongocrypt-ctx-decrypt.c test/test-mongocrypt-ctx-encrypt.c test/test-mongocrypt-ctx-setopt.c test/test-mongocrypt-datakey.c test/test-mongocrypt-endpoint.c test/test-mongocrypt-kek.c test/test-mongocrypt-key.c test/test-mongocrypt-key-broker.c test/test-mongocrypt-key-cache.c test/test-mongocrypt-kms-ctx.c test/test-mongocrypt-kms-responses.c test/test-mongocrypt-local-kms.c test/test-mongocrypt-log.c test/test-mongocrypt-marking.c test/test-mongocrypt-status.c test/test-mongocrypt-traverse-util.c test/test-mongocrypt-util.c test/test-mongocrypt.c ) # Define test-mongocrypt add_executable (test-mongocrypt ${TEST_MONGOCRYPT_SOURCES}) # Use the static version since it allows the test binary to use private symbols target_link_libraries (test-mongocrypt PRIVATE mongocrypt_static) target_include_directories (test-mongocrypt PRIVATE ./src "${CMAKE_CURRENT_SOURCE_DIR}/kms-message/src") target_link_libraries (test-mongocrypt PRIVATE ${BSON_TARGET}) target_include_directories (test-mongocrypt PRIVATE ${BSON_INCLUDES}) target_compile_definitions (test-mongocrypt PRIVATE ${BSON_DEFINITIONS}) add_test (mongocrypt test-mongocrypt WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) # Exclude example-state-machine since it requires native crypto. if (NOT MONGOCRYPT_CRYPTO STREQUAL none) # Define example-state-machine add_executable (example-state-machine test/example-state-machine.c) target_link_libraries (example-state-machine PRIVATE mongocrypt ${BSON_TARGET}) target_include_directories (example-state-machine PRIVATE ${BSON_INCLUDES}) target_compile_definitions (example-state-machine PRIVATE ${BSON_DEFINITIONS}) target_include_directories (example-state-machine PRIVATE ./src "${CMAKE_CURRENT_SOURCE_DIR}/kms-message/src") # Define example-state-machine-static add_executable (example-state-machine-static test/example-state-machine.c) target_link_libraries (example-state-machine-static PRIVATE mongocrypt_static ${BSON_TARGET}) target_include_directories (example-state-machine-static PRIVATE ${BSON_INCLUDES}) target_compile_definitions (example-state-machine-static PRIVATE ${BSON_DEFINITIONS}) target_include_directories (example-state-machine-static PRIVATE ./src) find_package (mongoc-1.0) if (ENABLE_ONLINE_TESTS AND mongoc-1.0_FOUND) message ("compiling utilities") add_executable (csfle test/util/csfle.c test/util/util.c) target_link_libraries (csfle PRIVATE mongocrypt_static) target_include_directories (csfle PRIVATE ${CMAKE_BINARY_DIR}/src) target_include_directories (csfle PRIVATE ./src) target_include_directories (csfle PRIVATE ./kms-message/src) target_link_libraries (csfle PRIVATE mongo::mongoc_shared) endif () endif () if (ENABLE_STATIC) set (TARGETS_TO_INSTALL mongocrypt mongocrypt_static) else () set (TARGETS_TO_INSTALL mongocrypt) endif () install ( TARGETS ${TARGETS_TO_INSTALL} EXPORT mongocrypt_targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) install ( FILES ${MONGOCRYPT_PUBLIC_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/src/mongocrypt.h ${CMAKE_CURRENT_BINARY_DIR}/src/mongocrypt-config.h ${CMAKE_CURRENT_BINARY_DIR}/src/mongocrypt-export.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mongocrypt COMPONENT Devel ) set (BUILD_VERSION "0.0.0" CACHE STRING "Library version") if (BUILD_VERSION STREQUAL "0.0.0") if (EXISTS ${PROJECT_SOURCE_DIR}/VERSION_CURRENT) file (STRINGS ${PROJECT_SOURCE_DIR}/VERSION_CURRENT BUILD_VERSION) message ("file VERSION_CURRENT contained BUILD_VERSION ${BUILD_VERSION}") else () include (GetVersion) GetVersion (BUILD_VERSION) message ("storing BUILD_VERSION ${BUILD_VERSION} in file VERSION_CURRENT for later use") file (WRITE ${PROJECT_SOURCE_DIR}/VERSION_CURRENT ${BUILD_VERSION}) endif () else () message ("storing BUILD_VERSION ${BUILD_VERSION} in file VERSION_CURRENT for later use") file (WRITE ${PROJECT_SOURCE_DIR}/VERSION_CURRENT ${BUILD_VERSION}) endif () message ("Configuring libmongocrypt version ${BUILD_VERSION}") set (MONGOCRYPT_BUILD_VERSION ${BUILD_VERSION}) configure_file (src/mongocrypt.h.in src/mongocrypt.h) set (PROJECT_VERSION "${BUILD_VERSION}") set (PROJECT_DESCRIPTION "The libmongocrypt client-side field level encryption library.") if (NOT ENABLE_BUILD_FOR_PPA) set (PKG_CONFIG_STATIC_REQUIRES "libbson-static-1.0") endif () if (ENABLE_SHARED_BSON) set (PKG_CONFIG_REQUIRES "libbson-1.0") set (PKG_CONFIG_STATIC_REQUIRES "libbson-1.0") endif () set (PKG_CONFIG_LIBDIR "\${prefix}/${CMAKE_INSTALL_LIBDIR}") set (PKG_CONFIG_INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}/mongocrypt") set (PKG_CONFIG_LIBS "-L\${libdir} -lmongocrypt") if (ENABLE_BUILD_FOR_PPA) set (PKG_CONFIG_LIBS "${PKG_CONFIG_LIBS} \${prefix}/${CMAKE_INSTALL_LIBDIR}/libbson-static-1.0.a") #librt needed for libbson on linux for clock_gettime find_library (RT_LIBRARY rt) if (RT_LIBRARY) set (PKG_CONFIG_LIBS "${PKG_CONFIG_LIBS} ${RT_LIBRARY}") endif () set (PKG_CONFIG_LIBS "${PKG_CONFIG_LIBS} -pthread") endif () set (PKG_CONFIG_CFLAGS "-I\${includedir}") set (PKG_CONFIG_STATIC_CFLAGS "${PKG_CONFIG_CFLAGS} -DMONGOCRYPT_STATIC_DEFINE -DKMS_MSG_STATIC") configure_file ( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/libmongocrypt.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libmongocrypt.pc" ) configure_file ( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/libmongocrypt-static.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/libmongocrypt-static.pc" ) install ( FILES "${CMAKE_BINARY_DIR}/libmongocrypt.pc" DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) if (ENABLE_STATIC) install ( FILES "${CMAKE_BINARY_DIR}/libmongocrypt-static.pc" DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) endif () include (CMakePackageConfigHelpers) set (INCLUDE_INSTALL_DIRS "${CMAKE_INSTALL_INCLUDEDIR}/mongocrypt") set (LIBRARY_INSTALL_DIRS ${CMAKE_INSTALL_LIBDIR}) write_basic_package_version_file ( "${CMAKE_CURRENT_BINARY_DIR}/mongocrypt/mongocrypt-config-version.cmake" COMPATIBILITY AnyNewerVersion ) export (EXPORT mongocrypt_targets NAMESPACE mongo:: FILE "${CMAKE_CURRENT_BINARY_DIR}/mongocrypt/mongocrypt_targets.cmake" ) configure_file (cmake/mongocrypt-config.cmake "${CMAKE_CURRENT_BINARY_DIR}/mongocrypt/mongocrypt-config.cmake" COPYONLY ) install (EXPORT mongocrypt_targets NAMESPACE mongo:: FILE mongocrypt_targets.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mongocrypt ) install ( FILES cmake/mongocrypt-config.cmake "${CMAKE_CURRENT_BINARY_DIR}/mongocrypt/mongocrypt-config-version.cmake" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mongocrypt COMPONENT Devel ) libmongocrypt-1.3.0/CODEOWNERS000066400000000000000000000004251414105245100157740ustar00rootroot00000000000000# Code Owners will automatically be added as reviewers on PRs # NodeJS Bindings bindings/node @nbbeeken @emadum @durran # Python Bindings bindings/python @ShaneHarvey @prashantmital # Java Bindings bindings/java @jyemin @rozza # CSharp Bindings bindings/cs @DmitryLukyanov libmongocrypt-1.3.0/LICENSE000066400000000000000000000261341414105245100154130ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.libmongocrypt-1.3.0/README.md000066400000000000000000000233031414105245100156600ustar00rootroot00000000000000# libmongocrypt # The companion C library for client side encryption in drivers. # Bugs / Feature Requests # If you have encountered a bug, or would like to see a new feature in libmongocrypt, please open a case in our issue management tool, JIRA: - [Create an account and login](https://jira.mongodb.org). - Navigate to [the MONGOCRYPT project](https://jira.mongodb.org/projects/MONGOCRYPT). - Click **Create Issue** - Please provide as much information as possible about the issue type and how to reproduce it. ## Documentation ## See [The Integration Guide](integrating.md) to integrate with your driver. See [mongocrypt.h.in](src/mongocrypt.h.in) for the public API reference. The documentation can be rendered into HTML with doxygen. Run `doxygen ./doc/Doxygen`, then open `./doc/html/index.html`. ## Building libmongocrypt ## First build the following dependencies: 1. [The BSON library (part of the C driver)](https://github.com/mongodb/mongo-c-driver), consisting of libbson. Build it from source. ``` git clone https://github.com/mongodb/mongo-c-driver cd mongo-c-driver mkdir cmake-build && cd cmake-build cmake -DENABLE_MONGOC=OFF -DCMAKE_INSTALL_PREFIX="/path/to/bson-install" ../ make -j8 install ``` This installs the library and includes into /path/to/bson-install. The prefix can be omitted if you prefer installing in /usr/local. 2. OpenSSL (if on Linux). Then build libmongocrypt: ``` git clone https://github.com/mongodb/libmongocrypt cd libmongocrypt mkdir cmake-build && cd cmake-build cmake -DCMAKE_PREFIX_PATH="/path/to/bson-install" ../ make ``` This builds libmongocrypt.dylib and test-libmongocrypt, in the cmake-build directory. Note, the `CMAKE_PREFIX_PATH` must include the path to the BSON library installation directory if it was not the defaults. Also note that if your project will also dynamically link to the BSON library, you will need to add `-DENABLE_SHARED_BSON=ON` to the `cmake` command line. ## Installing libmongocrypt on macOS ## Install the latest release of libmongocrypt with the following. ``` brew install mongodb/brew/libmongocrypt ``` To install the latest unstable development version of libmongocrypt, use `brew install mongodb/brew/libmongocrypt --HEAD`. Do not use the unstable version of libmongocrypt in a production environment. ## Building libmongocrypt from source on macOS ## First install [Homebrew according to its own instructions](https://brew.sh/). Using Homebrew, install the following dependencies. ``` brew install mongo-c-driver cmake ``` Install the XCode Command Line Tools: ``` xcode-select --install ``` Then clone and build libmongocrypt: ``` git clone https://github.com/mongodb/libmongocrypt.git cd libmongocrypt cmake -DENABLE_SHARED_BSON=ON . cmake --build . --target install ``` Then, libmongocrypt can be used with pkg-config: ``` pkg-config libmongocrypt --libs --cflags ``` Or use cmake's `find_package`: ``` find_package (mongocrypt) # Then link against mongo::mongocrypt ``` ## Installing libmongocrypt on Windows ## For Windows, there is a fixed URL to download the DLL and includes directory: https://s3.amazonaws.com/mciuploads/libmongocrypt/windows/latest_release/libmongocrypt.tar.gz To download the latest unstable release, download from this URL: https://s3.amazonaws.com/mciuploads/libmongocrypt/windows/latest_release/libmongocrypt_unstable.tar.gz Do not use the unstable version of libmongocrypt in a production environment. ### Testing ### `test-mongocrypt` mocks all I/O with files stored in the `test/data` and `test/example` directories. Run `test-mongocrypt` from the source directory: ``` cd libmongocrypt ./cmake-build/test-mongocrypt ``` libmongocrypt is [continuously built and published on evergreen](https://evergreen.mongodb.com/waterfall/libmongocrypt). Submit patch builds to this evergreen project when making changes to test on supported platforms. The latest tarball containing libmongocrypt built on all supported variants is [published here](https://s3.amazonaws.com/mciuploads/libmongocrypt/all/master/latest/libmongocrypt-all.tar.gz). ### Troubleshooting ### If OpenSSL is installed in a non-default directory, pass `-DOPENSSL_ROOT_DIR=/path/to/openssl` to the cmake command for libmongocrypt. If there are errors with cmake configuration, send the set of steps you performed to the maintainers of this project. If there are compilation or linker errors, run `make` again, setting `VERBOSE=1` in the environment or on the command line (which shows exact compile and link commands), and send the output to the maintainers of this project. ### Design Principles ### The design of libmongocrypt adheres to these principles. #### Easy to integrate #### The main reason behind creating a C library is to make it easier for drivers to support FLE. Some consequences of this principle: the API is minimal, structs are opaque, and global initialization is lazy. #### Lightweight #### We decided against the "have libmongocrypt do everything" approach because it complicated integration, especially with async drivers. Because of this we decided no I/O occurs in libmongocrypt. ### Releasing ### #### Version number scheme #### Version numbers of libmongocrypt must follow the format 1.[0-9].[0-9] for releases and 1.[0-9].[0-9]-rc[0-9] for release candidates. This ensures that Linux distribution packages built from each commit are published to the correct location. #### Steps to release #### Do the following when releasing: - Update CHANGELOG.md with any new changes and update the `[Unreleased]` text to the version being released. - In the Java binding build.gradle.kts, replace `version = "1.0.0-SNAPSHOT"` with `version = "1.0.0-rc123"`. - Commit, create a new git tag, like `1.0.0-rc123`, and push. - In the Java binding build.gradle.kts, replace `version = "1.0.0-rc123"` with `version = "1.0.0-SNAPSHOT"` (i.e. undo the change). For an example of this, see [this commit](https://github.com/mongodb/libmongocrypt/commit/2336123fbc1f4f5894f49df5e6320040987bb0d3) and its parent commit. - Commit and push. - Create the release from the GitHub releases page from the new tag. - Submit a PR to update the Homebrew package https://github.com/mongodb/homebrew-brew/blob/master/Formula/libmongocrypt.rb - File a DOCSP ticket to update the dependent version of bindings in the [CSFLE guide](https://github.com/mongodb-university/csfle-guides). ## Installing libmongocrypt From Distribution Packages ## Distribution packages (i.e., .deb/.rpm) are built and published for several Linux distributions. The installation of these packages for supported platforms is documented here. ### Unstable Development Distribution Packages ### To install the latest unstable development package, change `1.0` to `development` in the package URLs listed in the subsequent instructions. For example, `https://libmongocrypt.s3.amazonaws.com/apt/ubuntu /libmongocrypt/1.0` in the instructions would become `https://libmongocrypt.s3.amazonaws.com/apt/ubuntu /libmongocrypt/development`. Do not use the unstable version of libmongocrypt in a production environment. ### .deb Packages (Debian and Ubuntu) ### First, import the public key used to sign the package repositories: ``` sudo sh -c 'curl -s https://www.mongodb.org/static/pgp/libmongocrypt.asc | gpg --dearmor >/etc/apt/trusted.gpg.d/libmongocrypt.gpg' ``` Second, create a list entry for the repository. For Ubuntu systems (be sure to change `` to `xenial` or `bionic`, as appropriate to your system): ``` echo "deb https://libmongocrypt.s3.amazonaws.com/apt/ubuntu /libmongocrypt/1.0 universe" | sudo tee /etc/apt/sources.list.d/libmongocrypt.list ``` For Debian systems (be sure to change `` to `stretch` or `buster`, as appropriate to your system): ``` echo "deb https://libmongocrypt.s3.amazonaws.com/apt/debian /libmongocrypt/1.0 main" | sudo tee /etc/apt/sources.list.d/libmongocrypt.list ``` Third, update the package cache: ``` sudo apt-get update ``` Finally, install the libmongocrypt packages: ``` sudo apt-get install -y libmongocrypt-dev ``` ### .rpm Packages (RedHat, Suse, and Amazon) ### #### RedHat Enterprise Linux #### Create the file `/etc/yum.repos.d/libmongocrypt.repo` with contents: ``` [libmongocrypt] name=libmongocrypt repository baseurl=https://libmongocrypt.s3.amazonaws.com/yum/redhat/$releasever/libmongocrypt/1.0/x86_64 gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/libmongocrypt.asc ``` Then install the libmongocrypt packages: ``` sudo yum install -y libmongocrypt ``` #### Amazon Linux 2 #### Create the file `/etc/yum.repos.d/libmongocrypt.repo` with contents: ``` [libmongocrypt] name=libmongocrypt repository baseurl=https://libmongocrypt.s3.amazonaws.com/yum/amazon/2/libmongocrypt/1.0/x86_64 gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/libmongocrypt.asc ``` Then install the libmongocrypt packages: ``` sudo yum install -y libmongocrypt ``` #### Amazon Linux #### Create the file `/etc/yum.repos.d/libmongocrypt.repo` with contents: ``` [libmongocrypt] name=libmongocrypt repository baseurl=https://libmongocrypt.s3.amazonaws.com/yum/amazon/2013.03/libmongocrypt/1.0/x86_64 gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/libmongocrypt.asc ``` Then install the libmongocrypt packages: ``` sudo yum install -y libmongocrypt ``` #### Suse #### First, import the public key used to sign the package repositories: ``` sudo rpm --import https://www.mongodb.org/static/pgp/libmongocrypt.asc ``` Second, add the repository (be sure to change `` to `12` or `15`, as appropriate to your system): ``` sudo zypper addrepo --gpgcheck "https://libmongocrypt.s3.amazonaws.com/zypper/suse//libmongocrypt/1.0/x86_64" libmongocrypt ``` Finally, install the libmongocrypt packages: ``` sudo zypper -n install libmongocrypt ``` libmongocrypt-1.3.0/bindings/000077500000000000000000000000001414105245100161755ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/cs/000077500000000000000000000000001414105245100166025ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/cs/.gitignore000066400000000000000000000001471414105245100205740ustar00rootroot00000000000000# C# binary directories bin/ obj/ # Rider settings .idea/ # VS settings .vs/ # Other /Scripts/Tools libmongocrypt-1.3.0/bindings/cs/CMakeLists.txt000066400000000000000000000021501414105245100213400ustar00rootroot00000000000000 configure_file(cs.sln cs.sln COPYONLY) configure_file(MongoDB.Libmongocrypt/MongoDB.Libmongocrypt.csproj MongoDB.Libmongocrypt/MongoDB.Libmongocrypt.csproj COPYONLY) configure_file(MongoDB.Libmongocrypt/Package.include.template.csproj MongoDB.Libmongocrypt/Package.csproj.include) configure_file(MongoDB.Libmongocrypt.Test/MongoDB.Libmongocrypt.Test.csproj MongoDB.Libmongocrypt.Test/MongoDB.Libmongocrypt.Test.csproj COPYONLY) configure_file(MongoDB.Libmongocrypt.Test/Package.include.template.csproj MongoDB.Libmongocrypt.Test/Package.csproj.include) configure_file(MongoDB.Libmongocrypt.Test/MongoDB.Libmongocrypt.Test.csproj MongoDB.Libmongocrypt.Test32/MongoDB.Libmongocrypt.Test32.csproj COPYONLY) configure_file(MongoDB.Libmongocrypt.Test/Package.include.template.csproj MongoDB.Libmongocrypt.Test32/Package.csproj.include) configure_file(MongoDB.Libmongocrypt.Example/MongoDB.Libmongocrypt.Example.csproj MongoDB.Libmongocrypt.Example/MongoDB.Libmongocrypt.Example.csproj COPYONLY) configure_file(MongoDB.Libmongocrypt.Example/Package.include.template.csproj MongoDB.Libmongocrypt.Example/Package.csproj.include) libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Example/000077500000000000000000000000001414105245100243105ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Example/MongoDB.Libmongocrypt.Example.csproj000066400000000000000000000013761414105245100332470ustar00rootroot00000000000000 Exe net472;netcoreapp2.1 net472;netcoreapp2.1 netcoreapp2.1 AnyCPU false libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Example/Package.include.template.csproj000066400000000000000000000004741414105245100323260ustar00rootroot00000000000000 false @CMAKE_CURRENT_LIST_DIR@/MongoDB.Libmongocrypt.Example libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Example/Program.cs000066400000000000000000000402051414105245100262470ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using MongoDB.Bson; using MongoDB.Bson.IO; using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Serializers; using MongoDB.Libmongocrypt; using MongoDB.Driver; using System; using System.IO; using System.Net.Security; using System.Net.Sockets; using System.Security.Cryptography.X509Certificates; namespace drivertest { class BsonUtil { public static BsonDocument ToDocument(Binary bin) { MemoryStream stream = new MemoryStream(bin.ToArray()); using (var jsonReader = new BsonBinaryReader(stream)) { var context = BsonDeserializationContext.CreateRoot(jsonReader); return BsonDocumentSerializer.Instance.Deserialize(context); } } public static byte[] ToBytes(BsonDocument doc) { BsonBinaryWriterSettings settings = new BsonBinaryWriterSettings() { // C# driver "magically" changes UUIDs underneath by default so tell it not to GuidRepresentation = GuidRepresentation.Standard }; return doc.ToBson(null, settings); } public static BsonDocument Concat(BsonDocument doc1, BsonDocument doc2) { BsonDocument dest = new BsonDocument(); BsonDocumentWriter writer = new BsonDocumentWriter(dest); var context = BsonSerializationContext.CreateRoot(writer); writer.WriteStartDocument(); foreach (var field in doc1) { writer.WriteName(field.Name); BsonValueSerializer.Instance.Serialize(context, field.Value); } foreach (var field in doc2) { writer.WriteName(field.Name); BsonValueSerializer.Instance.Serialize(context, field.Value); } writer.WriteEndDocument(); return writer.Document; } public static BsonDocument FromJSON(string str) { using (var jsonReader = new JsonReader(str)) { var context = BsonDeserializationContext.CreateRoot(jsonReader); return BsonDocumentSerializer.Instance.Deserialize(context); } } } class MongoCryptDController { MongoClient _clientCryptD; IMongoCollection _keyVault; Uri _kmsEndpoint; public MongoCryptDController(MongoUrl urlCryptD, IMongoCollection keyVault, Uri kmsEndpoint) { _clientCryptD = new MongoClient(urlCryptD); _keyVault = keyVault; _kmsEndpoint = kmsEndpoint; } public Guid GenerateKey(KmsCredentials credentials, KmsKeyId kmsKeyId) { var options = new CryptOptions(new[] { credentials }); BsonDocument key = null; using (var cryptClient = CryptClientFactory.Create(options)) using (var context = cryptClient.StartCreateDataKeyContext(kmsKeyId)) { key = ProcessState(context, _keyVault.Database, null); } _keyVault.InsertOne(key); Guid g = key["_id"].AsGuid; return g; } public BsonDocument EncryptCommand(KmsCredentials credentials, IMongoCollection coll, BsonDocument cmd) { var options = new CryptOptions(new[] { credentials }); using (var cryptClient = CryptClientFactory.Create(options)) using (var context = cryptClient.StartEncryptionContext(coll.Database.DatabaseNamespace.DatabaseName, command: BsonUtil.ToBytes(cmd))) { return ProcessState(context, coll.Database, cmd); } } public BsonDocument DecryptCommand(KmsCredentials credentials, IMongoDatabase db, BsonDocument doc) { var options = new CryptOptions(new[] { credentials }); using (var cryptClient = CryptClientFactory.Create(options)) using (var context = cryptClient.StartDecryptionContext(BsonUtil.ToBytes(doc))) { return ProcessState(context, db, null); } } public static bool ValidateServerCertificate( object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { if (sslPolicyErrors == SslPolicyErrors.None) return true; Console.WriteLine("Certificate error: {0}", sslPolicyErrors); // Ignore certificate errors when testing against localhost return true; } void DoKmsRequest(KmsRequest request) { TcpClient tcpClient = new TcpClient(); Console.WriteLine("KMS: " + request.Endpoint); // change me to use the mock if (_kmsEndpoint != null) { tcpClient.Connect(_kmsEndpoint.DnsSafeHost, _kmsEndpoint.Port); } else { tcpClient.Connect(request.Endpoint, 443); } SslStream stream = new SslStream(tcpClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate)); stream.AuthenticateAsClient("localhost"); Binary bin = request.Message; stream.Write(bin.ToArray()); byte[] buffer = new byte[4096]; while (request.BytesNeeded > 0) { MemoryStream memBuffer = new MemoryStream(); int read = stream.Read(buffer, 0, buffer.Length); if (read > 0) { memBuffer.Write(buffer, 0, read); } request.Feed(memBuffer.ToArray()); } } private BsonDocument ProcessState(CryptContext context, IMongoDatabase db, BsonDocument cmd) { BsonDocument ret = cmd; while (!context.IsDone) { Console.WriteLine("\n----------------------------------\nState:" + context.State); switch (context.State) { case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_COLLINFO: { var binary = context.GetOperation(); var doc = BsonUtil.ToDocument(binary); Console.WriteLine("ListCollections Query: " + doc); ListCollectionsOptions opts = new ListCollectionsOptions() { Filter = new BsonDocumentFilterDefinition(doc) }; var reply = db.ListCollections(opts); var replyDocs = reply.ToList(); Console.WriteLine("ListCollections Reply: " + replyDocs); foreach (var replyDoc in replyDocs) { Console.WriteLine("ListCollections Reply: " + replyDoc); context.Feed(BsonUtil.ToBytes(replyDoc)); } context.MarkDone(); break; } case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_MARKINGS: { var binary = context.GetOperation(); var commandWithSchema = BsonUtil.ToDocument(binary); Console.WriteLine("MongoCryptD Query: " + commandWithSchema); var cryptDB = _clientCryptD.GetDatabase(db.DatabaseNamespace.DatabaseName); var reply = cryptDB.RunCommand(new BsonDocumentCommand(commandWithSchema)); Console.WriteLine("MongoCryptD Reply: " + reply); context.Feed(BsonUtil.ToBytes(reply)); context.MarkDone(); break; } case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_KEYS: { var binary = context.GetOperation(); Console.WriteLine("Buffer:" + BitConverter.ToString(binary.ToArray())); var doc = BsonUtil.ToDocument(binary); Console.WriteLine("GetKeys Query: " + doc); var reply = _keyVault.Find(new BsonDocumentFilterDefinition(doc)); var replyDocs = reply.ToList(); Console.WriteLine("GetKeys Reply: " + replyDocs); foreach (var replyDoc in replyDocs) { context.Feed(BsonUtil.ToBytes(replyDoc)); } context.MarkDone(); break; } case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_KMS: { var requests = context.GetKmsMessageRequests(); foreach (var req in requests) { DoKmsRequest(req); } requests.MarkDone(); break; } case CryptContext.StateCode.MONGOCRYPT_CTX_READY: { Binary b = context.FinalizeForEncryption(); Console.WriteLine("Buffer:" + BitConverter.ToString(b.ToArray())); ret = BsonUtil.ToDocument(b); break; } case CryptContext.StateCode.MONGOCRYPT_CTX_DONE: { Console.WriteLine("DONE!!"); return ret; } case CryptContext.StateCode.MONGOCRYPT_CTX_ERROR: { throw new NotImplementedException(); } } } return ret; } } class Program { static IMongoCollection SetupKeyStore(MongoClient client) { var dbAdmin = client.GetDatabase("admin"); var collKeyVault = dbAdmin.GetCollection("datakeys"); // Clear the key vault collKeyVault.DeleteMany(new BsonDocumentFilterDefinition(new BsonDocument())); return collKeyVault; } static IMongoCollection SetupTestCollection(MongoClient client, Guid keyID) { var database = client.GetDatabase("test"); // Reset state database.DropCollection("test"); var s = new BsonDocument { { "$jsonSchema" , new BsonDocument { { "type", "object" }, { "properties" , new BsonDocument { { "ssn" , new BsonDocument { { "encrypt" , new BsonDocument { { "keyId" , new BsonArray( new BsonValue[] { keyID } ) }, { "bsonType" , "string"}, { "algorithm" , "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" }, } } } } } } } } }; database.CreateCollection("test", new CreateCollectionOptions() { Validator = new BsonDocumentFilterDefinition(s) }); return database.GetCollection("test"); } static string GetEnvironmenVariabletOrValue(string env, string def) { string value = Environment.GetEnvironmentVariable(env); if (value != null) { return value; } return def; } static void Main(string[] args) { // The C# driver transmutes data unless you specify this stupid line! BsonDefaults.GuidRepresentation = GuidRepresentation.Standard; Console.WriteLine("Using url: " + args); // or change me to use the mock Uri kmsURL = Environment.GetEnvironmentVariable("FLE_AWS_SECRET_ACCESS_KEY") != null ? null : new Uri("https://localhost:8000"); var cryptDUrl = new MongoUrl("mongodb://localhost:27020"); var client = new MongoClient("mongodb://localhost:27017"); IMongoCollection collKeyVault = SetupKeyStore(client); var controller = new MongoCryptDController(cryptDUrl, collKeyVault, kmsURL); var awsKeyId = new KmsKeyId( new BsonDocument { { "provider", "aws" }, { "region", "us-east-1" }, { "key", "arn:aws:kms:us-east-1:579766882180:key/0689eb07-d588-4bbf-a83e-42157a92576b" } }.ToBson()); var kmsCredentials = new KmsCredentials( new BsonDocument { { "aws", new BsonDocument { { "secretAccessKey", GetEnvironmenVariabletOrValue("FLE_AWS_SECRET_ACCESS_KEY", "us-east-1") }, { "accessKeyId", GetEnvironmenVariabletOrValue("FLE_AWS_ACCESS_KEY_ID", "us-east-1") } } } }.ToBson()); Guid keyID = controller.GenerateKey(kmsCredentials, awsKeyId); IMongoCollection collection = SetupTestCollection(client, keyID); var database = collection.Database; // Insert a document with SSN var insertDoc = new BsonDocument { { "ssn" , "123-45-6789" }, }; var insertDocCmd = new BsonDocument { { "insert" , "test" }, { "documents", new BsonArray(new BsonValue[] { insertDoc }) } }; var insertEncryptedDoc = new BsonDocument(controller.EncryptCommand(kmsCredentials, collection, insertDocCmd)); Console.WriteLine("Insert Doc: " + insertEncryptedDoc); insertEncryptedDoc.Remove("$db"); database.RunCommand(new BsonDocumentCommand(insertEncryptedDoc)); var findDoc = BsonUtil.FromJSON(@"{ 'find': 'test', 'filter' : { '$or': [{ '_id': 1},{ 'ssn': '123-45-6789'}]}, }"); var findCmd = new BsonDocumentCommand(controller.EncryptCommand(kmsCredentials, collection, findDoc)); Console.WriteLine("Find CMD: " + findCmd.Document); findCmd.Document.Remove("$db"); var commandResult = database.RunCommand(findCmd); Console.WriteLine("Find Result: " + commandResult); var decryptedDocument = controller.DecryptCommand(kmsCredentials, database, commandResult); Console.WriteLine("Find Result (DECRYPTED): " + decryptedDocument); } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/000077500000000000000000000000001414105245100236345ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/BasicTests.cs000066400000000000000000000702451414105245100262370ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using MongoDB.Bson; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using Xunit; using System.Text; using FluentAssertions; using Xunit.Abstractions; namespace MongoDB.Libmongocrypt.Test { public class BasicTests { private static ITestOutputHelper _output; private const string AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic = "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"; private const string AEAD_AES_256_CBC_HMAC_SHA_512_Random = "AEAD_AES_256_CBC_HMAC_SHA_512-Random"; public BasicTests(ITestOutputHelper output) { _output = output; } #region local data BsonDocument CreateLocalCredentialsDocument() => new BsonDocument { { "local", new BsonDocument { { "key", new BsonBinaryData(new byte[96]) } } } }; KmsKeyId CreateLocalKey(IEnumerable keyAltNameBuffers = null) => new KmsKeyId( new BsonDocument { { "provider", "local" }, }.ToBson(), keyAltNameBuffers); KmsCredentials CreateLocalKmsCredentials() => new KmsCredentials( CreateLocalCredentialsDocument().ToBson()); #endregion #region aws data BsonDocument CreateAwsCredentialsDocument() => new BsonDocument { { "aws", new BsonDocument { { "secretAccessKey", "us-east-1" }, { "accessKeyId", "us-east-1" } } } }; KmsKeyId CreateAwsKey(string endpoint = null, IEnumerable keyAltNameBuffers = null) => new KmsKeyId( new BsonDocument { { "provider", "aws" }, { "key", "cmk" }, { "region", "us-east-1" }, { "endpoint", endpoint, endpoint != null } }.ToBson(), alternateKeyNameBytes: keyAltNameBuffers); KmsCredentials CreateAwsKmsCredentials() => new KmsCredentials( CreateAwsCredentialsDocument().ToBson()); #endregion CryptOptions CreateOptions() { return new CryptOptions( new[] { CreateAwsKmsCredentials(), CreateLocalKmsCredentials() }); } [Fact] public void EncryptQuery() { using (var cryptClient = CryptClientFactory.Create(CreateOptions())) using (var context = cryptClient.StartEncryptionContext("test", command: BsonUtil.ToBytes(ReadJsonTestFile("cmd.json")))) { var (_, bsonCommand) = ProcessContextToCompletion(context); bsonCommand.Should().Equal((ReadJsonTestFile("encrypted-command.json"))); } } [Fact] public void EncryptQueryStepwise() { using (var cryptClient = CryptClientFactory.Create(CreateOptions())) using (var context = cryptClient.StartEncryptionContext("test", command: BsonUtil.ToBytes(ReadJsonTestFile("cmd.json")))) { var (state, _, operationSent) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_COLLINFO); operationSent.Should().Equal((ReadJsonTestFile("list-collections-filter.json"))); (state, _, operationSent) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_MARKINGS); operationSent.Should().Equal(ReadJsonTestFile("mongocryptd-command.json")); (state, _, operationSent) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_KEYS); operationSent.Should().Equal(ReadJsonTestFile("key-filter.json")); (state, _, _) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_KMS); // kms fluent assertions inside ProcessState() (state, _, operationSent) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_READY); operationSent.Should().Equal((ReadJsonTestFile("encrypted-command.json"))); } } [Fact] public void EncryptQueryWithSchemaStepwise() { var listCollectionsReply = ReadJsonTestFile("collection-info.json"); var schema = new BsonDocument("test.test", listCollectionsReply["options"]["validator"]["$jsonSchema"]); var options = new CryptOptions( new[] { CreateAwsKmsCredentials() }, BsonUtil.ToBytes(schema)); using (var cryptClient = CryptClientFactory.Create(options)) using (var context = cryptClient.StartEncryptionContext( db: "test", command: BsonUtil.ToBytes(ReadJsonTestFile("cmd.json")))) { var (state, _, operationSent) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_MARKINGS); var mongoCryptdCommand = ReadJsonTestFile("mongocryptd-command.json"); mongoCryptdCommand["isRemoteSchema"] = false; operationSent.Should().Equal(mongoCryptdCommand); (state, _, operationSent) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_KEYS); operationSent.Should().Equal(ReadJsonTestFile("key-filter.json")); (state, _, _) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_KMS); // kms fluent assertions inside ProcessState() (state, _, operationSent) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_READY); operationSent.Should().Equal((ReadJsonTestFile("encrypted-command.json"))); } } [Fact] public void DecryptQuery() { using (var cryptClient = CryptClientFactory.Create(CreateOptions())) using (var context = cryptClient.StartDecryptionContext(BsonUtil.ToBytes(ReadJsonTestFile("encrypted-command-reply.json")))) { var (_, bsonCommand) = ProcessContextToCompletion(context); bsonCommand.Should().Equal(ReadJsonTestFile("command-reply.json")); } } [Fact] public void DecryptQueryStepwise() { using (var cryptClient = CryptClientFactory.Create(CreateOptions())) using (var context = cryptClient.StartDecryptionContext(BsonUtil.ToBytes(ReadJsonTestFile("encrypted-command-reply.json")))) { var (state, _, operationProduced) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_KEYS); operationProduced.Should().Equal(ReadJsonTestFile("key-filter.json")); (state, _, _) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_KMS); // kms fluent assertions inside ProcessState() (state, _, operationProduced) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_READY); operationProduced.Should().Equal(ReadJsonTestFile("command-reply.json")); (state, _, _) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_DONE); } } [Fact] public void EncryptBadBson() { using (var cryptClient = CryptClientFactory.Create(CreateOptions())) { Func startEncryptionContext = () => cryptClient.StartEncryptionContext("test", command: new byte[] { 0x1, 0x2, 0x3 }); // Ensure if we encrypt non-sense, it throws an exception demonstrating our exception code is good var exception = Record.Exception(startEncryptionContext); exception.Should().BeOfType(); } } [Fact] public void EncryptExplicit() { var keyDoc = ReadJsonTestFile("key-document.json"); var keyId = keyDoc["_id"].AsBsonBinaryData.Bytes; BsonDocument doc = new BsonDocument() { { "v" , "hello" }, }; var testData = BsonUtil.ToBytes(doc); byte[] encryptedBytes; using (var cryptClient = CryptClientFactory.Create(CreateOptions())) using (var context = cryptClient.StartExplicitEncryptionContextWithKeyId(keyId, AEAD_AES_256_CBC_HMAC_SHA_512_Random, testData)) { var (encryptedBinary, encryptedDocument) = ProcessContextToCompletion(context); encryptedBytes = encryptedBinary.ToArray(); // need to copy bytes out before the context gets destroyed } using (var cryptClient = CryptClientFactory.Create(CreateOptions())) using (var context = cryptClient.StartExplicitDecryptionContext(encryptedBytes)) { var (decryptedResult, _) = ProcessContextToCompletion(context); decryptedResult.ToArray().Should().Equal(testData); } } [Fact] public void EncryptExplicitStepwise() { var keyDoc = ReadJsonTestFile("key-document.json"); var keyId = keyDoc["_id"].AsBsonBinaryData.Bytes; var doc = new BsonDocument("v", "hello"); var testData = BsonUtil.ToBytes(doc); using (var cryptClient = CryptClientFactory.Create(CreateOptions())) { byte[] encryptedResult; using (var context = cryptClient.StartExplicitEncryptionContextWithKeyId( keyId: keyId, encryptionAlgorithm: AEAD_AES_256_CBC_HMAC_SHA_512_Deterministic, message: testData)) { var (state, binaryProduced, operationProduced) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_KEYS); operationProduced.Should().Equal(ReadJsonTestFile("key-filter.json")); (state, _, _) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_KMS); // kms fluent assertions inside ProcessState() (state, binaryProduced, operationProduced) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_READY); operationProduced.Should().Equal(ReadJsonTestFile("encrypted-value.json")); encryptedResult = binaryProduced.ToArray(); // need to copy bytes out before the context gets destroyed (state, _, _) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_DONE); } using (var context = cryptClient.StartExplicitDecryptionContext(encryptedResult)) { var (state, decryptedBinary, _) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_READY); decryptedBinary.ToArray().Should().Equal(testData); (state, _, _) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_DONE); } } } [Fact] public void TestAwsKeyCreationWithEndPoint() { var endpoint = "kms.us-east-1.amazonaws.com"; var keyId = CreateAwsKey(endpoint); var key = CreateAwsKmsCredentials(); using (var cryptClient = CryptClientFactory.Create(new CryptOptions(new[] { key }))) using (var context = cryptClient.StartCreateDataKeyContext(keyId)) { var (_, dataKeyDocument) = ProcessContextToCompletion(context, isKmsDecrypt: false); dataKeyDocument["masterKey"]["endpoint"].Should().Be(endpoint); } } [Fact] public void TestAwsKeyCreationWithEndpointStepwise() { var endpoint = "kms.us-east-1.amazonaws.com"; var keyId = CreateAwsKey(endpoint); var key = CreateAwsKmsCredentials(); using (var cryptClient = CryptClientFactory.Create(new CryptOptions(new[] { key }))) using (var context = cryptClient.StartCreateDataKeyContext(keyId)) { BsonDocument dataKeyDocument; var (state, _, _) = ProcessState(context, isKmsDecrypt: false); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_KMS); (state, _, dataKeyDocument) = ProcessState(context, isKmsDecrypt: false); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_READY); dataKeyDocument["masterKey"]["endpoint"].Should().Be(endpoint); (state, _, _) = ProcessState(context, isKmsDecrypt: false); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_DONE); } } [Fact] public void TestAwsKeyCreationWithkeyAltNames() { var keyAltNames = new[] { "KeyMaker", "Architect" }; var keyAltNameDocuments = keyAltNames.Select(name => new BsonDocument("keyAltName", name)); var keyAltNameBuffers = keyAltNameDocuments.Select(BsonUtil.ToBytes); var keyId = CreateAwsKey(keyAltNameBuffers: keyAltNameBuffers); var key = CreateAwsKmsCredentials(); using (var cryptClient = CryptClientFactory.Create(new CryptOptions(new[] { key }))) using (var context = cryptClient.StartCreateDataKeyContext(keyId)) { var (_, dataKeyDocument) = ProcessContextToCompletion(context, isKmsDecrypt: false); dataKeyDocument.Should().NotBeNull(); var actualKeyAltNames = dataKeyDocument["keyAltNames"].AsBsonArray.Select(x => x.AsString); var expectedKeyAltNames = keyAltNames.Reverse(); // https://jira.mongodb.org/browse/CDRIVER-3277? actualKeyAltNames.Should().BeEquivalentTo(expectedKeyAltNames); } } [Fact] public void TestAwsKeyCreationWithkeyAltNamesStepwise() { var keyAltNames = new[] { "KeyMaker", "Architect" }; var keyAltNameDocuments = keyAltNames.Select(name => new BsonDocument("keyAltName", name)); var keyAltNameBuffers = keyAltNameDocuments.Select(BsonUtil.ToBytes); var keyId = CreateAwsKey(keyAltNameBuffers: keyAltNameBuffers); var key = CreateAwsKmsCredentials(); using (var cryptClient = CryptClientFactory.Create(new CryptOptions(new[] { key }))) using (var context = cryptClient.StartCreateDataKeyContext(keyId)) { BsonDocument dataKeyDocument; var (state, _, _) = ProcessState(context, isKmsDecrypt: false); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_NEED_KMS); (state, _, dataKeyDocument) = ProcessState(context, isKmsDecrypt: false); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_READY); dataKeyDocument.Should().NotBeNull(); var actualKeyAltNames = dataKeyDocument["keyAltNames"].AsBsonArray.Select(x => x.AsString); var expectedKeyAltNames = keyAltNames.Reverse(); // https://jira.mongodb.org/browse/CDRIVER-3277? actualKeyAltNames.Should().BeEquivalentTo(expectedKeyAltNames); (state, _, _) = ProcessState(context, isKmsDecrypt: false); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_DONE); } } [Fact] public void TestLocalKeyCreationWithkeyAltNames() { var keyAltNames = new[] { "KeyMaker", "Architect" }; var keyAltNameDocuments = keyAltNames.Select(name => new BsonDocument("keyAltName", name)); var keyAltNameBuffers = keyAltNameDocuments.Select(BsonUtil.ToBytes); var key = CreateLocalKmsCredentials(); var keyId = CreateLocalKey(keyAltNameBuffers); var cryptOptions = new CryptOptions(new[] { key }); using (var cryptClient = CryptClientFactory.Create(cryptOptions)) using (var context = cryptClient.StartCreateDataKeyContext(keyId)) { var (_, dataKeyDocument) = ProcessContextToCompletion(context); dataKeyDocument.Should().NotBeNull(); var actualKeyAltNames = dataKeyDocument["keyAltNames"].AsBsonArray.Select(x => x.AsString); var expectedKeyAltNames = keyAltNames.Reverse(); // https://jira.mongodb.org/browse/CDRIVER-3277? actualKeyAltNames.Should().BeEquivalentTo(expectedKeyAltNames); } } [Fact] public void TestLocalKeyCreationWithkeyAltNamesStepwise() { var keyAltNames = new[] { "KeyMaker", "Architect" }; var keyAltNameDocuments = keyAltNames.Select(name => new BsonDocument("keyAltName", name)); var keyAltNameBuffers = keyAltNameDocuments.Select(BsonUtil.ToBytes); var key = CreateLocalKmsCredentials(); var keyId = CreateLocalKey(keyAltNameBuffers); var cryptOptions = new CryptOptions(new[] { key }); using (var cryptClient = CryptClientFactory.Create(cryptOptions)) using (var context = cryptClient.StartCreateDataKeyContext(keyId)) { var (state, _, dataKeyDocument) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_READY); dataKeyDocument.Should().NotBeNull(); var actualKeyAltNames = dataKeyDocument["keyAltNames"].AsBsonArray.Select(x => x.AsString); var expectedKeyAltNames = keyAltNames.Reverse(); // https://jira.mongodb.org/browse/CDRIVER-3277? actualKeyAltNames.Should().BeEquivalentTo(expectedKeyAltNames); (state, _, _) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_DONE); } } [Fact] public void TestLocalKeyCreation() { var key = CreateLocalKmsCredentials(); var keyId = CreateLocalKey(); var cryptOptions = new CryptOptions(new[] { key }); using (var cryptClient = CryptClientFactory.Create(cryptOptions)) using (var context = cryptClient.StartCreateDataKeyContext(keyId)) { var (_, dataKeyDocument) = ProcessContextToCompletion(context); dataKeyDocument.Should().NotBeNull(); } } [Fact] public void TestLocalKeyCreationStepwise() { var key = CreateLocalKmsCredentials(); var keyId = CreateLocalKey(); var cryptOptions = new CryptOptions(new[] { key }); using (var cryptClient = CryptClientFactory.Create(cryptOptions)) using (var context = cryptClient.StartCreateDataKeyContext(keyId)) { var (state, _, dataKeyDocument) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_READY); dataKeyDocument.Should().NotBeNull(); (state, _, _) = ProcessState(context); state.Should().Be(CryptContext.StateCode.MONGOCRYPT_CTX_DONE); } } // private methods private (Binary binarySent, BsonDocument document) ProcessContextToCompletion(CryptContext context, bool isKmsDecrypt = true) { BsonDocument document = null; Binary binary = null; while (!context.IsDone) { (_, binary, document) = ProcessState(context, isKmsDecrypt); } return (binary, document); } /// /// Processes the current state, simulating the execution the operation/post requests needed to reach the next state /// Returns (stateProcessed, binaryOperationProduced, bsonOperationProduced) /// /// private (CryptContext.StateCode stateProcessed, Binary binaryProduced, BsonDocument bsonOperationProduced) ProcessState(CryptContext context, bool isKmsDecrypt = true) { _output.WriteLine("\n----------------------------------\nState:" + context.State); switch (context.State) { case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_COLLINFO: { var binary = context.GetOperation(); var doc = BsonUtil.ToDocument(binary); _output.WriteLine("ListCollections: " + doc); var reply = ReadJsonTestFile("collection-info.json"); _output.WriteLine("Reply:" + reply); context.Feed(BsonUtil.ToBytes(reply)); context.MarkDone(); return (CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_COLLINFO, binary, doc); } case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_MARKINGS: { var binary = context.GetOperation(); var doc = BsonUtil.ToDocument(binary); _output.WriteLine("Markings: " + doc); var reply = ReadJsonTestFile("mongocryptd-reply.json"); _output.WriteLine("Reply:" + reply); context.Feed(BsonUtil.ToBytes(reply)); context.MarkDone(); return (CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_MARKINGS, binary, doc); } case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_KEYS: { var binary = context.GetOperation(); var doc = BsonUtil.ToDocument(binary); _output.WriteLine("Key Document: " + doc); var reply = ReadJsonTestFile("key-document.json"); _output.WriteLine("Reply:" + reply); context.Feed(BsonUtil.ToBytes(reply)); context.MarkDone(); return (CryptContext.StateCode.MONGOCRYPT_CTX_NEED_MONGO_KEYS, binary, doc); } case CryptContext.StateCode.MONGOCRYPT_CTX_NEED_KMS: { var requests = context.GetKmsMessageRequests(); foreach (var req in requests) { var binary = req.Message; _output.WriteLine("Key Document: " + binary); var postRequest = binary.ToString(); // TODO: add different hosts handling postRequest.Should().Contain("Host:kms.us-east-1.amazonaws.com"); // only AWS var reply = ReadHttpTestFile(isKmsDecrypt ? "kms-decrypt-reply.txt" : "kms-encrypt-reply.txt"); _output.WriteLine("Reply: " + reply); req.Feed(Encoding.UTF8.GetBytes(reply)); req.BytesNeeded.Should().Be(0); } requests.MarkDone(); return (CryptContext.StateCode.MONGOCRYPT_CTX_NEED_KMS, null, null); } case CryptContext.StateCode.MONGOCRYPT_CTX_READY: { Binary binary = context.FinalizeForEncryption(); _output.WriteLine("Buffer:" + binary.ToArray()); var document = BsonUtil.ToDocument(binary); _output.WriteLine("Document:" + document); return (CryptContext.StateCode.MONGOCRYPT_CTX_READY, binary, document); } case CryptContext.StateCode.MONGOCRYPT_CTX_DONE: { _output.WriteLine("DONE!!"); return (CryptContext.StateCode.MONGOCRYPT_CTX_DONE, null, null); } case CryptContext.StateCode.MONGOCRYPT_CTX_ERROR: { // We expect exceptions are thrown before we get to this state throw new NotImplementedException(); } } throw new NotImplementedException(); } static IEnumerable FindTestDirectories() { string[] searchPaths = new[] { Path.Combine("..", "test", "example"), Path.Combine("..", "test", "data") }; var assemblyLocation = Path.GetDirectoryName(typeof(BasicTests).GetTypeInfo().Assembly.Location); string cwd = Directory.GetCurrentDirectory(); // Assume we are in a child directory of the repo var searchDirectory = assemblyLocation ?? cwd; var testDirs = Enumerable.Range(1, 10) .Select(i => Enumerable.Repeat("..", i)) .Select(dotsSeq => dotsSeq.Aggregate(Path.Combine)) .SelectMany(previousDirectories => searchPaths.Select(searchPath => Path.Combine(searchDirectory, previousDirectories, searchPath))) .Where(Directory.Exists) .ToArray(); if (!testDirs.Any()) { throw new DirectoryNotFoundException("test/example"); } return testDirs; } static string ReadHttpTestFile(string file) { // The HTTP tests assume \r\n // And git strips \r on Unix machines by default so fix up the files var text = ReadTestFile(file); StringBuilder builder = new StringBuilder(text.Length); for (int i = 0; i < text.Length; i++) { if (text[i] == '\n' && text[i - 1] != '\r') builder.Append('\r'); builder.Append(text[i]); } return builder.ToString(); } static BsonDocument ReadJsonTestFile(string file) { var text = ReadTestFile(file); if (text == null) { throw new FileNotFoundException(file); } // Work around C# drivers and C driver have different extended json support text = text.Replace("\"$numberLong\"", "$numberLong"); return BsonUtil.FromJSON(text); } static string ReadTestFile(string fileName) { return FindTestDirectories() .Select(directory => Path.Combine(directory, fileName)) .Where(File.Exists) .Select(File.ReadAllText) .FirstOrDefault(); } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/BsonUtil.cs000066400000000000000000000054621414105245100257310ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using MongoDB.Bson; using MongoDB.Bson.IO; using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Serializers; using System.IO; namespace MongoDB.Libmongocrypt.Test { class BsonUtil { public static BsonDocument ToDocument(Binary bin) { MemoryStream stream = new MemoryStream(bin.ToArray()); using (var jsonReader = new BsonBinaryReader(stream)) { var context = BsonDeserializationContext.CreateRoot(jsonReader); return BsonDocumentSerializer.Instance.Deserialize(context); } } public static byte[] ToBytes(BsonDocument doc) { BsonBinaryWriterSettings settings = new BsonBinaryWriterSettings() { // C# driver "magically" changes UUIDs underneath by default so tell it not to GuidRepresentation = GuidRepresentation.Standard }; return doc.ToBson(null, settings); } public static BsonDocument Concat(BsonDocument doc1, BsonDocument doc2) { BsonDocument dest = new BsonDocument(); BsonDocumentWriter writer = new BsonDocumentWriter(dest); var context = BsonSerializationContext.CreateRoot(writer); writer.WriteStartDocument(); foreach (var field in doc1) { writer.WriteName(field.Name); BsonValueSerializer.Instance.Serialize(context, field.Value); } foreach (var field in doc2) { writer.WriteName(field.Name); BsonValueSerializer.Instance.Serialize(context, field.Value); } writer.WriteEndDocument(); return writer.Document; } public static BsonDocument FromJSON(string str) { var jsonReaderSettings = new JsonReaderSettings { GuidRepresentation = GuidRepresentation.Unspecified }; using (var jsonReader = new JsonReader(str, jsonReaderSettings)) { var context = BsonDeserializationContext.CreateRoot(jsonReader); return BsonDocumentSerializer.Instance.Deserialize(context); } } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/CallbackUtils.cs000066400000000000000000000022521414105245100267010ustar00rootroot00000000000000/* * Copyright 2020–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; namespace MongoDB.Libmongocrypt.Test { internal static class CallbackUtils { public static byte[] GetBytesFromHex(string hex) { if (hex.Length % 2 != 0) { throw new ArgumentException("Hex string must contain an even number of hex digits."); } int length = hex.Length; byte[] bytes = new byte[length / 2]; for (int i = 0; i < length; i += 2) bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); return bytes; } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/CipherCallbacksTests.cs000066400000000000000000000033111414105245100302160ustar00rootroot00000000000000/* * Copyright 2020–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using FluentAssertions; using Xunit; namespace MongoDB.Libmongocrypt.Test { public class CipherCallbacksTests { [Fact] public void CipherTest() { var keyHex = "92faa793d717675e2be804584a8a98252083fe6bf16010546a92e2ef4bdd27fd"; var ivHex = "31164b2f661e41fed5df60bfcfa40baa"; var inputHex = "379ddb78c30e5e4bf19dd81ae705796f"; var expectedHex = "671db60d464b09e9c3b03242dd29bdc5"; var keyBytes = CallbackUtils.GetBytesFromHex(keyHex); var ivBytes = CallbackUtils.GetBytesFromHex(ivHex); var inputBytes = CallbackUtils.GetBytesFromHex(inputHex); // decryptedBytes var expectedEncryptedBytes = CallbackUtils.GetBytesFromHex(expectedHex); var encryptedBytes = CipherCallbacks.AesCrypt(keyBytes, ivBytes, inputBytes, CryptMode.Encrypt); encryptedBytes.Should().Equal(expectedEncryptedBytes); var decryptedBytes = CipherCallbacks.AesCrypt(keyBytes, ivBytes, encryptedBytes, CryptMode.Decrypt); decryptedBytes.Should().Equal(inputBytes); } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/HashCallbackTests.cs000066400000000000000000000023251414105245100275100ustar00rootroot00000000000000/* * Copyright 2020–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using FluentAssertions; using Xunit; namespace MongoDB.Libmongocrypt.Test { public class HashCallbackTests { [Fact] public void HashTest() { var inputHex = "74657374206f66206d6163"; var expectedHex = "9ff3e52fa31c9e0fa0b08e19c40591553ea64b73709633271975bfab2db9d980"; var inputBytes = CallbackUtils.GetBytesFromHex(inputHex); var expectedBytes = CallbackUtils.GetBytesFromHex(expectedHex); var resultBytes = HashCallback.CalculateHash(inputBytes); resultBytes.Should().Equal(expectedBytes); } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/HmacShaCallbacksTests.cs000066400000000000000000000033161414105245100303150ustar00rootroot00000000000000/* * Copyright 2020–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using FluentAssertions; using Xunit; namespace MongoDB.Libmongocrypt.Test { public class HmacShaCallbacksTests { [Theory] [InlineData(256, "74657374206f66206d6163", "37626663386235656333306537336439386565666133653263633334643635376535323734623537656633326661353862663638313534396535663737303138", "ebfaa874ff7fcf5b48637a4aff49ed60f48b53a0802719d6ad85f96d315b2df2")] [InlineData(512, "74657374206f6620686d61630a", "06645237ece5638d1dcb66c70d8158c6ba5922dce3ae9f95242147fce0f989d9", "c8bc88465593980da5ed9bd213dcc4594106f6573d08eddc2b7cead3a642ef37dd848e8901a8c340f2a5d909057d28b1355fc9c82e7f7710e688f8c0c7635e9a")] public void HmacShaTest(int bitness, string inputHex, string keyHex, string expectedHex) { var keyBytes = CallbackUtils.GetBytesFromHex(keyHex); var inputBytes = CallbackUtils.GetBytesFromHex(inputHex); var expectedBytes = CallbackUtils.GetBytesFromHex(expectedHex); var resultBytes = HmacShaCallbacks.CalculateHash(keyBytes, inputBytes, bitness); resultBytes.Should().Equal(expectedBytes); } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/MongoDB.Libmongocrypt.Test.csproj000066400000000000000000000022411414105245100321070ustar00rootroot00000000000000 net472;netcoreapp2.1;netcoreapp3.0 netcoreapp2.1;netcoreapp3.0 AnyCPU false . PreserveNewest libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/Package.include.template.csproj000066400000000000000000000014351414105245100316500ustar00rootroot00000000000000 false @CMAKE_CURRENT_LIST_DIR@/MongoDB.Libmongocrypt.Test @CMAKE_CURRENT_BINARY_DIR@/MongoDB.Libmongocrypt.Test libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/SigningRSAESPKCSCallbackTests.cs000066400000000000000000000073771414105245100315160ustar00rootroot00000000000000/* * Copyright 2020–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Text; using FluentAssertions; using Xunit; namespace MongoDB.Libmongocrypt.Test.Callbacks { public class SigningRSAESPKCSCallbackTests { private static string DataToSign = "data to sign"; private static string PrivateKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC4JOyv5z05cL18ztpknRC7CFY2gYol4DAKerdVUoDJ" + "xCTmFMf39dVUEqD0WDiw/qcRtSO1/FRut08PlSPmvbyKetsLoxlpS8lukSzEFpFK7+L+R4miFOl6HvECyg7lbC1H/WGAhIz9yZRlXhRo9qmO/fB6PV9IeYtU+1xY" + "uXicjCDPp36uuxBAnCz7JfvxJ3mdVc0vpSkbSb141nWuKNYR1mgyvvL6KzxO6mYsCo4hRAdhuizD9C4jDHk0V2gDCFBk0h8SLEdzStX8L0jG90/Og4y7J1b/cPo/" + "kbYokkYisxe8cPlsvGBf+rZex7XPxc1yWaP080qeABJb+S88O//LAgMBAAECggEBAKVxP1m3FzHBUe2NZ3fYCc0Qa2zjK7xl1KPFp2u4CU+9sy0oZJUqQHUdm5CM" + "prqWwIHPTftWboFenmCwrSXFOFzujljBO7Z3yc1WD3NJl1ZNepLcsRJ3WWFH5V+NLJ8Bdxlj1DMEZCwr7PC5+vpnCuYWzvT0qOPTl9RNVaW9VVjHouJ9Fg+s2DrS" + "hXDegFabl1iZEDdI4xScHoYBob06A5lw0WOCTayzw0Naf37lM8Y4psRAmI46XLiF/Vbuorna4hcChxDePlNLEfMipICcuxTcei1RBSlBa2t1tcnvoTy6cuYDqqIm" + "RYjp1KnMKlKQBnQ1NjS2TsRGm+F0FbreVCECgYEA4IDJlm8q/hVyNcPe4OzIcL1rsdYN3bNm2Y2O/YtRPIkQ446ItyxD06d9VuXsQpFp9jNACAPfCMSyHpPApqlx" + "dc8z/xATlgHkcGezEOd1r4E7NdTpGg8y6Rj9b8kVlED6v4grbRhKcU6moyKUQT3+1B6ENZTOKyxuyDEgTwZHtFECgYEA0fqdv9h9s77d6eWmIioP7FSymq93pC4u" + "mxf6TVicpjpMErdD2ZfJGulN37dq8FOsOFnSmFYJdICj/PbJm6p1i8O21lsFCltEqVoVabJ7/0alPfdG2U76OeBqI8ZubL4BMnWXAB/VVEYbyWCNpQSDTjHQYs54" + "qa2I0dJB7OgJt1sCgYEArctFQ02/7H5Rscl1yo3DBXO94SeiCFSPdC8f2Kt3MfOxvVdkAtkjkMACSbkoUsgbTVqTYSEOEc2jTgR3iQ13JgpHaFbbsq64V0QP3TAx" + "bLIQUjYGVgQaF1UfLOBv8hrzgj45z/ST/G80lOl595+0nCUbmBcgG1AEWrmdF0/3RmECgYAKvIzKXXB3+19vcT2ga5Qq2l3TiPtOGsppRb2XrNs9qKdxIYvHmXo/" + "9QP1V3SRW0XoD7ez8FpFabp42cmPOxUNk3FK3paQZABLxH5pzCWI9PzIAVfPDrm+sdnbgG7vAnwfL2IMMJSA3aDYGCbF9EgefG+STcpfqq7fQ6f5TBgLFwKBgCd7" + "gn1xYL696SaKVSm7VngpXlczHVEpz3kStWR5gfzriPBxXgMVcWmcbajRser7ARpCEfbxM1UJyv6oAYZWVSNErNzNVb4POqLYcCNySuC6xKhs9FrEQnyKjyk8wI4V" + "nrEMGrQ8e+qYSwYk9Gh6dKGoRMAPYVXQAO0fIsHF/T0a"; private static string ExpectedSignature = "VocBRhpMmQ2XCzVehWSqheQLnU889gf3dhU4AnVnQTJjsKx/CM23qKDPkZDd2A/BnQsp99SN7ksIX5Raj0TPw" + "yN5OCN/YrNFNGoOFlTsGhgP/hyE8X3Duiq6sNO0SMvRYNPFFGlJFsp1Fw3Z94eYMg4/Wpw5s4+Jo5Zm/qY7aTJIqDKDQ3CNHLeJgcMUOc9sz01/GzoUYKDVODHSx" + "rYEk5ireFJFz9vP8P7Ha+VDUZuQIQdXer9NBbGFtYmWprY3nn4D3Dw93Sn0V0dIqYeIo91oKyslvMebmUM95S2PyIJdEpPb2DJDxjvX/0LLwSWlSXRWy9gapWoBk" + "b4ynqZBsg=="; [Fact] public void GetSignatureTest() { byte[] privateKeyBytes = Convert.FromBase64String(PrivateKey); var dataBytes = Encoding.ASCII.GetBytes(DataToSign); #if NETCOREAPP3_0 byte[] signature = SigningRSAESPKCSCallback.HashAndSignBytes(dataBytes, privateKeyBytes); string output = Convert.ToBase64String(signature); output.Should().Be(ExpectedSignature); #else var ex = Record.Exception(() => SigningRSAESPKCSCallback.HashAndSignBytes(dataBytes, privateKeyBytes)); ex.Should().BeOfType(); #endif } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/test/000077500000000000000000000000001414105245100246135ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/test/example/000077500000000000000000000000001414105245100262465ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/test/example/collection-info.json000066400000000000000000000017311414105245100322270ustar00rootroot00000000000000{ "type": "collection", "name": "test", "idIndex": { "ns": "test.test", "name": "_id_", "key": { "_id": { "$numberInt": "1" } }, "v": { "$numberInt": "2" } }, "options": { "validator": { "$jsonSchema": { "properties": { "ssn": { "encrypt": { "keyId": { "$binary": { "base64": "YWFhYWFhYWFhYWFhYWFhYQ==", "subType": "04" } }, "type": "string", "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" } } }, "bsonType": "object" } } } }libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/test/example/command-reply.json000066400000000000000000000002361414105245100317110ustar00rootroot00000000000000{ "cursor": { "firstBatch": [ { "_id": 1, "ssn": "457-55-5462" } ], "id": 0, "ns": "test.test" }, "ok": 1 } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/test/example/encrypted-command-reply.json000066400000000000000000000005251414105245100337050ustar00rootroot00000000000000{ "cursor" : { "firstBatch" : [ { "_id": 1, "ssn": { "$binary": "AWFhYWFhYWFhYWFhYWFhYWECRTOW9yZzNDn5dGwuqsrJQNLtgMEKaujhs9aRWRp+7Yo3JK8N8jC8P0Xjll6C1CwLsE/iP5wjOMhVv1KMMyOCSCrHorXRsb2IKPtzl2lKTqQ=", "$type": "06" } } ], "id" : 0, "ns" : "test.test" }, "ok" : 1 }libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/test/example/encrypted-command.json000066400000000000000000000004101414105245100325450ustar00rootroot00000000000000{ "filter": { "ssn": { "$binary": { "base64": "AWFhYWFhYWFhYWFhYWFhYWECRTOW9yZzNDn5dGwuqsrJQNLtgMEKaujhs9aRWRp+7Yo3JK8N8jC8P0Xjll6C1CwLsE/iP5wjOMhVv1KMMyOCSCrHorXRsb2IKPtzl2lKTqQ=", "subType": "06" } } }, "find": "test" } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/test/example/encrypted-value.json000066400000000000000000000002461414105245100322520ustar00rootroot00000000000000{ "v": { "$binary": "AWFhYWFhYWFhYWFhYWFhYWECW+zDjR/69eS6VtuMD5+O2lZw6JyiWOw3avI7mnUkdpKzPfvy8F/nlZrgZa2cGmQsb0TmLZuk5trldosnGKD91w==", "$type": "06" } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/test/example/key-document.json000066400000000000000000000020731414105245100315470ustar00rootroot00000000000000{ "status": { "$numberInt": "1" }, "_id": { "$binary": { "base64": "YWFhYWFhYWFhYWFhYWFhYQ==", "subType": "04" } }, "masterKey": { "region": "us-east-1", "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", "provider": "aws" }, "updateDate": { "$date": { "$numberLong": "1557827033449" } }, "keyMaterial": { "$binary": { "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", "subType": "00" } }, "creationDate": { "$date": { "$numberLong": "1557827033449" } }, "keyAltNames": [ "altKeyName", "another_altname" ] } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/test/example/key-filter.json000066400000000000000000000003631414105245100312160ustar00rootroot00000000000000{ "$or": [ { "_id": { "$in": [ { "$binary": "YWFhYWFhYWFhYWFhYWFhYQ==", "$type": "04" } ] } }, { "keyAltNames": { "$in": [] } } ] }libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/test/example/list-collections-filter.json000066400000000000000000000000241414105245100337070ustar00rootroot00000000000000{ "name": "test" }libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/test/example/mongocryptd-command.json000066400000000000000000000006531414105245100331260ustar00rootroot00000000000000{ "find": "test", "filter": { "ssn": "457-55-5462" }, "jsonSchema": { "properties": { "ssn": { "encrypt": { "keyId": { "$binary": "YWFhYWFhYWFhYWFhYWFhYQ==", "$type": "04" }, "type": "string", "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" } } }, "bsonType": "object" }, "isRemoteSchema": true }libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test/xunit.runner.json000066400000000000000000000002071414105245100272050ustar00rootroot00000000000000{ "$schema": "https://xunit.github.io/schema/current/xunit.runner.schema.json", "appDomain": "denied", "shadowCopy": false } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test32/000077500000000000000000000000001414105245100240015ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test32/BasicTests.cs000066400000000000000000000032111414105245100263710ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using Xunit; using FluentAssertions; using MongoDB.Bson; namespace MongoDB.Libmongocrypt.Test32 { public class BasicTests { BsonDocument CreateAwsCredentialsDocument() => new BsonDocument { { "aws", new BsonDocument { { "secretAccessKey", "us-east-1" }, { "accessKeyId", "us-east-1" } } } }; CryptOptions CreateOptions() => new CryptOptions( new[] { new KmsCredentials(CreateAwsCredentialsDocument().ToBson()) } ); [Fact] public void CryptClientShouldFailToiInitializeWhenTargetingX86() { var exception = Record.Exception(() => CryptClientFactory.Create(CreateOptions())); exception.Should().BeOfType(); } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test32/MongoDB.Libmongocrypt.Test32.csproj000066400000000000000000000027261414105245100324310ustar00rootroot00000000000000 net472;netcoreapp2.1;netcoreapp3.0 netcoreapp2.1;netcoreapp3.0 false . x86 x86 libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt.Test32/Package.include.template.csproj000066400000000000000000000014411414105245100320120ustar00rootroot00000000000000 false @CMAKE_CURRENT_LIST_DIR@/MongoDB.Libmongocrypt.Test32 @CMAKE_CURRENT_BINARY_DIR@/MongoDB.Libmongocrypt.Test32 libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/000077500000000000000000000000001414105245100227165ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/AssemblyInfo.cs000066400000000000000000000002471414105245100256430ustar00rootroot00000000000000using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("MongoDB.Libmongocrypt.Test")] [assembly: InternalsVisibleTo("MongoDB.Libmongocrypt.Test32")] libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/Binary.cs000066400000000000000000000067751414105245100245100ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.IO; using System.Runtime.InteropServices; namespace MongoDB.Libmongocrypt { /// /// A pointer and length pair the contains raw bytes to pass or retrive from libmongocrypt. /// /// public class Binary : IDisposable { private BinarySafeHandle _handle; internal Binary() { _handle = Library.mongocrypt_binary_new(); } internal Binary(BinarySafeHandle handle) { _handle = handle; } /// /// Gets the data. /// /// /// The data. /// public IntPtr Data { get { return Library.mongocrypt_binary_data(_handle); } } /// /// Gets the length. /// /// /// The length. /// public uint Length { get { return Library.mongocrypt_binary_len(_handle); } } internal BinarySafeHandle Handle => _handle; /// /// Converts to array. /// public byte[] ToArray() { byte[] arr = new byte[Length]; Marshal.Copy(Data, arr, 0, arr.Length); return arr; } /// /// Write bytes into Data. /// public void WriteBytes(byte[] bytes) { // The length of the new bytes can be smaller than allocated memory // because sometimes the allocated memory contains reserved blocks for future usage if (bytes.Length <= Length) { Marshal.Copy(bytes, 0, Data, bytes.Length); } else { // this code path is not expected, but it's worth doing it to avoid silent saving of corrupted data throw new InvalidDataException($"Incorrect bytes size {bytes.Length}. The bytes size must be less than or equal to {Length}."); } } /// /// Converts to string. /// /// /// A that represents this instance. /// public override string ToString() { return Marshal.PtrToStringAnsi(Data); } #region IDisposable public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { // Adapted from: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.safehandle?view=netcore-3.0 if (_handle != null && !_handle.IsInvalid) { // Free the handle _handle.Dispose(); } } #endregion } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/BinarySafeHandle.cs000066400000000000000000000033221414105245100264040ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; namespace MongoDB.Libmongocrypt { /// /// SafeHandle to manage the lifetime of a mongocrypt_binary_t. /// /// internal class BinarySafeHandle : SafeHandle { private BinarySafeHandle() : base(IntPtr.Zero, true) { } private BinarySafeHandle(IntPtr ptr) : base(ptr, false) { } public static BinarySafeHandle FromIntPtr(IntPtr ptr) { return new BinarySafeHandle(ptr); } public override bool IsInvalid { get { return handle == IntPtr.Zero; } } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { // Here, we must obey all rules for constrained execution regions. Library.mongocrypt_binary_destroy(handle); return true; } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/CipherCallbacks.cs000066400000000000000000000111211414105245100262530ustar00rootroot00000000000000/* * Copyright 2020–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Security.Cryptography; namespace MongoDB.Libmongocrypt { internal enum CryptMode { Encrypt, Decrypt } internal static class CipherCallbacks { public static bool Encrypt( IntPtr ctx, IntPtr key, IntPtr iv, IntPtr @in, IntPtr @out, ref uint bytes_written, IntPtr statusPtr) { using (var status = new Status(StatusSafeHandle.FromIntPtr(statusPtr))) { try { var keyBinary = new Binary(BinarySafeHandle.FromIntPtr(key)); var inputBinary = new Binary(BinarySafeHandle.FromIntPtr(@in)); var outputBinary = new Binary(BinarySafeHandle.FromIntPtr(@out)); var ivBinary = new Binary(BinarySafeHandle.FromIntPtr(iv)); byte[] keyBytes = keyBinary.ToArray(); byte[] ivBytes = ivBinary.ToArray(); byte[] inputBytes = inputBinary.ToArray(); var outputBytes = AesCrypt(keyBytes, ivBytes, inputBytes, CryptMode.Encrypt); bytes_written = (uint)outputBytes.Length; outputBinary.WriteBytes(outputBytes); return true; } catch (Exception e) { status.SetStatus(1, e.Message); return false; } } } public static bool Decrypt( IntPtr ctx, IntPtr key, IntPtr iv, IntPtr @in, IntPtr @out, ref uint bytes_written, IntPtr statusPtr) { using (var status = new Status(StatusSafeHandle.FromIntPtr(statusPtr))) { try { var keyBinary = new Binary(BinarySafeHandle.FromIntPtr(key)); var inputBinary = new Binary(BinarySafeHandle.FromIntPtr(@in)); var outputBinary = new Binary(BinarySafeHandle.FromIntPtr(@out)); var ivBinary = new Binary(BinarySafeHandle.FromIntPtr(iv)); byte[] keyBytes = keyBinary.ToArray(); byte[] ivBytes = ivBinary.ToArray(); byte[] inputBytes = inputBinary.ToArray(); var outputBytes = AesCrypt(keyBytes, ivBytes, inputBytes, CryptMode.Decrypt); bytes_written = (uint)outputBytes.Length; outputBinary.WriteBytes(outputBytes); return true; } catch (Exception e) { status.SetStatus(1, e.Message); return false; } } } public static byte[] AesCrypt(byte[] keyBytes, byte[] ivBytes, byte[] inputBytes, CryptMode cryptMode) { using (var aes = new RijndaelManaged()) { aes.Mode = CipherMode.CBC; aes.Key = keyBytes; aes.IV = ivBytes; aes.Padding = PaddingMode.None; // mongocrypt level is responsible for padding using (var encrypto = CreateCryptoTransform(aes)) { byte[] encryptedBytes = encrypto.TransformFinalBlock(inputBytes, 0, inputBytes.Length); return encryptedBytes; } ICryptoTransform CreateCryptoTransform(RijndaelManaged rijndaelManaged) { switch (cryptMode) { case CryptMode.Encrypt: return rijndaelManaged.CreateEncryptor(); case CryptMode.Decrypt: return rijndaelManaged.CreateDecryptor(); default: throw new InvalidOperationException($"Unsupported crypt mode {cryptMode}."); // should not be reached } } } } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/ContextSafeHandle.cs000066400000000000000000000033431414105245100266070ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; namespace MongoDB.Libmongocrypt { /// /// SafeHandle to manage the lifetime of a mongocrypt_ctx_t. /// /// internal class ContextSafeHandle : SafeHandle { private ContextSafeHandle() : base(IntPtr.Zero, true) { } public void Check(Status status, bool success) { if (!success) { Library.mongocrypt_ctx_status(this, status.Handle); status.ThrowExceptionIfNeeded(); } } public override bool IsInvalid { get { return handle == IntPtr.Zero; } } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { // Here, we must obey all rules for constrained execution regions. Library.mongocrypt_ctx_destroy(handle); return true; } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/CryptClient.cs000066400000000000000000000211121414105245100255020ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Runtime.InteropServices; namespace MongoDB.Libmongocrypt { /// /// CryptClient represents a session with libmongocrypt. /// /// It can be used to encrypt and decrypt documents. /// /// public class CryptClient : IDisposable, IStatus { private MongoCryptSafeHandle _handle; private Status _status; internal CryptClient(MongoCryptSafeHandle handle, Status status) { _handle = handle; _status = status; } /// /// Starts the create data key context. /// /// The key identifier. /// A crypt context for creating a data key public CryptContext StartCreateDataKeyContext(KmsKeyId keyId) { ContextSafeHandle handle = Library.mongocrypt_ctx_new(_handle); keyId.SetCredentials(handle, _status); handle.Check(_status, Library.mongocrypt_ctx_datakey_init(handle)); return new CryptContext(handle); } /// /// Starts the encryption context. /// /// The database of the collection. /// The command. /// A encryption context. public CryptContext StartEncryptionContext(string db, byte[] command) { ContextSafeHandle handle = Library.mongocrypt_ctx_new(_handle); IntPtr stringPointer = (IntPtr)Marshal.StringToHGlobalAnsi(db); try { unsafe { fixed (byte* c = command) { var commandPtr = (IntPtr)c; using (var pinnedCommand = new PinnedBinary(commandPtr, (uint)command.Length)) { // Let mongocrypt run strlen handle.Check(_status, Library.mongocrypt_ctx_encrypt_init(handle, stringPointer, -1, pinnedCommand.Handle)); } } } } finally { Marshal.FreeHGlobal(stringPointer); } return new CryptContext(handle); } /// /// Starts an explicit encryption context. /// /// The key id. /// The encryption algorithm. /// The BSON message. /// A encryption context. public CryptContext StartExplicitEncryptionContextWithKeyId(byte[] keyId, string encryptionAlgorithm, byte[] message) { ContextSafeHandle handle = Library.mongocrypt_ctx_new(_handle); unsafe { fixed (byte* p = keyId) { IntPtr ptr = (IntPtr)p; using (PinnedBinary pinned = new PinnedBinary(ptr, (uint)keyId.Length)) { handle.Check(_status, Library.mongocrypt_ctx_setopt_key_id(handle, pinned.Handle)); } } } handle.Check(_status, Library.mongocrypt_ctx_setopt_algorithm(handle, encryptionAlgorithm, -1)); unsafe { fixed (byte* p = message) { IntPtr ptr = (IntPtr)p; using (PinnedBinary pinned = new PinnedBinary(ptr, (uint)message.Length)) { handle.Check(_status, Library.mongocrypt_ctx_explicit_encrypt_init(handle, pinned.Handle)); } } } return new CryptContext(handle); } /// /// Starts an explicit encryption context. /// /// The alternative key name. /// The algorithm. /// The BSON message. /// A encryption context. public CryptContext StartExplicitEncryptionContextWithKeyAltName(byte[] keyAltName, string encryptionAlgorithm, byte[] message) { ContextSafeHandle handle = Library.mongocrypt_ctx_new(_handle); unsafe { fixed (byte* p = keyAltName) { IntPtr ptr = (IntPtr)p; using (PinnedBinary pinned = new PinnedBinary(ptr, (uint)keyAltName.Length)) { handle.Check(_status, Library.mongocrypt_ctx_setopt_key_alt_name(handle, pinned.Handle)); } } } handle.Check(_status, Library.mongocrypt_ctx_setopt_algorithm(handle, encryptionAlgorithm, -1)); unsafe { fixed (byte* p = message) { IntPtr ptr = (IntPtr)p; using (PinnedBinary pinned = new PinnedBinary(ptr, (uint)message.Length)) { handle.Check(_status, Library.mongocrypt_ctx_explicit_encrypt_init(handle, pinned.Handle)); } } } return new CryptContext(handle); } /// /// Starts the decryption context. /// /// The bson document to decrypt. /// A decryption context public CryptContext StartDecryptionContext(byte[] buffer) { ContextSafeHandle handle = Library.mongocrypt_ctx_new(_handle); GCHandle gch = GCHandle.Alloc(buffer, GCHandleType.Pinned); unsafe { fixed (byte* p = buffer) { IntPtr ptr = (IntPtr)p; using (PinnedBinary pinned = new PinnedBinary(ptr, (uint)buffer.Length)) { handle.Check(_status, Library.mongocrypt_ctx_decrypt_init(handle, pinned.Handle)); } } } return new CryptContext(handle); } /// /// Starts an explicit decryption context. /// /// The buffer. /// A encryption context public CryptContext StartExplicitDecryptionContext(byte[] buffer) { ContextSafeHandle handle = Library.mongocrypt_ctx_new(_handle); unsafe { fixed (byte* p = buffer) { IntPtr ptr = (IntPtr)p; using (PinnedBinary pinned = new PinnedBinary(ptr, (uint)buffer.Length)) { // Let mongocrypt run strlen handle.Check(_status, Library.mongocrypt_ctx_explicit_decrypt_init(handle, pinned.Handle)); } } } return new CryptContext(handle); } void IStatus.Check(Status status) { Library.mongocrypt_status(_handle, status.Handle); } #region IDisposable public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { // Adapted from: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.safehandle?view=netcore-3.0 if (_handle != null && !_handle.IsInvalid) { // Free the handle _handle.Dispose(); } } #endregion private void Check(bool success) { if (!success) { _status.Check(this); } } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/CryptClientFactory.cs000066400000000000000000000102371414105245100270400ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; namespace MongoDB.Libmongocrypt { /// /// A factory for CryptClients. /// public class CryptClientFactory { // MUST be static fields since otherwise these callbacks can be collected via the garbage collector // regardless they're used by mongocrypt level or no private static Library.Delegates.CryptoCallback __crypto256DecryptCallback = new Library.Delegates.CryptoCallback(CipherCallbacks.Decrypt); private static Library.Delegates.CryptoCallback __crypto256EncryptCallback = new Library.Delegates.CryptoCallback(CipherCallbacks.Encrypt); private static Library.Delegates.HashCallback __cryptoHashCallback = new Library.Delegates.HashCallback(HashCallback.Hash); private static Library.Delegates.CryptoHmacCallback __cryptoHmacSha256Callback = new Library.Delegates.CryptoHmacCallback(HmacShaCallbacks.HmacSha256); private static Library.Delegates.CryptoHmacCallback __cryptoHmacSha512Callback = new Library.Delegates.CryptoHmacCallback(HmacShaCallbacks.HmacSha512); private static Library.Delegates.RandomCallback __randomCallback = new Library.Delegates.RandomCallback(SecureRandomCallback.GenerateRandom); private static Library.Delegates.CryptoHmacCallback __signRsaesPkcs1HmacCallback = new Library.Delegates.CryptoHmacCallback(SigningRSAESPKCSCallback.RsaSign); /// Creates a CryptClient with the specified options. /// The options. /// A CryptClient public static CryptClient Create(CryptOptions options) { var handle = Library.mongocrypt_new(); var status = new Status(); // The below code can be avoided on Windows. So, we don't call it on this system // to avoid restrictions on target frameworks that present in some of below if (OperatingSystemHelper.CurrentOperatingSystem != OperatingSystemPlatform.Windows) { handle.Check( status, Library.mongocrypt_setopt_crypto_hooks( handle, __crypto256EncryptCallback, __crypto256DecryptCallback, __randomCallback, __cryptoHmacSha512Callback, __cryptoHmacSha256Callback, __cryptoHashCallback, IntPtr.Zero)); handle.Check( status, Library.mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5( handle, __signRsaesPkcs1HmacCallback, IntPtr.Zero)); } foreach (var kmsCredentials in options.KmsCredentials) { kmsCredentials.SetCredentials(handle, status); } if (options.Schema != null) { unsafe { fixed (byte* schema = options.Schema) { var schemaPtr = (IntPtr)schema; using (var pinnedSchema = new PinnedBinary(schemaPtr, (uint)options.Schema.Length)) { handle.Check(status, Library.mongocrypt_setopt_schema_map(handle, schema: pinnedSchema.Handle)); } } } } Library.mongocrypt_init(handle); return new CryptClient(handle, status); } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/CryptContext.cs000066400000000000000000000141701414105245100257160ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.Runtime.InteropServices; namespace MongoDB.Libmongocrypt { /// /// A encryption or decryption session. It may not be reused. /// /// /// public class CryptContext : IDisposable, IStatus { /// /// States of the CryptContext state machine /// public enum StateCode { /// /// LibMongoCrypt hit an error /// MONGOCRYPT_CTX_ERROR = 0, /// /// LibMongoCrypt wants the collection information by running a OP_MSG command against the users' mongod. /// MONGOCRYPT_CTX_NEED_MONGO_COLLINFO = 1, /// /// LibMongoCrypt wants a command to be run against mongocryptd. /// MONGOCRYPT_CTX_NEED_MONGO_MARKINGS = 2, /// /// LibMongoCrypt wants a command to be run against mongod key vault. /// MONGOCRYPT_CTX_NEED_MONGO_KEYS = 3, /// /// LibMongoCrypt wants a request sent to KMS. /// MONGOCRYPT_CTX_NEED_KMS = 4, /// /// LibMongoCrypt is ready to do encryption, call Finish(). /// MONGOCRYPT_CTX_READY = 5, /// /// LibMongoCrypt is complete. /// MONGOCRYPT_CTX_DONE = 6 } private ContextSafeHandle _handle; private Status _status; internal CryptContext(ContextSafeHandle handle) { _handle = handle; _status = new Status(); } /// /// Gets the state. /// /// /// The state. /// public StateCode State { get { return Library.mongocrypt_ctx_state(_handle); } } /// /// Gets a value indicating whether this instance is done. /// /// /// true if this instance is done; otherwise, false. /// public bool IsDone { get { return State == StateCode.MONGOCRYPT_CTX_DONE; } } /// /// Gets the operation. /// /// Binary payload to send to either KMS, mongod, or mongocryptd public Binary GetOperation() { Binary binary = new Binary(); Check(Library.mongocrypt_ctx_mongo_op(_handle, binary.Handle)); return binary; } /// /// Feeds the result from running a remote operation back to the libmongocrypt. /// /// The buffer. public void Feed(byte[] buffer) { unsafe { fixed (byte* p = buffer) { IntPtr ptr = (IntPtr)p; using (PinnedBinary pinned = new PinnedBinary(ptr, (uint)buffer.Length)) { Check(Library.mongocrypt_ctx_mongo_feed(_handle, pinned.Handle)); } } } } /// /// Signal the feeding is done. /// public void MarkDone() { Check(Library.mongocrypt_ctx_mongo_done(_handle)); } /// /// Finalizes for encryption. /// /// The encrypted or decrypted result. public Binary FinalizeForEncryption() { Binary binary = new Binary(); Check(Library.mongocrypt_ctx_finalize(_handle, binary.Handle)); return binary; } /// /// Gets a collection of KMS message requests to make /// /// Collection of KMS Messages public KmsRequestCollection GetKmsMessageRequests() { var requests = new List(); for (IntPtr request = Library.mongocrypt_ctx_next_kms_ctx(_handle); request != IntPtr.Zero; request = Library.mongocrypt_ctx_next_kms_ctx(_handle)) { requests.Add(new KmsRequest(request)); } return new KmsRequestCollection(requests, this); } void IStatus.Check(Status status) { Library.mongocrypt_ctx_status(_handle, status.Handle); } #region IDisposable public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { // Adapted from: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.safehandle?view=netcore-3.0 if (_handle != null && !_handle.IsInvalid) { // Free the handle _handle.Dispose(); } } #endregion internal void MarkKmsDone() { Check(Library.mongocrypt_ctx_kms_done(_handle)); } private void Check(bool success) { if (!success) { _status.Check(this); } } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/CryptException.cs000066400000000000000000000021541414105245100262270ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; namespace MongoDB.Libmongocrypt { /// /// An exception from libmongocrypt. /// /// public class CryptException : Exception { private readonly uint _code; private readonly Library.StatusType _statusType; internal CryptException(Library.StatusType statusType, uint code, string message) : base(message) { _code = code; _statusType = statusType; } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/CryptOptions.cs000066400000000000000000000026611414105245100257270ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; namespace MongoDB.Libmongocrypt { /// /// Options to configure mongocrypt with. /// public class CryptOptions { public IReadOnlyList KmsCredentials { get; } public byte[] Schema { get; } public CryptOptions(IEnumerable credentials) : this(credentials, null) { } public CryptOptions( IEnumerable credentials, byte[] schema) { KmsCredentials = new ReadOnlyCollection((credentials ?? throw new ArgumentNullException(nameof(credentials))).ToList()); Schema = schema; } // TODO: - add configurable logging support } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/HashCallback.cs000066400000000000000000000035201414105245100255450ustar00rootroot00000000000000/* * Copyright 2020–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Security.Cryptography; namespace MongoDB.Libmongocrypt { internal static class HashCallback { public static bool Hash( IntPtr ctx, IntPtr @in, IntPtr @out, IntPtr statusPtr) { using (var status = new Status(StatusSafeHandle.FromIntPtr(statusPtr))) { try { var inputBinary = new Binary(BinarySafeHandle.FromIntPtr(@in)); var outBinary = new Binary(BinarySafeHandle.FromIntPtr(@out)); var outBytes = CalculateHash(inputBinary.ToArray()); outBinary.WriteBytes(outBytes); return true; } catch (Exception ex) { status.SetStatus(1, ex.Message); return false; } } } public static byte[] CalculateHash(byte[] inputBytes) { using (var sha256 = SHA256.Create()) { sha256.Initialize(); _ = sha256.TransformFinalBlock(inputBytes, 0, inputBytes.Length); return sha256.Hash; } } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/HmacShaCallbacks.cs000066400000000000000000000060541414105245100263560ustar00rootroot00000000000000/* * Copyright 2020–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Security.Cryptography; namespace MongoDB.Libmongocrypt { internal static class HmacShaCallbacks { public static bool HmacSha512( IntPtr ctx, IntPtr key, IntPtr @in, IntPtr @out, IntPtr statusPtr) { return Hmac(key, @in, @out, statusPtr, bitness: 512); } public static bool HmacSha256( IntPtr ctx, IntPtr key, IntPtr @in, IntPtr @out, IntPtr statusPtr) { return Hmac(key, @in, @out, statusPtr, bitness: 256); } public static byte[] CalculateHash(byte[] keyBytes, byte[] inputBytes, int bitness) { using (var hmac = GetHmacByBitness(bitness, keyBytes)) { hmac.Initialize(); _ = hmac.TransformFinalBlock(inputBytes, 0, inputBytes.Length); return hmac.Hash; } } private static HMAC GetHmacByBitness(int bitness, byte[] keyBytes) { switch (bitness) { case 256: return new HMACSHA256(keyBytes); case 512: return new HMACSHA512(keyBytes); default: throw new ArgumentOutOfRangeException($"The bitness {bitness} is unsupported."); // should not be reached } } private static bool Hmac( IntPtr key, IntPtr @in, IntPtr @out, IntPtr statusPtr, int bitness) { using (var status = new Status(StatusSafeHandle.FromIntPtr(statusPtr))) { try { var keyBinary = new Binary(BinarySafeHandle.FromIntPtr(key)); var inBinary = new Binary(BinarySafeHandle.FromIntPtr(@in)); var outBinary = new Binary(BinarySafeHandle.FromIntPtr(@out)); var keyBytes = keyBinary.ToArray(); var inBytes = inBinary.ToArray(); var outBytes = CalculateHash(keyBytes, inBytes, bitness: bitness); outBinary.WriteBytes(outBytes); return true; } catch (Exception ex) { // let mongocrypt level to handle the error status.SetStatus(1, ex.Message); return false; } } } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/IStatus.cs000066400000000000000000000015101414105245100246360ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace MongoDB.Libmongocrypt { /// /// Interface for checking the status of the various libmongocrypt options. /// internal interface IStatus { void Check(Status status); } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/KmsCredentials.cs000066400000000000000000000033631414105245100261620ustar00rootroot00000000000000/* * Copyright 2020–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; namespace MongoDB.Libmongocrypt { /// /// KMS Credentials. /// public class KmsCredentials { private readonly byte[] _credentialsBytes; /// /// Creates a class. /// /// The byte representation of credentials bson document. public KmsCredentials(byte[] credentialsBytes) { _credentialsBytes = credentialsBytes ?? throw new ArgumentNullException(nameof(credentialsBytes)); } // internal methods internal void SetCredentials(MongoCryptSafeHandle handle, Status status) { unsafe { fixed (byte* p = _credentialsBytes) { IntPtr ptr = (IntPtr)p; using (PinnedBinary pinned = new PinnedBinary(ptr, (uint)_credentialsBytes.Length)) { handle.Check(status, Library.mongocrypt_setopt_kms_providers(handle, pinned.Handle)); } } } } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/KmsKeyId.cs000066400000000000000000000060111414105245100247230ustar00rootroot00000000000000/* * Copyright 2020–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.Linq; namespace MongoDB.Libmongocrypt { /// /// Represent a kms key. /// public class KmsKeyId { private readonly IReadOnlyList _alternateKeyNameBytes; private readonly byte[] _dataKeyOptionsBytes; /// /// Creates an class. /// /// The byte representation of dataOptions bson document. /// The byte representation of alternate keyName. public KmsKeyId( byte[] dataKeyOptionsBytes, IEnumerable alternateKeyNameBytes = null) { _dataKeyOptionsBytes = dataKeyOptionsBytes ?? throw new ArgumentNullException(nameof(dataKeyOptionsBytes)); _alternateKeyNameBytes = (alternateKeyNameBytes ?? Enumerable.Empty()).ToList().AsReadOnly(); } /// public IReadOnlyList AlternateKeyNameBytes => _alternateKeyNameBytes; // internal methods internal void SetAlternateKeyNames(ContextSafeHandle context, Status status) { foreach (var alternateKeyNameBytes in _alternateKeyNameBytes) { unsafe { fixed (byte* p = alternateKeyNameBytes) { IntPtr ptr = (IntPtr)p; using (PinnedBinary pinned = new PinnedBinary(ptr, (uint)alternateKeyNameBytes.Length)) { context.Check(status, Library.mongocrypt_ctx_setopt_key_alt_name(context, pinned.Handle)); } } } } } internal void SetCredentials(ContextSafeHandle context, Status status) { unsafe { fixed (byte* p = _dataKeyOptionsBytes) { IntPtr ptr = (IntPtr)p; using (PinnedBinary pinned = new PinnedBinary(ptr, (uint)_dataKeyOptionsBytes.Length)) { context.Check(status, Library.mongocrypt_ctx_setopt_key_encryption_key(context, pinned.Handle)); } } } SetAlternateKeyNames(context, status); } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/KmsRequest.cs000066400000000000000000000061241414105245100253530ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Runtime.InteropServices; namespace MongoDB.Libmongocrypt { /// /// Contains a KMS request to make to a remote server. /// /// public class KmsRequest : IStatus { private readonly Status _status; private readonly IntPtr _id; internal KmsRequest(IntPtr id) { _id = id; _status = new Status(); } /// /// Gets the bytes needed from the remote side. No more data is need when this returns 0. /// /// /// The number of bytes needed. /// public uint BytesNeeded { get { return Library.mongocrypt_kms_ctx_bytes_needed(_id); } } /// /// Gets the endpoint. /// /// /// The endpoint. /// public string Endpoint { get { IntPtr stringPointer = IntPtr.Zero; Check(Library.mongocrypt_kms_ctx_endpoint(_id, ref stringPointer)); return Marshal.PtrToStringAnsi(stringPointer); } } /// /// Gets the message to send to KMS. /// /// The message public Binary Message { get { Binary binary = new Binary(); Check(Library.mongocrypt_kms_ctx_message(_id, binary.Handle)); return binary; } } /// /// Feeds the response back to the libmongocrypt /// /// The response. public void Feed(byte[] buffer) { unsafe { fixed (byte* p = buffer) { IntPtr ptr = (IntPtr)p; using (PinnedBinary pinned = new PinnedBinary(ptr, (uint)buffer.Length)) { Check(Library.mongocrypt_kms_ctx_feed(_id, pinned.Handle)); } } } } void IStatus.Check(Status status) { Library.mongocrypt_kms_ctx_status(_id, status.Handle); } private void Check(bool success) { if (!success) { _status.Check(this); } } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/KmsRequestCollection.cs000066400000000000000000000034531414105245100273710ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections; using System.Collections.Generic; namespace MongoDB.Libmongocrypt { /// /// A collection of kms requests to make. /// /// When all requests are done, MarkDone most be called. /// /// public class KmsRequestCollection : IReadOnlyCollection { private List _requests; private CryptContext _parent; internal KmsRequestCollection(List requests, CryptContext parent) { _requests = requests; _parent = parent; } int IReadOnlyCollection.Count => _requests.Count; IEnumerator IEnumerable.GetEnumerator() { return _requests.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _requests.GetEnumerator(); } /// /// Marks alls the KMS requests as complete. /// public void MarkDone() { _parent.MarkKmsDone(); } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/Library.cs000066400000000000000000001006451414105245100246570ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Runtime.InteropServices; namespace MongoDB.Libmongocrypt { /// /// The low-level interface to libmongocrypt. /// public class Library { static Library() { _mongocrypt_version = new Lazy( () => __loader.Value.GetFunction("mongocrypt_version"), true); _mongocrypt_new = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_new")), true); _mongocrypt_init = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_init")), true); _mongocrypt_destroy = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_destroy")), true); _mongocrypt_status = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_status")), true); _mongocrypt_setopt_kms_providers = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_setopt_kms_providers")), true); _mongocrypt_ctx_setopt_key_encryption_key = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_ctx_setopt_key_encryption_key")), true); _mongocrypt_setopt_crypto_hooks = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_setopt_crypto_hooks")), true); _mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5 = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5")), true); _mongocrypt_setopt_log_handler = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_setopt_log_handler")), true); _mongocrypt_setopt_schema_map = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_setopt_schema_map")), true); _mongocrypt_status_new = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_status_new")), true); _mongocrypt_status_destroy = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_status_destroy")), true); _mongocrypt_status_type = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_status_type")), true); _mongocrypt_status_code = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_status_code")), true); _mongocrypt_status_message = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_status_message")), true); _mongocrypt_status_ok = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_status_ok")), true); _mongocrypt_status_set = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_status_set")), true); _mongocrypt_binary_new = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_binary_new")), true); _mongocrypt_binary_destroy = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_binary_destroy")), true); _mongocrypt_binary_new_from_data = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_binary_new_from_data")), true); _mongocrypt_binary_data = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_binary_data")), true); _mongocrypt_binary_len = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_binary_len")), true); _mongocrypt_ctx_new = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_ctx_new")), true); _mongocrypt_ctx_setopt_masterkey_aws = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_ctx_setopt_masterkey_aws")), true); _mongocrypt_ctx_setopt_masterkey_aws_endpoint = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_ctx_setopt_masterkey_aws_endpoint")), true); _mongocrypt_ctx_setopt_masterkey_local = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_ctx_setopt_masterkey_local")), true); _mongocrypt_ctx_setopt_key_alt_name = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_ctx_setopt_key_alt_name")), true); _mongocrypt_ctx_setopt_key_id = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_ctx_setopt_key_id")), true); _mongocrypt_ctx_setopt_algorithm = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_ctx_setopt_algorithm")), true); _mongocrypt_ctx_status = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_ctx_status")), true); _mongocrypt_ctx_encrypt_init = new Lazy( () => __loader.Value .GetFunction(("mongocrypt_ctx_encrypt_init")), true); _mongocrypt_ctx_decrypt_init = new Lazy( () => __loader.Value .GetFunction(("mongocrypt_ctx_decrypt_init")), true); _mongocrypt_ctx_explicit_encrypt_init = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_ctx_explicit_encrypt_init")), true); _mongocrypt_ctx_explicit_decrypt_init = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_ctx_explicit_decrypt_init")), true); _mongocrypt_ctx_datakey_init = new Lazy( () => __loader.Value .GetFunction(("mongocrypt_ctx_datakey_init")), true); _mongocrypt_ctx_state = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_ctx_state")), true); _mongocrypt_ctx_mongo_op = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_ctx_mongo_op")), true); _mongocrypt_ctx_mongo_feed = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_ctx_mongo_feed")), true); _mongocrypt_ctx_mongo_done = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_ctx_mongo_done")), true); _mongocrypt_ctx_next_kms_ctx = new Lazy( () => __loader.Value .GetFunction(("mongocrypt_ctx_next_kms_ctx")), true); _mongocrypt_kms_ctx_endpoint = new Lazy( () => __loader.Value .GetFunction(("mongocrypt_kms_ctx_endpoint")), true); _mongocrypt_kms_ctx_message = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_kms_ctx_message")), true); _mongocrypt_kms_ctx_bytes_needed = new Lazy( () => __loader.Value.GetFunction( ("mongocrypt_kms_ctx_bytes_needed")), true); _mongocrypt_kms_ctx_feed = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_kms_ctx_feed")), true); _mongocrypt_kms_ctx_status = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_kms_ctx_status")), true); _mongocrypt_ctx_kms_done = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_ctx_kms_done")), true); _mongocrypt_ctx_finalize = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_ctx_finalize")), true); _mongocrypt_ctx_destroy = new Lazy( () => __loader.Value.GetFunction(("mongocrypt_ctx_destroy")), true); } /// /// Gets the version of libmongocrypt. /// /// /// The version. /// public static string Version { get { uint length; IntPtr p = mongocrypt_version(out length); return Marshal.PtrToStringAnsi(p); } } internal static Delegates.mongocrypt_version mongocrypt_version => _mongocrypt_version.Value; internal static Delegates.mongocrypt_new mongocrypt_new => _mongocrypt_new.Value; internal static Delegates.mongocrypt_setopt_log_handler mongocrypt_setopt_log_handler => _mongocrypt_setopt_log_handler.Value; internal static Delegates.mongocrypt_setopt_kms_providers mongocrypt_setopt_kms_providers => _mongocrypt_setopt_kms_providers.Value; internal static Delegates.mongocrypt_ctx_setopt_key_encryption_key mongocrypt_ctx_setopt_key_encryption_key => _mongocrypt_ctx_setopt_key_encryption_key.Value; internal static Delegates.mongocrypt_setopt_crypto_hooks mongocrypt_setopt_crypto_hooks => _mongocrypt_setopt_crypto_hooks.Value; internal static Delegates.mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5 mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5 => _mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5.Value; internal static Delegates.mongocrypt_setopt_schema_map mongocrypt_setopt_schema_map => _mongocrypt_setopt_schema_map.Value; internal static Delegates.mongocrypt_init mongocrypt_init => _mongocrypt_init.Value; internal static Delegates.mongocrypt_destroy mongocrypt_destroy => _mongocrypt_destroy.Value; internal static Delegates.mongocrypt_status mongocrypt_status => _mongocrypt_status.Value; internal static Delegates.mongocrypt_status_new mongocrypt_status_new => _mongocrypt_status_new.Value; internal static Delegates.mongocrypt_status_destroy mongocrypt_status_destroy => _mongocrypt_status_destroy.Value; internal static Delegates.mongocrypt_status_type mongocrypt_status_type => _mongocrypt_status_type.Value; internal static Delegates.mongocrypt_status_code mongocrypt_status_code => _mongocrypt_status_code.Value; internal static Delegates.mongocrypt_status_message mongocrypt_status_message => _mongocrypt_status_message.Value; internal static Delegates.mongocrypt_status_ok mongocrypt_status_ok => _mongocrypt_status_ok.Value; internal static Delegates.mongocrypt_status_set mongocrypt_status_set => _mongocrypt_status_set.Value; internal static Delegates.mongocrypt_binary_new mongocrypt_binary_new => _mongocrypt_binary_new.Value; internal static Delegates.mongocrypt_binary_destroy mongocrypt_binary_destroy => _mongocrypt_binary_destroy.Value; internal static Delegates.mongocrypt_binary_new_from_data mongocrypt_binary_new_from_data => _mongocrypt_binary_new_from_data.Value; internal static Delegates.mongocrypt_binary_data mongocrypt_binary_data => _mongocrypt_binary_data.Value; internal static Delegates.mongocrypt_binary_len mongocrypt_binary_len => _mongocrypt_binary_len.Value; internal static Delegates.mongocrypt_ctx_new mongocrypt_ctx_new => _mongocrypt_ctx_new.Value; internal static Delegates.mongocrypt_ctx_setopt_masterkey_aws mongocrypt_ctx_setopt_masterkey_aws => _mongocrypt_ctx_setopt_masterkey_aws.Value; internal static Delegates.mongocrypt_ctx_setopt_masterkey_aws_endpoint mongocrypt_ctx_setopt_masterkey_aws_endpoint => _mongocrypt_ctx_setopt_masterkey_aws_endpoint.Value; internal static Delegates.mongocrypt_ctx_status mongocrypt_ctx_status => _mongocrypt_ctx_status.Value; internal static Delegates.mongocrypt_ctx_encrypt_init mongocrypt_ctx_encrypt_init => _mongocrypt_ctx_encrypt_init.Value; internal static Delegates.mongocrypt_ctx_decrypt_init mongocrypt_ctx_decrypt_init => _mongocrypt_ctx_decrypt_init.Value; internal static Delegates.mongocrypt_ctx_explicit_encrypt_init mongocrypt_ctx_explicit_encrypt_init => _mongocrypt_ctx_explicit_encrypt_init.Value; internal static Delegates.mongocrypt_ctx_explicit_decrypt_init mongocrypt_ctx_explicit_decrypt_init => _mongocrypt_ctx_explicit_decrypt_init.Value; internal static Delegates.mongocrypt_ctx_datakey_init mongocrypt_ctx_datakey_init => _mongocrypt_ctx_datakey_init.Value; internal static Delegates.mongocrypt_ctx_setopt_masterkey_local mongocrypt_ctx_setopt_masterkey_local => _mongocrypt_ctx_setopt_masterkey_local.Value; internal static Delegates.mongocrypt_ctx_setopt_key_id mongocrypt_ctx_setopt_key_id => _mongocrypt_ctx_setopt_key_id.Value; internal static Delegates.mongocrypt_ctx_setopt_key_alt_name mongocrypt_ctx_setopt_key_alt_name => _mongocrypt_ctx_setopt_key_alt_name.Value; internal static Delegates.mongocrypt_ctx_setopt_algorithm mongocrypt_ctx_setopt_algorithm => _mongocrypt_ctx_setopt_algorithm.Value; internal static Delegates.mongocrypt_ctx_state mongocrypt_ctx_state => _mongocrypt_ctx_state.Value; internal static Delegates.mongocrypt_ctx_mongo_op mongocrypt_ctx_mongo_op => _mongocrypt_ctx_mongo_op.Value; internal static Delegates.mongocrypt_ctx_mongo_feed mongocrypt_ctx_mongo_feed => _mongocrypt_ctx_mongo_feed.Value; internal static Delegates.mongocrypt_ctx_mongo_done mongocrypt_ctx_mongo_done => _mongocrypt_ctx_mongo_done.Value; internal static Delegates.mongocrypt_ctx_next_kms_ctx mongocrypt_ctx_next_kms_ctx => _mongocrypt_ctx_next_kms_ctx.Value; internal static Delegates.mongocrypt_kms_ctx_endpoint mongocrypt_kms_ctx_endpoint => _mongocrypt_kms_ctx_endpoint.Value; internal static Delegates.mongocrypt_kms_ctx_message mongocrypt_kms_ctx_message => _mongocrypt_kms_ctx_message.Value; internal static Delegates.mongocrypt_kms_ctx_bytes_needed mongocrypt_kms_ctx_bytes_needed => _mongocrypt_kms_ctx_bytes_needed.Value; internal static Delegates.mongocrypt_kms_ctx_feed mongocrypt_kms_ctx_feed => _mongocrypt_kms_ctx_feed.Value; internal static Delegates.mongocrypt_kms_ctx_status mongocrypt_kms_ctx_status => _mongocrypt_kms_ctx_status.Value; internal static Delegates.mongocrypt_ctx_kms_done mongocrypt_ctx_kms_done => _mongocrypt_ctx_kms_done.Value; internal static Delegates.mongocrypt_ctx_finalize mongocrypt_ctx_finalize => _mongocrypt_ctx_finalize.Value; internal static Delegates.mongocrypt_ctx_destroy mongocrypt_ctx_destroy => _mongocrypt_ctx_destroy.Value; private static readonly Lazy __loader = new Lazy( () => new LibraryLoader(), true); private static readonly Lazy _mongocrypt_version; private static readonly Lazy _mongocrypt_new; private static readonly Lazy _mongocrypt_setopt_log_handler; private static readonly Lazy _mongocrypt_setopt_kms_providers; private static readonly Lazy _mongocrypt_ctx_setopt_key_encryption_key; private static readonly Lazy _mongocrypt_setopt_crypto_hooks; private static readonly Lazy _mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5; private static readonly Lazy _mongocrypt_setopt_schema_map; private static readonly Lazy _mongocrypt_init; private static readonly Lazy _mongocrypt_destroy; private static readonly Lazy _mongocrypt_status; private static readonly Lazy _mongocrypt_status_new; private static readonly Lazy _mongocrypt_status_destroy; private static readonly Lazy _mongocrypt_status_type; private static readonly Lazy _mongocrypt_status_code; private static readonly Lazy _mongocrypt_status_message; private static readonly Lazy _mongocrypt_status_ok; private static readonly Lazy _mongocrypt_status_set; private static readonly Lazy _mongocrypt_binary_new; private static readonly Lazy _mongocrypt_binary_destroy; private static readonly Lazy _mongocrypt_binary_new_from_data; private static readonly Lazy _mongocrypt_binary_data; private static readonly Lazy _mongocrypt_binary_len; private static readonly Lazy _mongocrypt_ctx_new; private static readonly Lazy _mongocrypt_ctx_setopt_masterkey_aws; private static readonly Lazy _mongocrypt_ctx_setopt_masterkey_aws_endpoint; private static readonly Lazy _mongocrypt_ctx_status; private static readonly Lazy _mongocrypt_ctx_encrypt_init; private static readonly Lazy _mongocrypt_ctx_decrypt_init; private static readonly Lazy _mongocrypt_ctx_explicit_encrypt_init; private static readonly Lazy _mongocrypt_ctx_explicit_decrypt_init; private static readonly Lazy _mongocrypt_ctx_datakey_init; private static readonly Lazy _mongocrypt_ctx_setopt_masterkey_local; private static readonly Lazy _mongocrypt_ctx_setopt_key_id; private static readonly Lazy _mongocrypt_ctx_setopt_key_alt_name; private static readonly Lazy _mongocrypt_ctx_setopt_algorithm; private static readonly Lazy _mongocrypt_ctx_state; private static readonly Lazy _mongocrypt_ctx_mongo_op; private static readonly Lazy _mongocrypt_ctx_mongo_feed; private static readonly Lazy _mongocrypt_ctx_mongo_done; private static readonly Lazy _mongocrypt_ctx_next_kms_ctx; private static readonly Lazy _mongocrypt_kms_ctx_endpoint; private static readonly Lazy _mongocrypt_kms_ctx_message; private static readonly Lazy _mongocrypt_kms_ctx_bytes_needed; private static readonly Lazy _mongocrypt_kms_ctx_feed; private static readonly Lazy _mongocrypt_kms_ctx_status; private static readonly Lazy _mongocrypt_ctx_kms_done; private static readonly Lazy _mongocrypt_ctx_finalize; private static readonly Lazy _mongocrypt_ctx_destroy; internal enum StatusType { MONGOCRYPT_STATUS_OK = 0, MONGOCRYPT_STATUS_ERROR_CLIENT, MONGOCRYPT_STATUS_ERROR_KMS } internal class Delegates { // NOTE: Bool is expected to be 4 bytes during marshalling so we need to overwite it // https://blogs.msdn.microsoft.com/jaredpar/2008/10/14/pinvoke-and-bool-or-should-i-say-bool/ public delegate IntPtr mongocrypt_version(out uint length); public delegate MongoCryptSafeHandle mongocrypt_new(); public delegate void LogCallback([MarshalAs(UnmanagedType.I4)] LogLevel level, IntPtr messasge, uint message_length, IntPtr context); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_setopt_log_handler(MongoCryptSafeHandle handle, [MarshalAs(UnmanagedType.FunctionPtr)] LogCallback log_fn, IntPtr log_ctx); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_setopt_kms_providers( MongoCryptSafeHandle handle, BinarySafeHandle kms_providers); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_setopt_key_encryption_key( ContextSafeHandle handle, BinarySafeHandle bin); [return: MarshalAs(UnmanagedType.I1)] public delegate bool HashCallback( IntPtr ctx, IntPtr @in, IntPtr @out, IntPtr status); [return: MarshalAs(UnmanagedType.I1)] public delegate bool CryptoHmacCallback( IntPtr ctx, IntPtr key, IntPtr @in, IntPtr @out, IntPtr status); [return: MarshalAs(UnmanagedType.I1)] public delegate bool CryptoCallback( IntPtr ctx, IntPtr key, IntPtr iv, IntPtr @in, IntPtr @out, ref uint bytes_written, IntPtr status); [return: MarshalAs(UnmanagedType.I1)] public delegate bool RandomCallback( IntPtr ctx, IntPtr @out, uint count, IntPtr statusPtr); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_setopt_crypto_hooks( MongoCryptSafeHandle handle, [MarshalAs(UnmanagedType.FunctionPtr)] CryptoCallback aes_256_cbc_encrypt, [MarshalAs(UnmanagedType.FunctionPtr)] CryptoCallback aes_256_cbc_decrypt, [MarshalAs(UnmanagedType.FunctionPtr)] RandomCallback random, [MarshalAs(UnmanagedType.FunctionPtr)] CryptoHmacCallback hmac_sha_512, [MarshalAs(UnmanagedType.FunctionPtr)] CryptoHmacCallback hmac_sha_256, [MarshalAs(UnmanagedType.FunctionPtr)] HashCallback mongocrypt_hash_fn, IntPtr ctx); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5( MongoCryptSafeHandle handle, [MarshalAs(UnmanagedType.FunctionPtr)] CryptoHmacCallback sign_rsaes_pkcs1_v1_5, IntPtr sign_ctx); [return: MarshalAs(UnmanagedType.I1),] public delegate bool mongocrypt_setopt_schema_map(MongoCryptSafeHandle handle, BinarySafeHandle schema); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_init(MongoCryptSafeHandle handle); public delegate void mongocrypt_destroy(IntPtr ptr); public delegate bool mongocrypt_status(MongoCryptSafeHandle handle, StatusSafeHandle ptr); public delegate StatusSafeHandle mongocrypt_status_new(); public delegate void mongocrypt_status_destroy(IntPtr ptr); public delegate StatusType mongocrypt_status_type(StatusSafeHandle ptr); public delegate uint mongocrypt_status_code(StatusSafeHandle ptr); public delegate IntPtr mongocrypt_status_message(StatusSafeHandle ptr, out uint length); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_status_ok(StatusSafeHandle ptr); // currently it does nothing due to MONGOCRYPT-257 public delegate void mongocrypt_status_set(StatusSafeHandle ptr, int type, uint code, IntPtr msg, int length); public delegate BinarySafeHandle mongocrypt_binary_new(); public delegate void mongocrypt_binary_destroy(IntPtr ptr); public delegate BinarySafeHandle mongocrypt_binary_new_from_data(IntPtr ptr, uint len); public delegate IntPtr mongocrypt_binary_data(BinarySafeHandle handle); public delegate uint mongocrypt_binary_len(BinarySafeHandle handle); public delegate ContextSafeHandle mongocrypt_ctx_new(MongoCryptSafeHandle handle); [return: MarshalAs(UnmanagedType.I1),] public delegate bool mongocrypt_ctx_setopt_masterkey_aws(ContextSafeHandle handle, IntPtr region, int region_len, IntPtr cmk, int cmk_len); [return: MarshalAs(UnmanagedType.I1),] public delegate bool mongocrypt_ctx_setopt_masterkey_aws_endpoint( ContextSafeHandle handle, IntPtr endpoint, int endpoint_len); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_status(ContextSafeHandle handle, StatusSafeHandle status); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_encrypt_init(ContextSafeHandle handle, IntPtr ns, int length, BinarySafeHandle binary); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_decrypt_init(ContextSafeHandle handle, BinarySafeHandle binary); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_explicit_encrypt_init(ContextSafeHandle handle, BinarySafeHandle binary); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_explicit_decrypt_init(ContextSafeHandle handle, BinarySafeHandle binary); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_datakey_init(ContextSafeHandle handle); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_setopt_schema_map(ContextSafeHandle handle, BinarySafeHandle binary); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_setopt_masterkey_local(ContextSafeHandle handle); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_setopt_key_alt_name(ContextSafeHandle handle, BinarySafeHandle binary); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_setopt_key_id(ContextSafeHandle handle, BinarySafeHandle binary); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_setopt_algorithm(ContextSafeHandle handle, [MarshalAs(UnmanagedType.LPStr)] string algorithm, int length); public delegate CryptContext.StateCode mongocrypt_ctx_state(ContextSafeHandle handle); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_mongo_op(ContextSafeHandle handle, BinarySafeHandle bsonOp); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_mongo_feed(ContextSafeHandle handle, BinarySafeHandle reply); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_mongo_done(ContextSafeHandle handle); public delegate IntPtr mongocrypt_ctx_next_kms_ctx(ContextSafeHandle handle); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_kms_ctx_endpoint(IntPtr handle, ref IntPtr endpoint); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_kms_ctx_message(IntPtr handle, BinarySafeHandle binary); public delegate uint mongocrypt_kms_ctx_bytes_needed(IntPtr handle); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_kms_ctx_feed(IntPtr handle, BinarySafeHandle binary); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_kms_ctx_status(IntPtr handle, StatusSafeHandle status); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_kms_done(ContextSafeHandle handle); [return: MarshalAs(UnmanagedType.I1)] public delegate bool mongocrypt_ctx_finalize(ContextSafeHandle handle, BinarySafeHandle binary); public delegate void mongocrypt_ctx_destroy(IntPtr ptr); } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/LibraryLoader.cs000066400000000000000000000225021414105245100260010ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Runtime.InteropServices; namespace MongoDB.Libmongocrypt { /// /// LibraryLoader abstracts loading C functions from a shared library across OS /// internal class LibraryLoader { private ISharedLibraryLoader _loader; public LibraryLoader() { if (!Environment.Is64BitProcess) { throw new PlatformNotSupportedException($"{this.GetType().Namespace} needs to be run in a 64-bit process."); } // Windows: // https://stackoverflow.com/questions/2864673/specify-the-search-path-for-dllimport-in-net // // See for better ways // https://github.com/dotnet/coreclr/issues/930 // https://github.com/dotnet/corefx/issues/32015 List candidatePaths = new List(); // In the nuget package, get the shared library from a relative path of this assembly // Also, when running locally, get the shared library from a relative path of this assembly var assembly = typeof(LibraryLoader).GetTypeInfo().Assembly; var location = assembly.Location; string basepath = Path.GetDirectoryName(location); candidatePaths.Add(basepath); switch (OperatingSystemHelper.CurrentOperatingSystem) { case OperatingSystemPlatform.MacOS: { string[] suffixPaths = new[] { "../../runtimes/osx/native/", "runtimes/osx/native/", string.Empty }; string path = FindLibrary(candidatePaths, suffixPaths, "libmongocrypt.dylib"); _loader = new DarwinLibraryLoader(path); } break; case OperatingSystemPlatform.Linux: { string[] suffixPaths = new[] { "../../runtimes/linux/native/", "runtimes/linux/native/", string.Empty }; string path = FindLibrary(candidatePaths, suffixPaths, "libmongocrypt.so"); _loader = new LinuxLibrary(path); } break; case OperatingSystemPlatform.Windows: { string[] suffixPaths = new[] { @"..\..\runtimes\win\native\", @".\runtimes\win\native\", string.Empty }; string path = FindLibrary(candidatePaths, suffixPaths, "mongocrypt.dll"); _loader = new WindowsLibrary(path); } break; default: // should not be reached. If we're here, then there is a bug in OperatingSystemHelper throw new PlatformNotSupportedException("Unsupported operating system."); } } private string FindLibrary(IList basePaths, string[] suffixPaths, string library) { var candidates = new List(); foreach (var basePath in basePaths) { foreach (var suffix in suffixPaths) { string path = Path.Combine(basePath, suffix, library); if (File.Exists(path)) { // TODO - .NET Standard 2.0 //Trace.WriteLine("Load path: " + path); return path; } candidates.Add(path); } } throw new FileNotFoundException("Could not find: " + library + " --\n Tried: " + string.Join(",", candidates)); } public T GetFunction(string name) { IntPtr ptr = _loader.GetFunction(name); if (ptr == IntPtr.Zero) { throw new FunctionNotFoundException(name); } return Marshal.GetDelegateForFunctionPointer(ptr); } public class FunctionNotFoundException : Exception { public FunctionNotFoundException(string message) : base(message) { } } private interface ISharedLibraryLoader { IntPtr GetFunction(string name); } /// /// macOS Dynamic Library loader using dlsym /// private class DarwinLibraryLoader : ISharedLibraryLoader { // See dlfcn.h // #define RTLD_LAZY 0x1 // #define RTLD_NOW 0x2 // #define RTLD_LOCAL 0x4 // #define RTLD_GLOBAL 0x8 public const int RTLD_GLOBAL = 0x8; public const int RTLD_NOW = 0x2; private readonly IntPtr _handle; public DarwinLibraryLoader(string path) { _handle = dlopen(path, RTLD_GLOBAL | RTLD_NOW); if (_handle == IntPtr.Zero) { throw new FileNotFoundException(path); } } public IntPtr GetFunction(string name) { return dlsym(_handle, name); } #pragma warning disable IDE1006 // Naming Styles [DllImport("libdl")] public static extern IntPtr dlopen(string filename, int flags); [DllImport("libdl", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern IntPtr dlsym(IntPtr handle, string symbol); #pragma warning restore IDE1006 // Naming Styles } /// /// Linux Shared Object loader using dlsym /// private class LinuxLibrary : ISharedLibraryLoader { // See dlfcn.h // #define RTLD_LAZY 0x1 // #define RTLD_NOW 0x2 // #define RTLD_LOCAL 0x4 // #define RTLD_GLOBAL 0x100 public const int RTLD_GLOBAL = 0x100; public const int RTLD_NOW = 0x2; private readonly IntPtr _handle; public LinuxLibrary(string path) { _handle = dlopen(path, RTLD_GLOBAL | RTLD_NOW); if (_handle == IntPtr.Zero) { throw new FileNotFoundException(path); } } public IntPtr GetFunction(string name) { return dlsym(_handle, name); } #pragma warning disable IDE1006 // Naming Styles [DllImport("libdl")] public static extern IntPtr dlopen(string filename, int flags); [DllImport("libdl", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern IntPtr dlsym(IntPtr handle, string symbol); #pragma warning restore IDE1006 // Naming Styles } /// /// Windows DLL loader using GetProcAddress /// private class WindowsLibrary : ISharedLibraryLoader { private readonly IntPtr _handle; public WindowsLibrary(string path) { _handle = LoadLibrary(path); if (_handle == IntPtr.Zero) { var gle = Marshal.GetLastWin32Error(); // error code 193 indicates that a 64-bit OS has tried to load a 32-bit dll // https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499- throw new LibraryLoadingException(path + ", Windows Error: " + gle); } } public IntPtr GetFunction(string name) { var ptr = GetProcAddress(_handle, name); if (ptr == null) { var gle = Marshal.GetLastWin32Error(); throw new FunctionNotFoundException(name + ", Windows Error: " + gle); } return ptr; } [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)] public static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)] string lpFileName); [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)] public static extern IntPtr GetProcAddress(IntPtr hModule, string procName); } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/LibraryLoadingException.cs000066400000000000000000000021301414105245100300220ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; namespace MongoDB.Libmongocrypt { /// /// An exception that indicates that an error occured while loading a library. /// public class LibraryLoadingException : Exception { /// /// Initializes an instance of a /// /// The message. public LibraryLoadingException(string message) : base(message) { } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/License.txt000066400000000000000000000011151414105245100250370ustar00rootroot00000000000000/* Copyright 2010–present MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/LogLevel.cs000066400000000000000000000015571414105245100247660ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace MongoDB.Libmongocrypt { public enum LogLevel { MONGOCRYPT_LOG_LEVEL_FATAL = 0, MONGOCRYPT_LOG_LEVEL_ERROR = 1, MONGOCRYPT_LOG_LEVEL_WARNING = 2, MONGOCRYPT_LOG_LEVEL_INFO = 3, MONGOCRYPT_LOG_LEVEL_TRACE = 4 }; } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/MongoCryptSafeHandle.cs000066400000000000000000000033351414105245100272650ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; namespace MongoDB.Libmongocrypt { /// /// SafeHandle to manage the lifetime of a mongocrypt_t. /// /// internal class MongoCryptSafeHandle : SafeHandle { private MongoCryptSafeHandle() : base(IntPtr.Zero, true) { } public void Check(Status status, bool success) { if (!success) { Library.mongocrypt_status(this, status.Handle); status.ThrowExceptionIfNeeded(); } } public override bool IsInvalid { get { return handle == IntPtr.Zero; } } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { // Here, we must obey all rules for constrained execution regions. Library.mongocrypt_destroy(handle); return true; } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/MongoDB.Libmongocrypt.csproj000066400000000000000000000103621414105245100302560ustar00rootroot00000000000000 net472;netstandard2.0;netstandard2.1 netstandard2.0;netstandard2.1 AnyCPU 7.3 true MongoDB.Libmongocrypt.ruleset MongoDB.Libmongocrypt MongoDB.Libmongocrypt MongoDB Inc. Copyright © 2019–present MongoDB Inc. Libmongocrypt wrapper for the .NET driver. MongoDB Inc. http://jobs.mongodb.org/files/logos/889002/889002.png true Libmongocrypt wrapper for the .NET driver. http://www.mongodb.org/display/DOCS/CSharp+Language+Center License.txt mongodb;mongo;nosql en-US true ../../../cmake-build/$(Configuration) ../../../cmake-build/RelWithDebInfo/ libmongocrypt.so Always libmongocrypt.dylib Always mongocrypt.dll Always mongocrypt.pdb Always true runtimes/win/native true runtimes/linux/native true runtimes/osx/native true $(PackageLicenseFile) true build 1.1.0 bin\x64\Debug\MongoDB.Libmongocrypt.xml true bin\x64\Release\MongoDB.Libmongocrypt.xml libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/MongoDB.Libmongocrypt.ruleset000066400000000000000000000076261414105245100304520ustar00rootroot00000000000000 libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/MongoDB.Libmongocrypt.targets000066400000000000000000000017241414105245100304310ustar00rootroot00000000000000 Always mongocrypt.dll Always libmongocrypt.so Always libmongocrypt.dylib libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/OperatingSystemHelper.cs000066400000000000000000000034231414105245100275440ustar00rootroot00000000000000/* * Copyright 2020–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !NET472 using System; using System.Runtime.InteropServices; #endif namespace MongoDB.Libmongocrypt { internal enum OperatingSystemPlatform { Windows, Linux, MacOS } internal static class OperatingSystemHelper { public static OperatingSystemPlatform CurrentOperatingSystem { get { #if NET472 return OperatingSystemPlatform.Windows; #else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { return OperatingSystemPlatform.MacOS; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { return OperatingSystemPlatform.Linux; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return OperatingSystemPlatform.Windows; } // should not be reached. If we're here, then there is a bug in the library throw new PlatformNotSupportedException($"Unsupported platform '{RuntimeInformation.OSDescription}'."); #endif } } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/Package.include.template.csproj000066400000000000000000000032211414105245100307250ustar00rootroot00000000000000 false @CMAKE_CURRENT_LIST_DIR@/MongoDB.Libmongocrypt PreserveNewest x64/native/linux/libmongocrypt.so true PreserveNewest x64/native/osx/libmongocrypt.dylib true PreserveNewest x64/native/windows/mongocrypt.dll true PreserveNewest x64/native/windows/mongocrypt.dll true libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/PinnedBinary.cs000066400000000000000000000017601414105245100256330ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; namespace MongoDB.Libmongocrypt { /// /// A handle to a binary that must be either in unsafe code or pinned by the GC. /// /// internal class PinnedBinary : Binary { internal PinnedBinary(IntPtr ptr, uint len) : base(Library.mongocrypt_binary_new_from_data(ptr, len)) { } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/SecureRandomCallback.cs000066400000000000000000000032021414105245100272460ustar00rootroot00000000000000/* * Copyright 2020–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Security.Cryptography; namespace MongoDB.Libmongocrypt { internal static class SecureRandomCallback { public static bool GenerateRandom( IntPtr ctx, IntPtr @out, uint count, IntPtr statusPtr) { using (var outBinary = new Binary(BinarySafeHandle.FromIntPtr(@out))) using (var status = new Status(StatusSafeHandle.FromIntPtr(statusPtr))) { try { using (var randomNumberGenerator = RandomNumberGenerator.Create()) { var bytes = new byte[count]; randomNumberGenerator.GetBytes(bytes); outBinary.WriteBytes(bytes); return true; } } catch (Exception e) { status.SetStatus(1, e.Message); return false; } } } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/SigningRSAESPKCSCallback.cs000066400000000000000000000047031414105245100275430ustar00rootroot00000000000000/* * Copyright 2020–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; #if NETSTANDARD2_1 using System.Security.Cryptography; #endif namespace MongoDB.Libmongocrypt { internal static class SigningRSAESPKCSCallback { public static bool RsaSign( IntPtr ctx, IntPtr key, IntPtr inData, IntPtr outData, IntPtr statusPtr) { using (var status = new Status(StatusSafeHandle.FromIntPtr(statusPtr))) { try { var keyBinary = new Binary(BinarySafeHandle.FromIntPtr(key)); var inputBinary = new Binary(BinarySafeHandle.FromIntPtr(inData)); var outBinary = new Binary(BinarySafeHandle.FromIntPtr(outData)); byte[] inputBytes = inputBinary.ToArray(); byte[] keyBytes = keyBinary.ToArray(); // Hash and sign the data. var signedData = HashAndSignBytes(inputBytes, keyBytes); outBinary.WriteBytes(signedData); return true; } catch (Exception e) { // let mongocrypt level to handle the error status.SetStatus(1, e.Message); return false; } } } public static byte[] HashAndSignBytes(byte[] dataToSign, byte[] key) { #if NETSTANDARD2_1 using (var rsaProvider = new RSACryptoServiceProvider()) { rsaProvider.ImportPkcs8PrivateKey(key, out _); return rsaProvider.SignData(dataToSign, SHA256.Create()); } #else throw new System.PlatformNotSupportedException("RSACryptoServiceProvider.ImportPkcs8PrivateKey is supported only on frameworks higher or equal to .netstandard2.1."); #endif } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/Status.cs000066400000000000000000000053621414105245100245360ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Runtime.InteropServices; namespace MongoDB.Libmongocrypt { /// /// A LibMongoCrypt Status /// /// internal class Status : IDisposable { private StatusSafeHandle _handle; public Status() { _handle = Library.mongocrypt_status_new(); } public Status(StatusSafeHandle handle) { _handle = handle; } public void Check(IStatus status) { status.Check(this); ThrowExceptionIfNeeded(); } public void SetStatus(uint code, string msg) { IntPtr stringPointer = (IntPtr)Marshal.StringToHGlobalAnsi(msg); try { Library.mongocrypt_status_set(_handle, (int)Library.StatusType.MONGOCRYPT_STATUS_ERROR_CLIENT, code, stringPointer, -1); } finally { Marshal.FreeHGlobal(stringPointer); } } #region IDisposable public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { // Adapted from: https://docs.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.safehandle?view=netcore-3.0 if (_handle != null && !_handle.IsInvalid) { // Free the handle _handle.Dispose(); } } #endregion internal StatusSafeHandle Handle => _handle; internal void ThrowExceptionIfNeeded() { if (!Library.mongocrypt_status_ok(_handle)) { var statusType = Library.mongocrypt_status_type(_handle); var statusCode = Library.mongocrypt_status_code(_handle); uint length; IntPtr msgPtr = Library.mongocrypt_status_message(_handle, out length); var message = Marshal.PtrToStringAnsi(msgPtr); throw new CryptException(statusType, statusCode, message); } } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/StatusSafeHandle.cs000066400000000000000000000033221414105245100264430ustar00rootroot00000000000000/* * Copyright 2019–present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; namespace MongoDB.Libmongocrypt { /// /// SafeHandle to manage the lifetime of a mongocrypt_status_t. /// /// internal class StatusSafeHandle : SafeHandle { private StatusSafeHandle() : base(IntPtr.Zero, true) { } private StatusSafeHandle(IntPtr ptr) : base(ptr, false) { } public static StatusSafeHandle FromIntPtr(IntPtr ptr) { return new StatusSafeHandle(ptr); } public override bool IsInvalid { get { return handle == IntPtr.Zero; } } [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] protected override bool ReleaseHandle() { // Here, we must obey all rules for constrained execution regions. Library.mongocrypt_status_destroy(handle); return true; } } } libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/StyleCop.ruleset000066400000000000000000000007151414105245100260700ustar00rootroot00000000000000 libmongocrypt-1.3.0/bindings/cs/MongoDB.Libmongocrypt/stylecop.json000066400000000000000000000003731414105245100254560ustar00rootroot00000000000000{ "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", "settings": { "layoutRules": { "newlineAtEndOfFile": "require" } } } libmongocrypt-1.3.0/bindings/cs/README.md000066400000000000000000000032411414105245100200610ustar00rootroot00000000000000# Requirements __All__ CMake 3.12 or later __Windows__ Visual Studio 2017 15.9+ __Linux, macOS__ dotnet 2.1+ # Quick Instructions *Requires:* Cygwin ``` 1. bash ./libmongocrypt/.evergreen/compile.sh ``` *Note*: You must call this from the parent directory of the libmongocrypt repo. It will not work within the repo directory ## Developer Instructions ### Windows To build libmongocrypt on Windows. This example assumes kms-message and the c driver are installed to "d:/usr" ``` 1. mkdir build 2. "C:\Program Files\CMake\bin\cmake.exe" -Thost=x64 -G "Visual Studio 15 2017 Win64" -DCMAKE_INSTALL_PREFIX=d:/usr -DCMAKE_PREFIX_PATH=d:/usr -DCMAKE_BUILD_TYPE=Debug "-DCMAKE_C_FLAGS=-Id:/usr/include" .. 3. msbuild libmongocrypt.sln 4. cd bindings/cs 5. msbuild cs.sln ``` ### Troubleshooting If you see `Windows Error: 126` during tests, like the example below, it means that `libbson-1.0.dll` is not in your path. ``` System.TypeInitializationException : The type initializer for 'MongoDB.Libmongocrypt.Library' threw an exception. ---- System.IO.FileNotFoundException : D:\repo\libmongocrypt\build\bindings\cs\MongoDB.Libmongocrypt.Test\bin\x64\Debug\netcoreapp2.1\mongocrypt.dll, Windows Error: 126 ``` ### Linux and macOS *Note* Only building from the cmake build directory is supported ``` 1. Build libmongocrypt with CMake 2. cd /bindings/cs 3. dotnet build cs.build ``` # Testing Do not modify xunit.runner.json - Be wary of https://github.com/xunit/xunit/issues/1654 ### Debugging on Linux To attach to a unit test with lldb, print the PID in the process and then attach. Tests always run in child processes and lldb, as of 7.0, cannot follow child processes. libmongocrypt-1.3.0/bindings/cs/Scripts/000077500000000000000000000000001414105245100202315ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/cs/Scripts/build.cake000066400000000000000000000201761414105245100221630ustar00rootroot00000000000000#addin nuget:?package=Cake.FileHelpers&version=3.3.0 #addin nuget:?package=Cake.Git&version=0.22.0 #addin nuget:?package=Cake.Incubator&version=5.1.0 #tool dotnet:?package=GitVersion.Tool&version=5.3.7 using System; using System.Linq; var target = Argument("target", "CreatePackage"); var configuration = Argument("configuration", "Release"); var gitVersion = GitVersion(); var buildDirectory = MakeAbsolute(Directory(GetSettingValue("buildDirectory", "c:\\build"))); var libmongocryptAllDirectory=buildDirectory.Combine("libmongocrypt-all"); var downloadedMongocryptDirectory=buildDirectory.Combine("downloadedMongocryptDirectory"); var localReleaseVersion = "local-0.0.0"; var releaseVersion = GetSettingValue("releaseVersion", localReleaseVersion); var fork = GetSettingValue("fork", "https://github.com/mongodb/libmongocrypt.git"); var branch = GetSettingValue("branch", "master"); var libmongocryptAllUrl = GetSettingValue("url", "https://mciuploads.s3.amazonaws.com/libmongocrypt/all/master/811df516e2985a08eab5b5e0eeca00823b2a2a58/libmongocrypt-all.tar.gz"); var csharpBindingsGitTagName = $"csharp-v{releaseVersion}"; var csharpBindingsDirectory = buildDirectory.Combine(csharpBindingsGitTagName); var libmongocryptRelWithDebInfoDirectory = csharpBindingsDirectory.Combine("cmake-build").Combine("RelWithDebInfo"); var libmongocryptCsDirectory = csharpBindingsDirectory.Combine("bindings").Combine("cs"); var libmongocryptSolutionDirectory = libmongocryptCsDirectory.Combine("MongoDB.Libmongocrypt"); var libmongocryptSolutionFile = libmongocryptSolutionDirectory.CombineWithFilePath("MongoDB.Libmongocrypt.csproj"); var libmongocryptTestsSolutionDirectory = libmongocryptCsDirectory.Combine("MongoDB.Libmongocrypt.Test"); var artifactsDirectory = buildDirectory.Combine("artifacts"); Task("Prepare") .Does(() => { if (DirectoryExists(buildDirectory)) { DeleteDirectory( buildDirectory, new DeleteDirectorySettings { Recursive = true, Force = true }); } CreateDirectory(buildDirectory); Information($"Release version: {releaseVersion}"); Information($"Fork: {fork}"); Information($"Branch: {branch}"); Information($"Native libraries url: {libmongocryptAllUrl}"); Information("Downloading native libs.."); EnsureDirectoryExists(libmongocryptAllDirectory); var nativeLibrariesArchive = libmongocryptAllDirectory.CombineWithFilePath("libmongocrypt-all.tar"); DownloadFile(libmongocryptAllUrl, nativeLibrariesArchive); Information("Unzipping.."); UncompressToTheCurrentDirectory(nativeLibrariesArchive); Information("Cloning the libmongocrypt repo.."); GitClone( fork, csharpBindingsDirectory, new GitCloneSettings { BranchName = branch, Checkout = true, IsBare = false, RecurseSubmodules = true }); EnsureDirectoryExists(libmongocryptRelWithDebInfoDirectory); EnsureDirectoryExists(downloadedMongocryptDirectory); CopyFile( libmongocryptAllDirectory.Combine("windows-test").Combine("bin").CombineWithFilePath("mongocrypt.dll"), downloadedMongocryptDirectory.CombineWithFilePath("mongocrypt.dll")); CopyFile( libmongocryptAllDirectory.Combine("ubuntu1804-64").Combine("nocrypto").Combine("lib").CombineWithFilePath("libmongocrypt.so"), downloadedMongocryptDirectory.CombineWithFilePath("libmongocrypt.so")); CopyFile( libmongocryptAllDirectory.Combine("macos").Combine("nocrypto").Combine("lib").CombineWithFilePath("libmongocrypt.dylib"), downloadedMongocryptDirectory.CombineWithFilePath("libmongocrypt.dylib")); CopyDirectory(downloadedMongocryptDirectory, libmongocryptRelWithDebInfoDirectory); }); Task("Tests") .IsDependentOn("Prepare") .DoesForEach( () => { var monikersDetails = new List<(string Moniker, string Bitness)> { { ("net472", "x64") }, { ("netcoreapp2.1", "x64") }, { ("netcoreapp3.0", "x64") }, { ("net50", "x64") } }; return monikersDetails; }, (monikerInfo) => { Information($"Test running {monikerInfo.Moniker}.."); var settings = new DotNetCoreTestSettings { Configuration = configuration, Framework = monikerInfo.Moniker, ArgumentCustomization = args => args.Append($"-- RunConfiguration.TargetPlatform={monikerInfo.Bitness}") }; var projectFullPath = libmongocryptTestsSolutionDirectory.CombineWithFilePath("MongoDB.Libmongocrypt.Test.csproj").FullPath; Information(projectFullPath); DotNetCoreTest( projectFullPath, settings ); }) .DeferOnError(); Task("CreatePackage") .IsDependentOn("Tests") .Does(() => { var projectFullPath = libmongocryptSolutionFile.FullPath; Information($"Project path: {projectFullPath}. ReleaseVersion: {releaseVersion}"); var settings = new DotNetCorePackSettings { Configuration = configuration, OutputDirectory = artifactsDirectory, EnvironmentVariables = new Dictionary { { "Version", releaseVersion }, } }; DotNetCorePack( projectFullPath, settings); }); Task("NugetPush") .Does(() => { ThrowIfLocalRelease(); var nugetApi = GetSettingValue("NugetApiKey", null); var packageFilePath = artifactsDirectory.CombineWithFilePath($"{libmongocryptSolutionFile.GetFilenameWithoutExtension().ToString()}.{releaseVersion}.nupkg"); Information(packageFilePath); NuGetPush( packageFilePath, new NuGetPushSettings { ApiKey = nugetApi, Source = "https://api.nuget.org/v3/index.json" }); }); Task("CreateGitTag") .Does(() => { ThrowIfLocalRelease(); Information($"Directory: {libmongocryptSolutionDirectory}"); Information("Show origin:"); Git(libmongocryptSolutionDirectory, "remote -v"); Git(libmongocryptSolutionDirectory, $"tag -a {csharpBindingsGitTagName} -m {csharpBindingsGitTagName}"); Git(libmongocryptSolutionDirectory, $"push origin {csharpBindingsGitTagName}"); }); RunTarget(target); string GetSettingValue(string commandArgumentName, string defaultValue) { var optionValue = Argument(commandArgumentName, (string)null); if (optionValue != null) { return optionValue; } var environmentVariableName = $"LIBMONGOCRYPT_PACKAGING_{commandArgumentName.ToUpper()}"; var environmentVariable = Environment.GetEnvironmentVariable(environmentVariableName); if (environmentVariable == null) { if (defaultValue == null) { throw new Exception($"Neither {commandArgumentName} command argument nor {environmentVariableName} environmentVariable have been configured."); } else { return defaultValue; } } return environmentVariable; } void Git(DirectoryPath workingDirectory, string command) { CustomToolCall(workingDirectory, "git", command); } void UncompressToTheCurrentDirectory(FilePath archiveFilePath) { CustomToolCall(archiveFilePath.GetDirectory(), "tar", "xzvf", archiveFilePath.GetFilename().ToString()); } void CustomToolCall(DirectoryPath workingDirectory, string tool, params string[] arguments) { var argumentsBuilder = new ProcessArgumentBuilder(); foreach (var argument in arguments) { argumentsBuilder.Append(argument); } Information($"{tool} {string.Join(" ", arguments)}"); StartProcess(tool, new ProcessSettings { Arguments = argumentsBuilder, WorkingDirectory = workingDirectory }); } void ThrowIfLocalRelease() { if (releaseVersion == localReleaseVersion) { throw new Exception("Attempt to publish a local nuget."); } } libmongocrypt-1.3.0/bindings/cs/Scripts/build.ps1000066400000000000000000000216311414105245100217600ustar00rootroot00000000000000########################################################################## # This is the Cake bootstrapper script for PowerShell. # This file was downloaded from https://github.com/cake-build/resources # Feel free to change this file to fit your needs. ########################################################################## <# .SYNOPSIS This is a Powershell script to bootstrap a Cake build. .DESCRIPTION This Powershell script will download NuGet if missing, restore NuGet tools (including Cake) and execute your Cake build script with the parameters you provide. .PARAMETER Script The build script to execute. .PARAMETER Target The build script target to run. .PARAMETER Configuration The build configuration to use. .PARAMETER Verbosity Specifies the amount of information to be displayed. .PARAMETER ShowDescription Shows description about tasks. .PARAMETER DryRun Performs a dry run. .PARAMETER SkipToolPackageRestore Skips restoring of packages. .PARAMETER ScriptArgs Remaining arguments are added here. .LINK https://cakebuild.net #> [CmdletBinding()] Param( [string]$Script, [string]$Target, [string]$Configuration, [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] [string]$Verbosity, [switch]$ShowDescription, [Alias("WhatIf", "Noop")] [switch]$DryRun, [switch]$SkipToolPackageRestore, [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] [string[]]$ScriptArgs ) # This is an automatic variable in PowerShell Core, but not in Windows PowerShell 5.x if (-not (Test-Path variable:global:IsCoreCLR)) { $IsCoreCLR = $false } # Attempt to set highest encryption available for SecurityProtocol. # PowerShell will not set this by default (until maybe .NET 4.6.x). This # will typically produce a message for PowerShell v2 (just an info # message though) try { # Set TLS 1.2 (3072), then TLS 1.1 (768), then TLS 1.0 (192), finally SSL 3.0 (48) # Use integers because the enumeration values for TLS 1.2 and TLS 1.1 won't # exist in .NET 4.0, even though they are addressable if .NET 4.5+ is # installed (.NET 4.5 is an in-place upgrade). # PowerShell Core already has support for TLS 1.2 so we can skip this if running in that. if (-not $IsCoreCLR) { [System.Net.ServicePointManager]::SecurityProtocol = 3072 -bor 768 -bor 192 -bor 48 } } catch { Write-Output 'Unable to set PowerShell to use TLS 1.2 and TLS 1.1 due to old .NET Framework installed. If you see underlying connection closed or trust errors, you may need to upgrade to .NET Framework 4.5+ and PowerShell v3' } [Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null function MD5HashFile([string] $filePath) { if ([string]::IsNullOrEmpty($filePath) -or !(Test-Path $filePath -PathType Leaf)) { return $null } [System.IO.Stream] $file = $null; [System.Security.Cryptography.MD5] $md5 = $null; try { $md5 = [System.Security.Cryptography.MD5]::Create() $file = [System.IO.File]::OpenRead($filePath) return [System.BitConverter]::ToString($md5.ComputeHash($file)) } finally { if ($file -ne $null) { $file.Dispose() } } } function GetProxyEnabledWebClient { $wc = New-Object System.Net.WebClient $proxy = [System.Net.WebRequest]::GetSystemWebProxy() $proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials $wc.Proxy = $proxy return $wc } Write-Host "Preparing to run build script..." if(!$PSScriptRoot){ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent } if(!$Script){ $Script = Join-Path $PSScriptRoot "build.cake" } $TOOLS_DIR = Join-Path $PSScriptRoot "tools" $ADDINS_DIR = Join-Path $TOOLS_DIR "Addins" $MODULES_DIR = Join-Path $TOOLS_DIR "Modules" $NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe" $CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe" $NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" $PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config" $PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum" $ADDINS_PACKAGES_CONFIG = Join-Path $ADDINS_DIR "packages.config" $MODULES_PACKAGES_CONFIG = Join-Path $MODULES_DIR "packages.config" $env:CAKE_PATHS_TOOLS = $TOOLS_DIR $env:CAKE_PATHS_ADDINS = $ADDINS_DIR $env:CAKE_PATHS_MODULES = $MODULES_DIR # Make sure tools folder exists if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { Write-Verbose -Message "Creating tools directory..." New-Item -Path $TOOLS_DIR -Type Directory | Out-Null } # Make sure that packages.config exist. if (!(Test-Path $PACKAGES_CONFIG)) { Write-Verbose -Message "Downloading packages.config..." try { $wc = GetProxyEnabledWebClient $wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch { Throw "Could not download packages.config." } } # Try find NuGet.exe in path if not exists if (!(Test-Path $NUGET_EXE)) { Write-Verbose -Message "Trying to find nuget.exe in PATH..." $existingPaths = $Env:Path -Split ';' | Where-Object { (![string]::IsNullOrEmpty($_)) -and (Test-Path $_ -PathType Container) } $NUGET_EXE_IN_PATH = Get-ChildItem -Path $existingPaths -Filter "nuget.exe" | Select -First 1 if ($NUGET_EXE_IN_PATH -ne $null -and (Test-Path $NUGET_EXE_IN_PATH.FullName)) { Write-Verbose -Message "Found in PATH at $($NUGET_EXE_IN_PATH.FullName)." $NUGET_EXE = $NUGET_EXE_IN_PATH.FullName } } # Try download NuGet.exe if not exists if (!(Test-Path $NUGET_EXE)) { Write-Verbose -Message "Downloading NuGet.exe..." try { $wc = GetProxyEnabledWebClient $wc.DownloadFile($NUGET_URL, $NUGET_EXE) } catch { Throw "Could not download NuGet.exe." } } # These are automatic variables in PowerShell Core, but not in Windows PowerShell 5.x if (-not (Test-Path variable:global:ismacos)) { $IsLinux = $false $IsMacOS = $false } # Save nuget.exe path to environment to be available to child processed $env:NUGET_EXE = $NUGET_EXE $env:NUGET_EXE_INVOCATION = if ($IsLinux -or $IsMacOS) { "mono `"$NUGET_EXE`"" } else { "`"$NUGET_EXE`"" } # Restore tools from NuGet? if(-Not $SkipToolPackageRestore.IsPresent) { Push-Location Set-Location $TOOLS_DIR # Check for changes in packages.config and remove installed tools if true. [string] $md5Hash = MD5HashFile $PACKAGES_CONFIG if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) { Write-Verbose -Message "Missing or changed package.config hash..." Get-ChildItem -Exclude packages.config,nuget.exe,Cake.Bakery | Remove-Item -Recurse -Force } Write-Verbose -Message "Restoring tools from NuGet..." $NuGetOutput = Invoke-Expression "& $env:NUGET_EXE_INVOCATION install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`"" if ($LASTEXITCODE -ne 0) { Throw "An error occurred while restoring NuGet tools." } else { $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII" } Write-Verbose -Message ($NuGetOutput | Out-String) Pop-Location } # Restore addins from NuGet if (Test-Path $ADDINS_PACKAGES_CONFIG) { Push-Location Set-Location $ADDINS_DIR Write-Verbose -Message "Restoring addins from NuGet..." $NuGetOutput = Invoke-Expression "& $env:NUGET_EXE_INVOCATION install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`"" if ($LASTEXITCODE -ne 0) { Throw "An error occurred while restoring NuGet addins." } Write-Verbose -Message ($NuGetOutput | Out-String) Pop-Location } # Restore modules from NuGet if (Test-Path $MODULES_PACKAGES_CONFIG) { Push-Location Set-Location $MODULES_DIR Write-Verbose -Message "Restoring modules from NuGet..." $NuGetOutput = Invoke-Expression "& $env:NUGET_EXE_INVOCATION install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`"" if ($LASTEXITCODE -ne 0) { Throw "An error occurred while restoring NuGet modules." } Write-Verbose -Message ($NuGetOutput | Out-String) Pop-Location } # Make sure that Cake has been installed. if (!(Test-Path $CAKE_EXE)) { Throw "Could not find Cake.exe at $CAKE_EXE" } $CAKE_EXE_INVOCATION = if ($IsLinux -or $IsMacOS) { "mono `"$CAKE_EXE`"" } else { "`"$CAKE_EXE`"" } # Build an array (not a string) of Cake arguments to be joined later $cakeArguments = @() if ($Script) { $cakeArguments += "`"$Script`"" } if ($Target) { $cakeArguments += "--target=`"$Target`"" } if ($Configuration) { $cakeArguments += "--configuration=$Configuration" } if ($Verbosity) { $cakeArguments += "--verbosity=$Verbosity" } if ($ShowDescription) { $cakeArguments += "--showdescription" } if ($DryRun) { $cakeArguments += "--dryrun" } $cakeArguments += $ScriptArgs # Start Cake Write-Host "Running build script..." Invoke-Expression "& $CAKE_EXE_INVOCATION --bootstrap" Invoke-Expression "& $CAKE_EXE_INVOCATION $($cakeArguments -join " ")" exit $LASTEXITCODE libmongocrypt-1.3.0/bindings/cs/Scripts/build.sh000066400000000000000000000052551414105245100216730ustar00rootroot00000000000000#!/usr/bin/env bash # Define varibles SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) source $SCRIPT_DIR/build.config TOOLS_DIR=$SCRIPT_DIR/tools CAKE_EXE=$TOOLS_DIR/dotnet-cake CAKE_PATH=$TOOLS_DIR/.store/cake.tool/$CAKE_VERSION if [ "$CAKE_VERSION" = "" ] || [ "$DOTNET_VERSION" = "" ]; then echo "An error occured while parsing Cake / .NET Core SDK version." exit 1 fi # Make sure the tools folder exist. if [ ! -d "$TOOLS_DIR" ]; then mkdir "$TOOLS_DIR" fi ########################################################################### # INSTALL .NET CORE CLI ########################################################################### export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 export DOTNET_CLI_TELEMETRY_OPTOUT=1 export DOTNET_SYSTEM_NET_HTTP_USESOCKETSHTTPHANDLER=0 export DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX=2 DOTNET_INSTALLED_VERSION=$(dotnet --version 2>&1) if [ "$DOTNET_VERSION" != "$DOTNET_INSTALLED_VERSION" ]; then echo "Installing .NET CLI..." if [ ! -d "$SCRIPT_DIR/.dotnet" ]; then mkdir "$SCRIPT_DIR/.dotnet" fi curl -Lsfo "$SCRIPT_DIR/.dotnet/dotnet-install.sh" https://dot.net/v1/dotnet-install.sh bash "$SCRIPT_DIR/.dotnet/dotnet-install.sh" --channel 1.1 --install-dir .dotnet --no-path bash "$SCRIPT_DIR/.dotnet/dotnet-install.sh" --channel 2.1 --install-dir .dotnet --no-path bash "$SCRIPT_DIR/.dotnet/dotnet-install.sh" --version $DOTNET_VERSION --install-dir .dotnet --no-path export PATH="$SCRIPT_DIR/.dotnet":$PATH export DOTNET_ROOT="$SCRIPT_DIR/.dotnet" fi ########################################################################### # INSTALL CAKE ########################################################################### CAKE_INSTALLED_VERSION=$(dotnet-cake --version 2>&1) if [ "$CAKE_VERSION" != "$CAKE_INSTALLED_VERSION" ]; then if [ ! -f "$CAKE_EXE" ] || [ ! -d "$CAKE_PATH" ]; then if [ -f "$CAKE_EXE" ]; then dotnet tool uninstall --tool-path $TOOLS_DIR Cake.Tool fi echo "Installing Cake $CAKE_VERSION..." dotnet tool install --tool-path $TOOLS_DIR --version $CAKE_VERSION Cake.Tool if [ $? -ne 0 ]; then echo "An error occured while installing Cake." exit 1 fi fi # Make sure that Cake has been installed. if [ ! -f "$CAKE_EXE" ]; then echo "Could not find Cake.exe at '$CAKE_EXE'." exit 1 fi else CAKE_EXE="dotnet-cake" fi ########################################################################### # RUN BUILD SCRIPT ########################################################################### # Start Cake (exec "$CAKE_EXE" build.cake --bootstrap) && (exec "$CAKE_EXE" build.cake "$@") libmongocrypt-1.3.0/bindings/cs/cs.sln000066400000000000000000000124361414105245100177330ustar00rootroot00000000000000 Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26124.0 MinimumVisualStudioVersion = 15.0.26124.0 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MongoDB.Libmongocrypt", "MongoDB.Libmongocrypt\MongoDB.Libmongocrypt.csproj", "{90EA4DBB-69E6-426D-985A-C66D65A2E63A}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MongoDB.Libmongocrypt.Test", "MongoDB.Libmongocrypt.Test\MongoDB.Libmongocrypt.Test.csproj", "{F2D29C5D-DA83-456D-994F-57AB43EA9470}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MongoDB.Libmongocrypt.Example", "MongoDB.Libmongocrypt.Example\MongoDB.Libmongocrypt.Example.csproj", "{536E0590-7287-4D73-A5D7-5B8EFD2945B8}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MongoDB.Libmongocrypt.Test32", "MongoDB.Libmongocrypt.Test32\MongoDB.Libmongocrypt.Test32.csproj", "{EBD0FAFF-4794-4346-9313-A286E278EDA7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {90EA4DBB-69E6-426D-985A-C66D65A2E63A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {90EA4DBB-69E6-426D-985A-C66D65A2E63A}.Debug|Any CPU.Build.0 = Debug|Any CPU {90EA4DBB-69E6-426D-985A-C66D65A2E63A}.Debug|x64.ActiveCfg = Debug|Any CPU {90EA4DBB-69E6-426D-985A-C66D65A2E63A}.Debug|x64.Build.0 = Debug|Any CPU {90EA4DBB-69E6-426D-985A-C66D65A2E63A}.Debug|x86.ActiveCfg = Debug|Any CPU {90EA4DBB-69E6-426D-985A-C66D65A2E63A}.Debug|x86.Build.0 = Debug|Any CPU {90EA4DBB-69E6-426D-985A-C66D65A2E63A}.Release|Any CPU.ActiveCfg = Release|Any CPU {90EA4DBB-69E6-426D-985A-C66D65A2E63A}.Release|Any CPU.Build.0 = Release|Any CPU {90EA4DBB-69E6-426D-985A-C66D65A2E63A}.Release|x64.ActiveCfg = Release|Any CPU {90EA4DBB-69E6-426D-985A-C66D65A2E63A}.Release|x64.Build.0 = Release|Any CPU {90EA4DBB-69E6-426D-985A-C66D65A2E63A}.Release|x86.ActiveCfg = Release|Any CPU {90EA4DBB-69E6-426D-985A-C66D65A2E63A}.Release|x86.Build.0 = Release|Any CPU {F2D29C5D-DA83-456D-994F-57AB43EA9470}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F2D29C5D-DA83-456D-994F-57AB43EA9470}.Debug|Any CPU.Build.0 = Debug|Any CPU {F2D29C5D-DA83-456D-994F-57AB43EA9470}.Debug|x64.ActiveCfg = Debug|Any CPU {F2D29C5D-DA83-456D-994F-57AB43EA9470}.Debug|x64.Build.0 = Debug|Any CPU {F2D29C5D-DA83-456D-994F-57AB43EA9470}.Debug|x86.ActiveCfg = Debug|Any CPU {F2D29C5D-DA83-456D-994F-57AB43EA9470}.Debug|x86.Build.0 = Debug|Any CPU {F2D29C5D-DA83-456D-994F-57AB43EA9470}.Release|Any CPU.ActiveCfg = Release|Any CPU {F2D29C5D-DA83-456D-994F-57AB43EA9470}.Release|Any CPU.Build.0 = Release|Any CPU {F2D29C5D-DA83-456D-994F-57AB43EA9470}.Release|x64.ActiveCfg = Release|Any CPU {F2D29C5D-DA83-456D-994F-57AB43EA9470}.Release|x64.Build.0 = Release|Any CPU {F2D29C5D-DA83-456D-994F-57AB43EA9470}.Release|x86.ActiveCfg = Release|Any CPU {F2D29C5D-DA83-456D-994F-57AB43EA9470}.Release|x86.Build.0 = Release|Any CPU {536E0590-7287-4D73-A5D7-5B8EFD2945B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {536E0590-7287-4D73-A5D7-5B8EFD2945B8}.Debug|Any CPU.Build.0 = Debug|Any CPU {536E0590-7287-4D73-A5D7-5B8EFD2945B8}.Debug|x64.ActiveCfg = Debug|Any CPU {536E0590-7287-4D73-A5D7-5B8EFD2945B8}.Debug|x64.Build.0 = Debug|Any CPU {536E0590-7287-4D73-A5D7-5B8EFD2945B8}.Debug|x86.ActiveCfg = Debug|Any CPU {536E0590-7287-4D73-A5D7-5B8EFD2945B8}.Debug|x86.Build.0 = Debug|Any CPU {536E0590-7287-4D73-A5D7-5B8EFD2945B8}.Release|Any CPU.ActiveCfg = Release|Any CPU {536E0590-7287-4D73-A5D7-5B8EFD2945B8}.Release|Any CPU.Build.0 = Release|Any CPU {536E0590-7287-4D73-A5D7-5B8EFD2945B8}.Release|x64.ActiveCfg = Release|Any CPU {536E0590-7287-4D73-A5D7-5B8EFD2945B8}.Release|x64.Build.0 = Release|Any CPU {536E0590-7287-4D73-A5D7-5B8EFD2945B8}.Release|x86.ActiveCfg = Release|Any CPU {536E0590-7287-4D73-A5D7-5B8EFD2945B8}.Release|x86.Build.0 = Release|Any CPU {EBD0FAFF-4794-4346-9313-A286E278EDA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EBD0FAFF-4794-4346-9313-A286E278EDA7}.Debug|Any CPU.Build.0 = Debug|Any CPU {EBD0FAFF-4794-4346-9313-A286E278EDA7}.Debug|x64.ActiveCfg = Debug|Any CPU {EBD0FAFF-4794-4346-9313-A286E278EDA7}.Debug|x64.Build.0 = Debug|Any CPU {EBD0FAFF-4794-4346-9313-A286E278EDA7}.Debug|x86.ActiveCfg = Debug|Any CPU {EBD0FAFF-4794-4346-9313-A286E278EDA7}.Debug|x86.Build.0 = Debug|Any CPU {EBD0FAFF-4794-4346-9313-A286E278EDA7}.Release|Any CPU.ActiveCfg = Release|Any CPU {EBD0FAFF-4794-4346-9313-A286E278EDA7}.Release|Any CPU.Build.0 = Release|Any CPU {EBD0FAFF-4794-4346-9313-A286E278EDA7}.Release|x64.ActiveCfg = Release|Any CPU {EBD0FAFF-4794-4346-9313-A286E278EDA7}.Release|x64.Build.0 = Release|Any CPU {EBD0FAFF-4794-4346-9313-A286E278EDA7}.Release|x86.ActiveCfg = Release|Any CPU {EBD0FAFF-4794-4346-9313-A286E278EDA7}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C644578D-7C87-4AC7-A3E2-AA124E0911B1} EndGlobalSection EndGlobal libmongocrypt-1.3.0/bindings/java/000077500000000000000000000000001414105245100171165ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/000077500000000000000000000000001414105245100213175ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/.evergreen/000077500000000000000000000000001414105245100233575ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/.evergreen/publish.sh000077500000000000000000000015211414105245100253630ustar00rootroot00000000000000#!/bin/bash # DO NOT ECHO COMMANDS AS THEY CONTAIN SECRETS! set -o errexit # Exit the script with error if any of the commands fail ############################################ # Main Program # ############################################ echo ${RING_FILE_GPG_BASE64} | base64 -d > ${PROJECT_DIRECTORY}/secring.gpg trap "rm ${PROJECT_DIRECTORY}/secring.gpg; exit" EXIT HUP export ORG_GRADLE_PROJECT_nexusUsername=${NEXUS_USERNAME} export ORG_GRADLE_PROJECT_nexusPassword=${NEXUS_PASSWORD} export ORG_GRADLE_PROJECT_signing_keyId=${SIGNING_KEY_ID} export ORG_GRADLE_PROJECT_signing_password=${SIGNING_PASSWORD} export ORG_GRADLE_PROJECT_signing_secretKeyRingFile=${PROJECT_DIRECTORY}/secring.gpg echo "Publishing snapshot with jdk8" export JAVA_HOME="/opt/java/jdk8" ./gradlew -version ./gradlew publishSnapshots libmongocrypt-1.3.0/bindings/java/mongocrypt/.evergreen/test.sh000077500000000000000000000007351414105245100247020ustar00rootroot00000000000000#!/bin/bash # Test the Java bindings for libmongocrypt set -o xtrace # Write all commands first to stderr set -o errexit # Exit the script with error if any of the commands fail export JAVA_HOME="/opt/java/jdk8" if [ "Windows_NT" = "$OS" ]; then export JAVA_HOME=/cygdrive/c/java/jdk8 else export JAVA_HOME=/opt/java/jdk8 fi ./gradlew -version ./gradlew clean check --info -Djna.debug_load=true -Djna.library.path=${PROJECT_DIRECTORY}/install/libmongocrypt/lib/ libmongocrypt-1.3.0/bindings/java/mongocrypt/.gitignore000066400000000000000000000004671414105245100233160ustar00rootroot00000000000000*~ .#* .git *# # os x stuff *Thumbs.db* *.DS_Store # Build artifacts build out # Eclipse files .classpath .project .settings # Intellij IDEA files *.ipr *.iws *.iml *.idea workspace.xml atlassian-ide-plugin.xml # gradle .gradle # local settings **/gradle.properties local.properties # jenv .java-version libmongocrypt-1.3.0/bindings/java/mongocrypt/README.md000066400000000000000000000033561414105245100226050ustar00rootroot00000000000000# mongocrypt Java Wrapper # The Java wrapper for the companion C library for client side encryption in drivers. ### Testing ### `./gradlew clean check` runs the java test suite. By default it expects that libmongocrypt has been built and is in the `../../../cmake-build-nocrypto` directory. Note: libmongocrypt and the java library are [continuously built on evergreen](https://evergreen.mongodb.com/waterfall/libmongocrypt). Submit patch builds to this evergreen project when making changes to test on supported platforms. ### Publishing #### First check the build artifacts locally (~/.m2/repository/org/mongodb/mongocrypt): `./gradlew clean downloadJnaLibs publishToMavenLocal` **Snapshots** `./gradlew publishSnapshots` Will push the latest snapshot version to the sonatype snapshot repository. **Releases** `./gradlew publishArchives` Will push the latest version to maven central repository. Note: Has to be run on a git tagged version / hash. ### Custom gradle flags ### * `jnaLibsPath`: Custom local JNA library path for inclusion into the build (rather than downloading from s3)
Usage: `./gradlew publishSnapshots -DjnaLibsPath=./build/jnaLibs/` * `gitRevision`: Sets the Git Revision to download the built resources for from s3.
Usage: `./gradlew publishSnapshots -DgitRevision=` These flags can be combined with the `downloadJnaLibs` task: * Test without compiling libmongocrypt locally:
`./gradlew clean downloadJnaLibs test -DgitRevision=` * Test using a custom libmongocrypt path:
`./gradlew clean test -DjnaLibsPath=` ### Debugging errors ### * Use the info and jna debug flags to output debugging information when running tasks:
`./gradlew --info -Djna.debug_load=true` libmongocrypt-1.3.0/bindings/java/mongocrypt/build.gradle.kts000066400000000000000000000255071414105245100244070ustar00rootroot00000000000000/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import de.undercouch.gradle.tasks.download.Download import groovy.util.Node import groovy.util.NodeList import java.io.ByteArrayOutputStream import java.net.URI buildscript { repositories { jcenter() mavenCentral() } dependencies { "classpath"(group = "net.java.dev.jna", name = "jna", version = "4.5.2") } } plugins { `java-library` `maven-publish` signing id("de.undercouch.download").version("3.4.3") id("biz.aQute.bnd.builder").version("4.3.1") } repositories { google() jcenter() } group = "org.mongodb" version = "1.3.0" description = "MongoDB client-side crypto support" java { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } val bsonRangeVersion = "[3.10,5.0)" dependencies { api("org.mongodb:bson:$bsonRangeVersion") api("net.java.dev.jna:jna:5.6.0") implementation("org.slf4j:slf4j-api:1.7.6") // Tests testImplementation("junit:junit:4.12") testRuntime("ch.qos.logback:logback-classic:1.1.1") } /* * Git version information */ val gitVersion: String by lazy { val describeStdOut = ByteArrayOutputStream() exec { commandLine = listOf("git", "describe", "--tags", "--always", "--dirty") standardOutput = describeStdOut } val gv: String = describeStdOut.toString().trim() gv.subSequence(gv.toCharArray().indexOfFirst { it.isDigit() }, gv.length).toString() } val gitHash: String by lazy { val describeStdOut = ByteArrayOutputStream() exec { commandLine = listOf("git", "rev-parse", "HEAD") standardOutput = describeStdOut } describeStdOut.toString().trim() } /* * Jna copy or download resources */ val jnaLibsPath: String = System.getProperty("jnaLibsPath", "") val jnaResources: String = System.getProperty("jna.libary.path", jnaLibsPath) val jnaDownloadsDir = "$buildDir/jnaLibsDownloads/" val jnaResourcesBuildDir = "$buildDir/jnaLibs/" // Copy resources to jnaResourcesBuildDir val copyResources by tasks.register("copyResources") { val cmakeBuildPath = "../../../cmake-build-nocrypto" destinationDir = file(jnaResourcesBuildDir) if (jnaResources.isNotEmpty()) { from(jnaResources) include("**/libmongocrypt.so", "**/libmongocrypt.dylib", "**/mongocrypt.dll") } else if (file(cmakeBuildPath).exists()){ val jnaMapping = mapOf( "libmongocrypt.so" to "linux-" + com.sun.jna.Platform.ARCH, "mongocrypt.dll" to "win32-" + com.sun.jna.Platform.ARCH, "libmongocrypt.dylib" to "darwin") val copySpecs = jnaMapping.mapTo(mutableListOf(), { copySpec { from(cmakeBuildPath) include(it.key) into(it.value) } }).toTypedArray() with(*copySpecs) } } // Download jnaLibs that match the git to jnaResourcesBuildDir val downloadJnaLibs by tasks.register("downloadJnaLibs") val revision: String = System.getProperty("gitRevision", if (gitVersion == version) gitVersion else gitHash) data class LibMongoCryptS3Data(val evergreenName: String, val osArch: String) { fun downloadUrl(): String { return "https://s3.amazonaws.com/mciuploads/libmongocrypt/$evergreenName/master/$revision/libmongocrypt.tar.gz" } } // If updating this list remember to also update the Publish Snapshots `depends_on` in the main evergreen config.yml val jnaMappingList: List = listOf( LibMongoCryptS3Data("rhel-62-64-bit", "linux-x86-64"), LibMongoCryptS3Data("rhel-67-s390x", "linux-s390x"), LibMongoCryptS3Data("ubuntu1604-arm64", "linux-aarch64"), LibMongoCryptS3Data("windows-test", "win32-x86-64"), LibMongoCryptS3Data("macos", "darwin") ) jnaMappingList.forEach { tasks { val download by register("download-${it.osArch}") { src(it.downloadUrl()) dest("${jnaDownloadsDir}zips/${it.osArch}.tgz") overwrite(true) } val unzip by register("unzip-${it.osArch}") { from(tarTree(resources.gzip("${jnaDownloadsDir}zips/${it.osArch}.tgz"))) include("nocrypto/**/libmongocrypt.so", "nocrypto/**/libmongocrypt.dylib", "nocrypto/**/mongocrypt.dll") eachFile { path = name } into("$jnaDownloadsDir${it.evergreenName}/${it.osArch}") } unzip.dependsOn(download) val addDefaultLibToMainPackage by register("default-${it.osArch}") { from("$jnaDownloadsDir${it.evergreenName}/") into(jnaResourcesBuildDir) } addDefaultLibToMainPackage.dependsOn(unzip) downloadJnaLibs.dependsOn(addDefaultLibToMainPackage) } } tasks.withType { description = """$description | System properties: | ================= | | jnaLibsPath : Custom local JNA library path for inclusion into the build (rather than downloading from s3) | gitRevision : Optional Git Revision to download the built resources for from s3. """.trimMargin() } tasks.withType { sourceSets["main"].resources.srcDirs("resources", jnaResourcesBuildDir) } tasks.withType { dependsOn(copyResources) sourceSets["main"].resources.srcDirs("resources", jnaResourcesBuildDir) } tasks.withType { @Suppress("UNCHECKED_CAST") systemProperties((System.getProperties().toMap() as Map).filter { it.key.startsWith("jna.") }) dependsOn(copyResources) sourceSets["test"].resources.srcDirs("resources", jnaResourcesBuildDir) } /* * Publishing */ tasks.register("sourcesJar") { description = "Create the sources jar" from(sourceSets.main.get().allJava) archiveClassifier.set("sources") } tasks.register("javadocJar") { description = "Create the Javadoc jar" from(tasks.javadoc) archiveClassifier.set("javadoc") } tasks.jar { manifest { attributes( "-exportcontents" to "com.mongodb.crypt.capi.*;-noimport:=true", "Automatic-Module-Name" to "com.mongodb.crypt.capi", "Import-Package" to """org.bson.*;version="$bsonRangeVersion"""", "Build-Version" to gitVersion, "Bundle-Version" to gitVersion, "Bundle-Name" to "MongoCrypt", "Bundle-SymbolicName" to "com.mongodb.crypt.capi", "Private-Package" to "" ) } } publishing { publications { create("mavenJava") { artifactId = "mongodb-crypt" from(components["java"]) artifact(tasks["sourcesJar"]) artifact(tasks["javadocJar"]) pom { name.set("MongoCrypt") description.set(project.description) url.set("http://www.mongodb.org") licenses { license { name.set("The Apache License, Version 2.0") url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") } } developers { developer { id.set("Various") organization.set("MongoDB") } } scm { url.set("https://github.com/mongodb/libmongocrypt") connection.set("scm:https://github.com/mongodb/libmongocrypt") developerConnection.set("scm:git@github.com:mongodb/libmongocrypt") } } } } repositories { maven { val snapshotsRepoUrl = URI("https://oss.sonatype.org/content/repositories/snapshots/") val releasesRepoUrl = URI("https://oss.sonatype.org/service/local/staging/deploy/maven2/") url = if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl credentials { val nexusUsername: String? by project val nexusPassword: String? by project username = nexusUsername ?: "" password = nexusPassword ?: "" } } } } signing { sign(publishing.publications["mavenJava"]) } tasks.javadoc { if (JavaVersion.current().isJava9Compatible) { (options as StandardJavadocDocletOptions).addBooleanOption("html5", true) } } tasks.register("publishSnapshots") { group = "publishing" description = "Publishes snapshots to Sonatype" if (version.toString().endsWith("-SNAPSHOT")) { dependsOn(downloadJnaLibs) dependsOn(tasks.withType()) } } tasks.register("publishArchives") { group = "publishing" description = "Publishes a release and uploads to Sonatype / Maven Central" doFirst { if (gitVersion != version) { val cause = """ | Version mismatch: | ================= | | $version != $gitVersion | | The project version does not match the git tag. |""".trimMargin() throw GradleException(cause) } else { println("Publishing: ${project.name} : $gitVersion") } } if (gitVersion == version) { dependsOn(tasks.withType()) } } /* For security we allow the signing-related project properties to be passed in as environment variables, which Gradle enables if they are prefixed with "ORG_GRADLE_PROJECT_". But since environment variables can not contain the '.' character and the signing-related properties contain '.', here we map signing-related project properties with '_' to ones with '.' that are expected by the signing plugin. */ gradle.taskGraph.whenReady { if (allTasks.any { it is Sign }) { val signing_keyId: String? by project val signing_secretKeyRingFile: String? by project val signing_password: String? by project allprojects { signing_keyId?.let { extra["signing.keyId"] = it } signing_secretKeyRingFile?.let { extra["signing.secretKeyRingFile"] = it } signing_password?.let { extra["signing.password"] = it } } } } libmongocrypt-1.3.0/bindings/java/mongocrypt/gradle/000077500000000000000000000000001414105245100225555ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/gradle/wrapper/000077500000000000000000000000001414105245100242355ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/gradle/wrapper/gradle-wrapper.jar000066400000000000000000001536261414105245100276640ustar00rootroot00000000000000PK A META-INF/PK Am±>=@?META-INF/MANIFEST.MFóMÌËLK-.Ñ K-*ÎÌϳR0Ô3àåòÌ-ÈIÍMÍ+I, ê†d–ä¤Z)¸%¦ä¤*„%¤ñrñrPK Aorg/PK A org/gradle/PK Aorg/gradle/wrapper/PK AªÙfØê -org/gradle/wrapper/BootstrapMainStarter.classV[WWþŽ™d`c@ƒŠƒ7.‰µÖV°´J½ -lDÛÉ!ŒNfÒÉÄKï{ý¾ö¥O]«} ´®ÚÕ×þ‹þ‹>i÷™É@‚«,Ö™3ûìÛ÷í}öäïg¿?p ?(ˆâ‚‚LÊxKÆE½¸¤à2®(˜ÂU±L+!£`³b¹ÖëBòvæddeŒ(輌g±(ãÆNÄðŽŒ\n wKb¹%–ÛxWÁ{x_†Þe±Í+8„‚ Î9gX†;ÁJ$¤I»@Ò®ŒañÙji™;óú²I’hÆÎëæ¢îâ½.”ÜU£ÂÌØN1]tô‚ÉÓ÷½\æNú‚m»—^ftÃʺºãrgœ!\[†c‰¥Ìýžž6u«˜ÎºŽaÇ}‰a§/&÷òÑ"EØÛF™AñC^±K”Ëîfc†NÿôªîPöyÛrùwÒÔ+•Œ­8 ã¾…ÅÝôÂ\¦áH—(kOݧ!¶'¡Åù wWíC_ƒ‚ÃWLžwÓþiö6÷°ku{nh‚ôwWù»3zÙS“±BÁ.>Èó²kØVEF‘ª³bX…Œ^µò«Üñðõ'Z¨k%CZ1„³Ur–µ«Nž 9QЮJ)a«âŽª8‡×ömÃÚx¢ÂÀwU˜(ɰTØ(«ø@,GàȨ¨pQUq÷)eê™”_¢”YÇ’ºì½‹\T<ÀCÊ[ðLˆ[¨Rñ!>bèÞ_[¾C´«øŸPÅô“¦]á‚GŸâhoêyÓX¹}¦âs|¡âK|Ehý¤Fƒ¤FSC·ˆÊÿ‘Нñ Õ{3ì\Õrß(ÃÅI»j4Ëv5“*ïrÍ]åšL |jWÏÏi†ˆ ÕÀX® ÚàñÊ`JÅ·øN¤ö=Ãàÿ¼] û·ëCºA›G Év-µ6Jص榈ÚD²ñzL7{ª®™Ù¢™!Íž–rí+r7û°âòRóE <´Zx·˜»×u‡[43’ÁÌ"mc%GCk̯:\' v嫎p¼ÇšÂúR‘|…»“mÆE_âá:MÚ×çÅñÄÖaµ`ZPž7ÛØ,m±I¾hÐD ëž}—ºúl£/ÿ^4ùª‹’[ETÔ¼¸1 G[JDjj\q.¦d"¹¥™dB8«‹éÜÌõÆïn•‘MIwéŠÇžv<Þ$ +¶CJ-@ÛÖèFä¶Îé“<@ßfñ#Öcô–¦'£gxh ìWÚìÀqZ#žp?NЪú D‚žÔ­"-2f¤'“Œ¬aÇì„rÒr¡ÑÂ5D²ëkèXC瘴%.Õ°3.EÕv…ãáènÒîÊ…¢ÝÙöŒEâF‚h.4Lï{oÄ¥¿{,Ì~CƒHNò’;NZû(øÂqÃôÑ?~\Âa,@ÃmÂZ ‘ü?Ázòb7ŒÇ(R$B¿Ò´ ‘ÅœÄKå4­§ð2>OãÒ:S§Â?{•Î^#I?Øs &ËÑ-£×ûÉè’é÷ 0æeÍ0N‘è›SgýgÊ*BÏé'èÍ G÷­a ñ™‘§¡3RtèGé‘N ’j苨áàcDâá_Iì§çÿ<Á¡\´?àj‡× ýé•VÐÓK© ’4=J°OÒþ Áth¤£¡XhMo3íÑÁNŒiL’Æ9ž&Z7 MÓïÛ–P6î¹(  Kü›8æ2À$‹6V]šîSä¡G …ÿ»L†ì‰±S‰™‘M3dzĈÇõ`³ÛÒb—aÂÌEIBê.ò_€hÆõRþlˆáÉà?R3§cdBËrƒ«5¥8™Húùí2CnH‰í²™ðôˆ61O¯Æ…ù°Ì A/€N­4Œ­ÀúJ ú÷‚q f>=<\¥5‰,r}ò+Šš\îï¼ä!ƼqÏ>Dê.Àùr"ç Ø'ÙOtþLûÒ¹#i¦1Õ—~J«Õ÷ņûÊú¾Ìî:¦{´=ü ®ôJ[Ôz—áàšeRPK A5¶<›Àœ!org/gradle/wrapper/Download.classY |\ÇYÿÒî¾§ÕÓáõ¹¾²NìXÖi;ŽˉK¾dË’¬•äÊv∠~'ˆßÅïñ ~_5 xþP5Äü±/ø“ –ãOƒáÏ‚x_TÓ_RÍŸ›ø‹ Þ¿TÍ_ø²úþuÏáo‚ø[|E5WEioâ‚øGü“6ñz›ñ/~¨õ€‰¯ñ¯ø·jü;þ#ˆgñŸ&þKQþ[íô5Eùš¯+}þG5ÿ«šÿSÍ7Tó†j¾©šo)nšB³úEL©0¥Ò_ûñYSüüJ€,b¨žI7IU]4¥:ˆkb™RcH­"Õ™RoÊ2O ÊrYaÊJµë*CV²Æ”°)k YgÊú †dƒ)M¹Eí¡&²É”[M¹Í”ͦl1åvS¶šÒ 6ØfH£!M«+‘pÜθJ9)A¨ÏM^ž9ö&„µ½¤+¨ì9ÞÓ{ªçÜСþhWoÙºÏÛí¶¸˜h‹zn,1±OPÓ™L¤<;á Ùñ´cJ³ ¶¯¿÷Hÿ¡hô\çQn"®JåkAuÇàáÇúÏE»NªH Ä“å­ëNºm®=wÚ.¹öô´ã¶uëIŠ18î±§ú—½!ÇMÅ’ Aý´›œpTª;–òœ„Ú§¥Ü>“—ñ¤=Ö·€;îŽ%bÞ~AGÃ,6}1eÛÀ×™£’uݱ„Ó“žqÜ{$î(ç%GíøíÆÔ8Gôy“1úÃR*SÅä’š}7æ¾Y3Ö&㱉´ë,L íöÊÅTõìÑ 'ìéœ5æXN¬à–†ì¾ ÇkìïÊI‰%ÛÇ⎖`ØccJ5¦K)+³dÌIy±DNVméZ&À¡Ë£Î´šäâú¼Ì®„ç¸ ;NåÒn|Á®Ý\V›N9î '—© üHz|\eLÅ™ê“HOõ;J÷ÚNoyÝNb›d,ó9Ö™L+!Ìçcä"ÞÍWù¸ŠÚ®)ËÚH8£JU*P™L{‚UszÓÞtÚ£Ó{ŠÓ1._Y˜íJÌOÒbH«!m†l7d‡!;©oÊwݘ`ã_o[èO:$fÈ”MŸwØ©ØèÂxn+®ÅF¨ÀG c†\9µ+1ž$¦ŒØ)g÷®C‰Q]·7”ɬrR?áxÙEî Ç›LÒ—k‹ø\g#ø ’÷2fØ>ÌÑ üðñ[ÕØ$Í-³õ6hÆ ¶›`âV¼•½Æ,#¾oÓ?ëUiA¢{JT…î)a•ZÄ£9ïäŒú!pcã,*›®¡²±å|aß5ø›¯!À c^îF l¦´-ÜïvÔb+V ŽØ† ÔBé²+»cA—]6j3+tÏÓº¨žÒÊG*Q9­zµ–ÀŠyU7P;‡à°Ì¢ú:,¥K¥Ö¥V¯o¡Z±Ûµl+».'ûíšW–“øxEd½Z©Ö5gP“Aí©Æ¦æYÔÍÛ˜Ý÷ý;õ¾‘ì’‚Mu¸‚Ô²êðCÚ‹?̾”(ûïÊ «Ü„€þÙ¯†£vÓuÔg°¬=0‡Ðð–SðŠY¬ì 2XÕîkl ûf±š._Ón„}¡pØÈ`mØ—Áºvÿ²|Êl7ÕhÃî`Õžêª=5aØÌ`ãðç1u·dy +?†M¡[3¸m›‡C[fqûË«jVV]±÷Ô¬ªÖßêUÕ+°uªê=Ï¡©ñ¨ mË ñ”&:{ªI Ü@H}šV¯¬ªù$šh ›•+«2h~áæ»õš– ZÃþ0Ãþ ÚZn ‘”í/à¶öºòó†š×½ü¢NºÏãuºìu|U³!}/Ó ØËù}万îßϹ—ÔûÐŒ؉Ît²=ˆ.FŽÐáG1ÄÑޱúŽ3º™Þ= K/ž ÇÓ8‰¢%çÇ1€WqвOã 8ƒ/á,¾Œðœ£§ñuÒÞÀY< ~œ“*ØbaD§ÀR›Z¼‚wãGÔx3q J¾Â¹'˜.²ÖŒU”ú6ü8{AÊ|?ŸD5u¼Œ÷°WCk^ÃOÑVŸJŒ|J±—K)ö²)U!ÕxïC¥¨´Î®ð‹‰§h“_'÷«¨ºÉk ¬7°ÃÀ3ž5ð~ÏxÞ@¿åÜd.Å%šëè¸IM‹ Q7iMÉ ] |à& ®~ÑLþØÜ¤=e÷-*Sý¸‘«Òãô¢*¯MsØ1ܘÁNasÿvñïNþíæßžYÜuµP·½àBlÂÏÒ¥ó">HÎáÃ9¿˜ƒ×ýM³ØÛÓò|/†Ú›(+ƒ}OÃÒI|7“¸9tÏöÏâÞÐ}h$wð›A'«s²Ø˜¤ÓtÕCtd «‰s¢Þ=ĽyœÞ_À‘ýÙ`: wáç46¾]cvŨfŒVŒØL&¾ï³P)q pæqºã`‡N4‡gp$t´òÓèÊàXOsè¸wû8® ˆ’ØîkÎ÷dÐÛîûÂ~Nö W6…ú28I†ÞWЕ+ÔÊÁÒ•aŸ”ãn÷Íah8tJØ[^¦Š&‹à$ƒÚOKå7ë£Fz´ÙdНa’·Ò¬½ÄË“,«~Ô$KéQÓc,$寳ôÀrüË·’Ü·1j¥ö’úKøeFp’>ÎÒcÔ¯âEöú cOaöã_?®ýÊ+埠ŽÊÃM¨¸Iñ•:7Y ×TJGoò\ñH$h*—d0›;¤žæHsGh˜‡Ô‰Ði¶=Í7p ‘n]._xĨoÏàLK6_®2»Î^-dÌ*}R¾—|’º¿eôaLÙQÐ~‡Îe^a¨ñu}¢[’O2¥òM4k}û9ùærz~‘BTbÞºŸv‡ÐÚžSÚ†dÛî Ùêã¨O 4Zoê3ÿ}Ña?þè0Ó$:³g„Ña³):\hfc´D¯cl¾ ³Uð<õüÔ¯•!–t˜ºGX}[Y}ʶ£Y…r¶ÈŸÒ‘±ˆOkÛB€ÏhÛ„ú—õ !Â*z…=?÷Ù_a/@ÎWµä_Å„¾FU`\ÿ_MêÿEN"ømPK AyL¢¡Ê1org/gradle/wrapper/DownloadProgressListener.classuÁ ‚@Eï+ÓjDËöEÐ@Û–EERûI¦ˆ#3cþ[‹> Š4Úv‡»9œ×ûñ°ÂÀƒç¡O˜Äª.r%ãÐJ[™ÍM Ç„ñ,Èä]Š‚­8Ÿökߟ_ÃPU:â]š3aºý©G­ÍÆ©±\°^¶&a¡t"-ãœE­eY²ÿÂè›Ë›¼8\3ެK tÐŽBNûÐkØûPK A!9|¶„ 3org/gradle/wrapper/ExclusiveFileAccessManager.class•WÛsWÿYÒÚ«u|iªVÍMNZ*;±•JŠlB×NåKœÆŽ[—t-دvÅjÇÜSšB[(·¶ÐP`x¡ 3íL«$x†ô©Ì0à }á…0¿³+9¾%L=öÙs¾óÝ¿ß÷íúOÿýýÁ¯t<ŠgZ ãYµÌjxNG_ÔpNGϨ×Ô Íx^mMEœSKA-EµH ›1¯¶ ::`éÔvIÃb3lIÅžDIGŽºqu”ñåfxJ_¥~O¡ªc—u,áJ ê§íÄñ–ñ _Õð5öñÉ¡± #ùñá SgGFòÏ tŽ_2/›YÛtæ³S¾g9óý­C®SñMÇŸ1íªhñ­’t«þDE@äv”]ÛÎ;¾ô.›¶"Æ,Çò Ä2ù|÷Œ@tÈ-R°mÜrä©jiNzÓæœ-•=·`Ú3¦g©sõ,jÉŽ»Þ|vÞ3‹¶Ì.yf¹,½ìð•‚]­X—åˆeËÁBAV*¦cÎKŽÆÍ€ 0˜ ã°Ü¬âëOUß²³×)T=O:~vÈ´me±¿{]Ô“s—dÁWÊ䕲å-3ÄQºd»…EÝ!£C½…Óq¤] 0ŠE•(¹Þ;&f£*2³B5ûþ?ÍÊ^¨¤£±}Òò虫\j÷L§è–ÂøC¶‡ÖlÙtGuZÝÛ5Ó[" äMn,Ér¹Q–‡ïíõÀôtÿ1•„)ß,,N˜å@LÃ×5|CÃ75|K@gùdÙ·ˆ'ÂhÊšwL¿êQ÷ÄÀtnkŽ}¢2†ts¥óÒŸ&J',ÛVXjÊt³Š%syNÙnE>]µ¤o3•É;6‚‹ÄlK¡q¸oF3åV½B½ÖûîŽÌ>%l W Ä!½8$`¬ÍÀ ø¶À›»ïDÕ²‹Ò3ð"®x ßèýD]AÌõÙ…EßU úð²Wðªï©åûx•À¹cóLÕQ­½V$ÃCnÕ.¦×O#€&¤A7zxŠ N5@¸ïT3„Ï(ïúåz˜§Yò4©}Ï ˆž] Ò³û4½?ˆE¹vqÝÀ<Ì ŠáÓøLø¥˜ÁNŠpÿ8>K.š‰ü1´â‰DgÖ[A|ö4n›khéLp©Á¸ÖS½¼ÍESÑv\ÇcêÙöêÙ~]+蘭ËvvRˆÜ÷5dwÞ¹˜ÈÅÊý=ï#rÍ<ª‰\KªåT´¤öúÛ8º‚äloç7ð`.–ŠÕÊÅSñ WÿšŠßÄ®TŒ U4]»‰Ýï¬~¨Tô®7½‡6•‰övîãþà7ÝBZ §§Hè Ò«@'¼c ¥¿›KlÏ“¸3Ö1·™ÿ¿ãcÑÆ¶‰õDQDDwp>¨žäPõzp}”ÕÊ@8B gmγ*& _$W™Ô ëö+ôkôŽrÖ}¿F¿A?~‹Ô(µ‚AZÆÇ8‰ðÃñŸü:üưŠqÁ¤Ð8­ Ó›“"‰¼Ø…Q±câï?… z5)“çqj…™sDP·hí hô F›9Òˆ‹ޏë§uì>cÄÑ~êþiMȈvz5ÀHMü¾ ªŠø †ð$?b‡)n¬IŽPò$)SÐþƒã¢üݳŠhÑ ǧB¢†¤†<£À¿q¢ÏÒ0¶Ê.Ò¶åƒÃx½dÐ(§øÇWW½§Žw@óMì߉¥ß­5S< Ÿ ’a„<õÀuõ.«ËŸç3ôäGhí¹…GÞAtü=’£dl¥Ù¦@]± …ùßéçysŽýùü:õmŒšO• ‘ ²¼8x4ó?PK Aì„,y†-org/gradle/wrapper/GradleUserHomeLookup.classSÛNÛ@= $vŒÔ”K J)$´ÄÚÒ E¢`@"\”@¤Õ-Þsc-ÂÄg¥ØOˆN™QMž} (1ŠáìÁ#Šj€ RŽ`뛿Í€i­õm¹õßP/ÊQ«ðWM:‡Ü‰â;"¢¬+) Q¤g ™ÊŽ°Ñ°?ѹZ>f\´Âz\P$ȦaX­aò–Œif\çÇšl=C‘pC‹j±aaì!›‡@¥!#v–@bÃŽü ½çâ–=”•Ð2½²1f…?‘¶œá¬}d¯ŒçÁÒEŽ} +i˜¡ ;¬~*ÛaDigIÄÊÞä… ½È}iJÛ„JXù׺ñär ··M„tÇŸep´áá|7HXÈ HîLÄVq$9JWç±×å‡sQZ¡l•6o„Y)tËdDL·ú{:¹&QΪb﹘¥MdìUÖki¡Óµ1;¡e|NÂÖÀÜ!+Ðã¶ymš->J¯‘0Cº“»K Šg³È»@´㱈¡ «èÆ!Gaª8ƒ1waŒ}c®”Wñy|Îͯ8&È|ªš~&k¥Ã¶)AÀM£ ±Š/âK2¾¬â+ø*yÎH(>“ë–„mÿGM©ø¾®âø¦Œo©ø6¾Ã™©->Ê ªø.¾'ãû*~€ª8‰s*¢ˆ©ÁãeüHÅñ +\Ìê½6aå: ãTy‹pèOs=8ÍH³F›ãq=ʬ1ßÏÄðs µ.Ìû؈â'Â_L8Ç _à—Ôì<¢IÎÎÍ3½LÀþJƯUü¿Uñ;Üßㆊ?àkÿNæ…¹VBYΖ?âObߟeüEÅ_ñ7WñüSÆ¿TüËøŠGð_æÓ,åAOÍäDO"f…£zf‘øÔ^’„ž“T^•HEö¶h±˜aÕ ë42ÊÖ„"Z<>FÕœ4Ìš´OjØÄkNšF´&Äóæ„×kj×Åk7çäa÷‰SzÈR%T,Ä•¨’Œ²äU¥RIa‚Ie²¤ªÒBA,áfSó?j ˆ ¶¯ü,KÕl?ˆ‰ãý±Ó1ÖV÷t/_¨›ÏRb¤Awºs³@tO·¥Yж; ^6ªÅ›Í‘DTYs©–ÁgÛÉðHÂd®­+hY…ƈ¾]lŸžóµÆõxËÚf×:ûîˆne·öåÓ­½ðÀ“Ó籄}óh²Y(lMuys ‹ÝĈ;BÂj Àȇ ÖÌ}RÒæ÷@þ©åÔõö‚ãn^Go®ÁyGFa0ÜïT‹òe“v÷¬Ànýqúq]Í醶Y·­ éCniã*ÂiÁ®knÔ–s‹ëµ#ßõ.ù§N3("®QUL͹ï7…‰e§´f²˜—fæLºéôνÑÊdéÒÄ}H5õ±ˆ&Ž3Nþ]yE× ³v~[镊j‹èÑŽé4Úb×e¿h5œÛúšiåã ©¶Î5äóPlõìŽ{ÄÛ¹æðYR€:³J¼å¶ÆÎG¤`æÚ—¹:Í;Ø”Û̃l`–a7õ"\©í7úœ­5sˆ¬Ÿ'/çT<ýzu»µç*UFÚõI7LÂsCq×JS=~OÞ¿§ø*J‹|e½ƒŸÚ›ÄÂ$ÊgÈ‚\)ÈSXľÆb±Ø[å÷Ô'±¸±dKe¿LjÉ–’eYË“ðû¹²¢Ñë÷nšÄMb²²±tã$V5*~¥~ ÕƒþÒ)H}«}5)Ü<…5ƒ~o ·¤°v ë´>‰Ú³ÀÇq=½\KC(G=–aVa#¶c:è¯ÃØ‚Ça+Ž“¢c&°÷`7îEÎãV\`œ®aŸíº1Ç=ä´c7ÅÇÈÝYŠ$îä×J¸ÌgÉŠ(çAÜcä:ŒÑ5ºü8ç'b8tîæ(SÖí¼Ù 1Žç±ùQ¢] naœb8NÛr$DøÍ›~:Ê!b-ào-9…À`½¯.…úIl Ó¤ Y¤‡”S1  UØO·´ÛF-u `P Ø_wÙF)â}•¸#VeŒßFçߥ¼ä:•\e¶_@ˆ3ˆæ4ß2[á$6ño³¯Á·%‰Ç¤°5®+ nYŽo¿4ܺNèÝéS’Ø–Äö$v$ñØ;ÀÂàv nHa÷uŠhô5%±ç~,Dß­ž«Ø;XTß;‰ÛR¸ýzZ—æö]²EU0cvÒIB‘jŠË¤‚âc±T±TV2öFÿV*$¬!oÿâ°8«bì8K¤•Œ CçßBõÈØù0JeLÔоÜÒv Úᥰz_Y-±Ø ('­I´ Å&±_x§(+‚Ç(è8V0™f¼Tm§–#°Ò Šá³0-fWZLùÚ‰^AQ)tä;ýd\yNÂl®'þPK AúâæªÛ"org/gradle/wrapper/IDownload.classEÁ Â0 †ÿÌéæ¼ ^õbÁë®* AÑ{ÝÊØ(í¨Óùl|JìTf $_òçÏóuX ï¡ë! ø‰®”ÔêóÎìn6›mlýaßó{<ïû}¾ßwöµ¿ð"€MxkC6Ge““ͤlLÙ‹a3¦X1¨˜V`ÇÔœ8r”WñÙ»r¥ O6EÙ!ƒ1œÄ)÷ʕʕ©ø¸TùD ÷á“råSÍø4>#î—ÓÏ6ã0>׌q|^6_PñE¹ü¥¾Œ¯Äp§t–ÁWe󀂯©øºŠU|CÅ7cèķ䯷¥µïÄx€‡<¬`FÁ#­Çuk­ådtkÜÌï7-CàŠô1ý¸ž2”œïh–2Y³àõ™®À••™kN=Ó±G\«ªd^jd¨ŸJ+¤XÆ±š¹¢«K9δãæR9WÏZFê„«çó†› úÞZQêÇëÝ Oê›¶l.N ´Î,ÝÎ¥†)`ç¨õ&ÍÂÚ «yé· žnYRn§i›ÞnûK .¼„F³ÊY/ùP‹QwŽ „{,o}yÚ´Áâô„áÒ'dÚÒ2,£ºkÊyy1,O) õÛ6Í[z¡`pzí'Y»‘‡Ó£Ôšè¬nÌ›ÎWCÊÊ ŽVVåúì;™1òå°Ä¦uwÊpñÛ0²…>ç„m9z–Šã¤GA?jôÕÓCóœ|Ú8nX¤ñ¶Ö¹o¥Ò”•]ÇñÚúT¾rðŽ:• ²›&Z†==35 ç}*xLÁã]=AAÁWU®ÁʼncFFBX6lælÝ+ºt·w±@ ò:St]ÃöR½¼X鮞ذSt3FpWZ9ÝRŒáÞgg,§@ Þ¤“Uð¤†ïâ{vã [°UÃ6Ù¼Û5ô`‡†Ø¥a¾O[µ®4üýWדëÖ¢ie WÃñ# Oá4ÃÛíLixZÎ÷àÇ~‚ŸjxF6?“k?dz ÎhxÏ Dºóºëiø…Ü>‹Yz­šÆ;¤Å’‚sæp^à ¸ à—~…5¼„—5ü¿Ñð ~«áwÒ«¸›Üè3,Óêä¯ÔqOÑÐïñÔðþ¤áuüYÃ_ðW 7 ™Óë­l‡íxEû^3ßAætx;Ñ- zÁ±{hõ y¢7ñ7 —þo“w´z©,¡íú ¬Y2æ•H”+«àBŽ2‡çú=ƒuÀq+'óýԜ욋ƒ#•2®¡{~^ loX¸–œEéJÈšÓ’3¼ƒºø#鉯˜|©¸G?Mo#"ýˆ·.@=œ<‹¦–]@ìð943­„–¶+Ø”°ü?ª¸*aÅ Ö¬/¡mí\r1ظrW 4Û>phçá9¬\=ƒ©%ý´Wýô„ãᮓÖçðž²h[œ]%\C¡V›«¥ùxø<Ö„Ö®«ÀšÃu=þ.ŸïžHHN>DVž%S^%WÞ GþAÍwÐ'Ö`ŸX‡ý"‰ÛD/nC8HËi1†ñų8 žÇxÃâuobÔgá,£Ý[ðAfA˜–ÖãvŽ¢Ô»‹þÈ?²¯ÌÑ„xƒÜ8"Nâ’¥Y‘ÇD"’bÃÓÇ ¢\#ÔÒ(ìÒÃWn€úÒ Ô–=â]xBÁïb¥‚à Æÿ…Þc :ß&°»(–ÎZ÷2%îR)?EÀü*a㙆™¥eÔU3l?äË÷ø½Ž /ÃÞÏQŒR›ü\ÄPK AT¨,-t+ org/gradle/wrapper/Install.classY |TÕÕ?'³¼ÉðØ! 눲‡ ˆ„$H4 HXŒáeæ%™%μ! µj-Vkµ­[-Zתh¥UP ŠkÕZܪ­ÚM«¶ÖªŸ¶ýýЦÿóÞÌd’ ò#÷½w—sÏò?˽óÜÑþÈMÛy¸4#¤)Í(iFg£É‘fŒ|ŽuS!ç*<ÎFüêcnrsžŒ—Æãæ Gánªê+ùk.Þ$çJ3GáÍnjä- knnfŸ4~7­“ÝMMœëây¶J3ÇÍmpñy.Þ*l³9Äa.ââvyž//’·‹Å4)üM&µ6Ö£UA-ÓcLžêš•ëêÖn®®m\»¦vùºµµ«6¯®\»’)§î¥±M›3Ac<Ä4:(¢W§ *ü-t× îfšwL-O² ;+²su šbª_fÕÜüœ@»|C—À‰Þ.Ëb ï€Y0è‹¡Þ4†§ ¤R˜É{lmz'ðW K¶˜ä³Bp‰ÉÖô˜î‹GFWy=° VZõ˜!+[Ä蹩=jÃíqtu-„Q†œÍñ–zÖÆåð¶æ.X_34¦lljqÀ4~WËÍUbèFCóm­×ÚMœ)|©ÂßVè> ­U7*Ãþõz4ÐÒ•®Ä5‘À5kàCå‚©¼t£Wë1_4ÐnÙÒîD!ç(kƃåuSãúBW{Ò¼ƒæ.¸ÛÒÅ _†åÛ,öžYÕ¦û¶ÆÄnó †2|Là´JȲô«ùŒ¸4Q‹Ä£>ÝÄú0½³]÷ºßq-¸A:of¨ôK«ðå Õh kF<ªÕñàCd†¥cºQÓ 8¢¦Õz4ˆÅÂp¢ÁÔ N–Àk|ªßB…î_£k~+Æ $n¤ hn½" i†aN°½@§½‘8Me«£‰«Ëã E‰Û™Æ #ú„¯J¹Ý┕͵al·CµéSÜVX Îpë£* iaø—Š‘h«þôˆm„‘” ¸­ ðȉ5h²8Û¯u žÑ ÊÂD%7“XÆ—Ë×Ù¢:à;fcF¯¨z‹Éo@ü©]&Ý=lD»R1µ¥åˆI52"A æHÅñ$‘Uiýç„T@’}^±šp<¤§µÍdËî×%[(Û“/oèî&‡ _¡ðw¾!ÞiïJ FLeƒTfö,èAs6\¶ hÑ­™Ú>kÖ,¦ºŒ¹+™èN8ôduÎ’f¶4sú·š-[eN“É­2&¾Tu“$4G-9qBéÕO’ÖÜcÓ:F é§5Oh•ž­súÏ—ÅgÇâ ¢YsûwY »,>as§»M’Ô–V7š±Û‚¾š˜W&ÓTzšžQézW¥^zX¥ßÓTzœžPéú–JÓ7UzRér¾ ŸP©)‹¾§Ò·é2•v²î÷Uþ_­ò5|­Â×ÉÇõ*ÿoPùG|ÒñÑ…š>[ˆíTùF¾ "¤K·n\YYŠjEåóÍðíôÑ4GÈÊ·ð­*߯·«|ÿÑ%sÙ ð*ßÅw«¼‹ïQù^þ©4÷©¼›¯UùgôrAÿÊ5ñ°驘ʹåtSoz=à™›éõGô˜71¼(? -öjá.L‹"¡F$š•ykÙÕkD¼-ä^½‰8Øåš×U†R¢ÿUÍç¡[åŸóý¢§TÞÃ÷0m:*‰½cØ"â }5TÞ˪t+ݦòC¼Oånh…ÛÌj*à3°7ÒâÍÄC‹ÓøOÊ燛͌sBZ—·MÛ¦{›u=ì5´P»¤moGÀh+Ë›y4ä5Ú4ܞémF°ÐèòBÓ]²—°ÒÀÊãÛ+E«7ƒr¢"# ã—%^- ÖA 1·K,÷¶D#!¯æ5¢ñ˜èË*’ÊD0ozAéEÝTáÍ凓ÑÐ+UŸ YÝ)ûõ[…i(ñVšEØ•{Äö«|€*Ü«òÃbøGø²u´¬ŒFµ. ™*?Jo¨ü?®òòö$lF¯ ’ÝÍpÂñ>O!;­Ì»dííðµ…"(El çÏWùðPyZågøY•)H—¹üÂ1=CFµÆT~Ž%„Kóü¡Rå™Ê/ðµÈï¢Bÿ‹ÉiË,•_’iS¾¼ÒRøe•ͯ¨üª»¼¡‘!¡‚¢ªH<è7µ(œ#YŒzÛû«QoK$Zᕨñ…«òküñê ®ÅN^9ìŠëÁ¶p¬@‹ µ-lˆÓÅ1G`–pŒuµðw%+ £ŠSùu~Cáß©ü{þƒÊä?a¬Ã*øT~“ßRùÏü6 ÎŒ%ŽJïó;*¿+ø ÿ5iš!u˜ÊïI¤û›àcÒ`ë­P O¸éCb¸÷ÅŽWéŸô/•?à«TþoGðâ|l•ävrB·æ–ãV6Ç"Á¸¡‹+ L¸]¨2à6ä®ô…Õà¦ÿ\<&C7ÔÑ._A¹ŠÒ;¦A-ãËŒ²Ùr#X4/R ‡Ä¸aXu²ø š¶;ùØWdØbdªÒ‘0Ê %Ô¸‚  f¨œ£¦&ÓÙ•¢thùaÙDZÍK oÇg>¹Ë~cú‡WBÒ뿨3ï}–œf†ÜIªO^¨¥™1Þt½á WO~ ¼Vïb¹ÓI,æñï¸\"y/å9êñ^î%"­V Y(”™fýÅIq¬Ä(qZnÉÖ5¦~_IXl‰ºH¢$êŸþ=ÒçdÜCAa£w®j9ŠÖš÷s1 0ï¨<é¦x;4²M‹ÕG¢zMPÁþ°°Þi$>#åÍ Ôeݧ9C[­{]O?Œ†\•§Ë:à®ëhxuø‚Ñ’£Q[§“h;‘ƒ^T¼”¢’}ä,*ÝG#ö˜;|ír¢†•^K'ƒ‡é4…òñ6ƒ®ÄH‘E“®¢ï™o›oÂU–ù&|ÙÐû}úz„›ýä&Ï¥ÅÝ4²ͨ†¢‡h^FWØ=önÊ©pÈcL…ýÃ=Î^ÛTäqz%Å¥=”ÛM㣼ñY‹@¹¼–ÒD*ç³L>WZ»¥ø\JWÓ5àÈA‹èZºTÜ4®‡~mX[D?¤l"休n¬i4‰~Œ7'ÝŒÕv¬¼kpüµäá ÐçÆÈ¥9ã÷“§¾—&4÷ÐÄÛûèQô°«Â‘kϺ•&•zÝ4i=×~Kß'%‡-BNÞÕ÷nI7M©€”S›zÈ[¡Ø¸r]ç¡;hÖhêó8s]s/ÜO'Ud{²»išý6æQFÍꦓ7xéš¾a‡‹wõ½àQº)_Ôb3Õ²‚F£Ý¶Ï¥‘´ÐØj4•ši&ù (?B­PG€N§óh mÅŒ ¾Bt>E¨ }QÔTa ”Õ·CIÙtͧ;è'ä¡Sj½”î„’àXuÝ åŒ¤m´‹î?9£{±ÂAú)ݵ.Å®»ñæÄs)ýŒ~3Ý:¥äèÃ4§BÛÊSè…ö°B{‰¦|A£ñ¢ÐT>B3ªüŒ†°ÉƒôPc¿1AgCLáh(=@3fßK3›r ìPa“­¤q?Á!ŠÅh ÂÉ­‰áÒÁöT–E ÌÙÓ0×¶bvç_â. *xh¿o4¤”Ó`b‰Í·}PbV®¤nêrö£W5'=Ð#jȦ¬#4]¡ƒSˆØK'D| :&jJŸ¦ª¢’*¯°—Šß̺‘æR³7äÌQLIŠ›ìè˜ÛØä(mlrzì"Y…c/ÍDηï§{R°)2±| 6ÜAÃ`Ô±ˆ(Ä”ðß¹xžßY¿©†Ÿ\iz“}*=©X±ˆáM¤¯II_CšÑKÞÄ“²Ì·ÇL»ßŒoüoL—óqz"!ç«xŠWöÒB8È)1í¤¹xT4”Z`·-päÂÅî oi®cN…Óãì¦Å;I-ñ8Ð’,Ú°Ã÷x³¤ßzSL‚;àa½›¨\ÍÂö‹ð~@ž´`\èNÓó±}JšÊ„-]˜/ÌJYÐê9€‘j"ÙúФ€|P¡'J˜ü)~Ê _¿ÀßÓôŒ¦³†c£lôìNE ÚÓKyMÅ9K{è´znè¥eMÎG¨²É–³Í©‚9aÕêÆª±âæ ÄMôô´¢—V6õRm“|ŸÑCgöPD˜z(°¡B ­jªp=My%gµ…w«±›ÎÚ€x$dMÃ.šd‘]‹WDæý´¾›6HÇÙ €\!b³ÒKM xNÎÆnúš nÚÔMçÊ`Îf¼ì„¹€ÑåÔh>¯¥u  Kyhï‚)î†âîAʺ3îÈvSâÁrD„ PäڃȴQå!¬ï¥nh«pìµýÜ`Žƒ0Ûàöpsîÿ˜iÄvróYú%t»Éë934´Ñd: ø¹°Ûzž^€±+èLzÑôª+0÷eú5ú®‡Y_¦WL8Nà00)ƒcÂ9üü6çr¹ú°¯+iyü¯Th™B¯)´R¡z¢#4}}’—Ó'-W¨ñ …Ö /Ù×éDo×xÍ„œ-ûIÛKÍÝä«+Îñw“žu'9ì»m»Sœc²û$XŠÆbã0QÆ8‹BB •FÐïL¯–]„:^8È’Ÿ»î‡"x.,6=ª –zÛÒÉ%ÈM'™è,™<ðì!»äµÉaÛ½Ã&Þ†©³ûYšfæ Ñüalü<‚Ê °Å‹p²—‡ž§9О°8ÛåcÖéObªäÖÌ 7é-S€…);,¤?›v†“ís¡ÐÛ<ù3É’Ÿ6ùùel.nuM/µJfn³`¬pžd…^¶2 ´(´“òD¸ùC¼nŠÀ/^é¥v8ÕùMÆz(ÚC1”*»tgÅÅÁ¶í¢á–«mó(îê»N6íN—ùæq=ºBnBš‚»(æÓ  Kwª·ËR lØ–qC5£  ”1Þ†òÞ¡S!é2z”Þ­º?¥•>DFúô>F,ÿÔ>†â>AõóSÙk —ét6ý…þ mBaðý …¼ö>ý;Cg)e_ŠV»tôWãËšç†S~DÿiÄ)ŸÓ(…>V¨õ•+ì£Ù¤¤á\FЭ€dö|FÙY}°º#5­æP,ç´[$3E#Øø'ý+‘)nFŸÀ5´eWCq)Ê­¦ö›hDI©YluîêûÀìB¨ÚÖŸñ¬\þßhÿñþST{ÿFÅ‹äKŸ§@ ¢)Mäcî=¦&òé 1ÉåSÍ¢ÆÈæÑÿš…Îý¦!‡#þï=B¹ÜÏô(vú4Át V‰¦•¢bäpWYë4·˜h²àµ¦Ðg úÿ„10+åD*w‚ø0n9p9ž2Ë!ñ83iÕš`‘Æâ/¨/Ãbçq-Æ|N,®H,§Y€e^m$gJ*§%èd±-ûî¤cgGBÍ«¡ ‹.¨‡ÛžŒ”¬²Í•¢ä%«pqAÏVáâb§éÓ4Î »2š3+ó6_nΛÒÌ ¬p6»3)ƒ3Ó>Š2(‹‡É|VQ©JŽÈB¶þÝÀ“éGÄÿPK Að¿:öo4org/gradle/wrapper/Logger.class…“koÒ`Çÿ—UncŒá@Ø&s*]7¼‹11$KHð’°`²wÏÊ“®³´¬_ÅO¡Fgâ ?€ÊxžRŽ5KÓÓçrÎÿw.éï??h G ·b¸‚Û1TP£†º4w¤¹+ͶUÁŽ‚]†èÉØ.;`XxfX†ûœ!R9¨öèÓ²û‚!Ý1,ñj<8Î>?4éd¹ckÜìqÇ{ÿ0â#†bÇvtUwxßꇇÂQ;¶® §É6m!Wéó÷\5¹¥«]×1,½)Ê@ŒF\÷s ©®Ëµw/ùÐ'.Hq«Ï°3«×:âNWœŒ…¥‰fuæâ…ç-Ce"Úè„!ÇÐÔl·U£#—;²›m"x©*­@o¦ÑÛbˆwí±£‰=C•˜ôj[Æ$‘B#‰’ î%qŸc”‰±I![3ŒÌ”‘¡JgŒ´ÇXó&Õ¡ovÂHIFií ó” Qª¤V÷(µIØ”’õ)rµŽ /‡,®Ó*üœñÈåàꊧPæ¹*qw(¤PÝ&nü_Ý–7Û›PK Aon¶`8org/gradle/wrapper/PathAssembler$LocalDistribution.class•R[KAþÎf³«éV㪽ÙK¢>Äõ²EúÖRŠP¶ÐâCß&ÉL\wÃd£ø¯ Búú£JÏLB1V}˜3çöï›Ãüúýã'€}lÌ£ˆ%xX3ÞKc^ùxã£BðÛjW}ÂB£'ÎE¬²øH%òý¤t¨4ÁË»j°ù–°ÞÈt'îhÑNd|¡E¿/uüEäÝú` Ïš‰ÔŒó>¨Tå õÚìöiÒéhë„àdmIXl¨TÏšR $„¬%’¡•‰'I×%,ÙÚ!Ëת9ÌU–‚Oi*õA"˜š[ÞÍ”¶ùÏ~[Ø‘ùÝ”]O¹¶uw%îã­šˆƒ¯ÙP·ä8§Hö .@ ¨˜Ç\s>Ö ûÿ¯‘ÕX)‰H;ñçfO¶rB¡fVY™5 Uþÿ™B£½ÐÊe#ÑVx“xÌv£.¸|¯DÛ#Pt 'Ú¡íŽà^sÞÁ¢azOê1êËHPæL4Æb‰¬g8Èz†Õ±žÑaXWñdÂómºŠÑ Wi<›Ôvt0n˜Œ&<}ìÞ_>vðÌÚ第¸òšßDPK AJØâ[&org/gradle/wrapper/PathAssembler.class•VicW=cKYÇŽb'µcÅ1­,Ù 4@ܼ5QkÙÁ[qÒÖ[yy¤ŽF‰ e)–})P(”²CÙ]h¤PýÎob;wf,Ù®LÛzï¾§ûî9wy÷Í?ÿóÆ?œÅß#r-ˆc=×#”nÈ—aC…%ÛYU<A9Ù±E*…áÈ\Ž@ÅMÙ¾%Ã¦Š­Žá|Rþ‹ã™0>Á§ñ™t|V¤gU|NæÏGp_á¶ŠçT<Æ#ˆáKa|Y”¿"ÃWÅÐ×DúºŠo„ñM¿Æ a|;‚ïໂÿbß ãûrøE/)8:]XÓó“fɱÍÕ²c,ZÚ² {"¯—JFIÁ‰‹sc“ÓS+‹óSs+—f3S+ó s陋 ¢Ó×õ›z*¯[¹Ô< X¹Qm«äè–³¤çˆ‚#—çf™šX¨:’³õlÞX,ö¥Â†hxfÌBêa3oÐDèAÓ2 šãƒK …,ÕÚ§M˘)o¬ö‚¾š7_È/é¶)k3ଛdÝ?]°s)*uËÖ‹EÃN]Öõ1zµAM›@Gãû¡­=g8ûã±odë1o¦·×Ì\ÙÖEwtðmQÞp‰ÙÚ^+ ši¨ ¼ª—Œ]ÎÒ¬'¶Ú…ݰ½•*påKWÌ¢‚Ùø[³÷.ülyµlç/é¥uJŒ¡'Ý×¥áá¶ £TÒsƤ™3JŽ‚>O©d¬•mÓÙJeöþMýàê–#ÕÙtu\B»öXÚ\3Š~|B%‚ó޾v#£ýBi·ÂMcjÓ1¬’ö€åFKat”4cèW‚Ã~ßËpR‹séCB á]´óµ¢ÞÕ¦ñ"Ë@ÅDhwœIsÒx€ê" 9æÁùBÙ^3d“Å¿¯¬F䄆Q<¨áÃ8¯â‡&ð²†Çñ„†cVCÓ¼Û{-kø^ѰŠ5Þòƒ,ÆËf>kØ~,:?ÁO””†ŸÉj?×ð ‘~‰Wœ}÷E/6~¥â×f0Ë‹ž™|@Å«~ƒßjø~¯áø£‚N—Õm¥ÆÍ\ÚrŒœPú“(Œb[輦àXƒÌ+è©ïΕ-ÇÜ0öüÙ;Q(ç³1«àÄÖY¨1Ó*–˜W*#bûÏt—Â_ðº†;¨h¨Š»w.övî*è8Ø35ÜÅ_Y~3ä]-³ÿdM[Åv$A£øËU*ã|ŒÕ3K±²uÃ*Ü"ߎº3³«×5gßÖ¼_â÷¿ÃûËÃñÁƒzì@ãwk®3Þ°Ð*‹ÿ$/PVVÁð;ºö~‰Is »>œ>ГZòîÛ˜ÇÑ_xÆvëý¿ÂÞ7@Û'ÿO+òÚDÚ}òÖÈåÌážÚËÂÒ¼vˆJC •‹YÝ¡¹`üê¸0 e}´P<íítÅÓ 3“hÔ×ë; ëvá–4@×ÑV>ò$Ÿ56g¯‰ÉÜéK©¼ºÛEÇÓq¥çûU`<]Öó¥ö¼²¼²¿r·Jޱáñ²]`ªœ­Cˆ,á¿’Îò‹¬Ýxç àƒ\5aëíY'ùc¤æ{"LJ¸z?g…s0Q…òš«zc„3ЇîÅG(iž>Š1Îb`Ü7ð05E7"É;hª[9BZàwU€4[ÐïZ:îiû–DZBb“¾ÍÿIå|;‘¬ ¹Š@&1TEp&1œ¬"t>°uYþ WѲƒÈr­\i´Epèp¨ ½ŠŽóÁ]Ý£ût£ût]i¨~(´ƒcˉî`w¨ŠÎíš;=qŒÓ•A´#Œê†°‰a×µKéšk·1Åð°Vð .2M@ÿCèÅe|Œø­ŒÏæyö4å,ºÞŒÔØ`Éeÿå”U•8Mò¤û¬¯ó¤”^g2zº‚‡z_F0¹lî­à½ÛîmNQ׳G™µi¢dýY—KÌ;[CëIJ‹¦Rã ®ÉÇýÚøµ%ß>î³<)6{§û2C’š }Úê g:Ɔ¾ÏÙV¹¥K9#½ªÛ]QÛ¶ìÎÍ”nv¦-m•¾Î½†v^g-£*6`Ja©Èà#Y­" GANÅ lª¸‰”Š-|,Ðûì÷ƒg+[ò *øDŧøLÅ縥â |©â+|­â|+ÐXyvyÊ) î'ð1MnÄBʶ6‹w{/(æè¶æX,£Ö(~> WÙ¹Ê## IŽÀ±=×þ›(¾DÚÊÊWFîÙ$v tð$õ0;©À/èÓð~Ç*˜x¤BDôV©`ª -nýµ|/âº#·¿ÿŽÐ)ãÚÅøy­eðǤ2FIiÙý&Ñ^ÓÊ«,=A•5ò²ñÙ¶ì’áð¾´Tã‘mªMëfRص/}6·’-Æ·„bU ñ$eñgþ‡èRevXà|ø3%Àóò_ ๡~Šcg5hçOÈW‚ò -aŽ‚£¯÷Äï.¤›²Ö5¢T ô —cúÐOƒÅ_ð ü¶‹šå{ðLõæáý¾¾»»ðÑP;½ e™™ý3ýyÔñ؆:â•JÐ{3»P—wÑ@ô¡æÃy42ESÍ÷pä~GwÐ"03°ƒV;¸L¥M`Äôæq¬¹=çî ¿4éÈãøˆ/è£öZú‚>×u‚Þœô`iûÑNß]xÈG7Yø κcÃA=·#7?£”ÇáÇ ÆI4¹lv1ê4ýÝ$ Ĩn¼Ìq˜³R!9K€MÏ-²z›™À9üBÔ¯r‰œäWÊ)´5È"è î,µÛìÊ9z|Œ~…_=/±’ÊÈ!Ž~üLë0›Ä÷8WIþH±-_„Ú÷{ÉÿM F1µWÁU>…Ë ¯=€ÿ’‚úއ¨SpñL<`¦×Ý–_b†qW»üPK Aª=©°?-org/gradle/wrapper/WrapperConfiguration.class“mOAÇg¡ôÚãJKŸ|iᤠ" HULCß-œåH¹’»«&~*M$&¾ðø¡Œ3w ”e›˜&3³3óŸýíîõÏß_¿ Ë:¤ÀÒàaæ’`@EƒG xLá<™2OÈ<%³¨Á’ÏŽxN£8m—ÁPíˆæ–kÖöÖÖ3Ýõ5îÛ ²QO‹»M«Ž5·)÷½çÁ!ƒBwª~È+ó õÎ1í«sM¢(ê/;®¬0è/•wÄ^´°ž®9®ý®sܰ½¼Ñ ÷nïóÖ÷Z‹d,8t|åZÛkZM´lë‹ÇONlÏÚü‹¶ûÉiv,.âsñmâìî£nsúô =ÌN æN8¡u‰ Ñ½ÐÆØq$&ƒL*AîÂ=HL)£ÆìBCO*A4dF r_ ¢É s¨©ôÉ )%È  2¯)©AeEÔ,õÉ ²$!ƒÂçX Ìþywã ¬âyõ%^}9„¯°úÏ3à 2¦y~žÉOȸ¨`;¾Êä¯)Hãƒ^V0ƒYWðõ^”а¿;98ÐÝ14ØÝß724Ð3’èOt K÷×Njí-;Þž´-#;¾[ÂüN3›·µ¬}HËt eû’]„rbbßàAqy1ypßÈ–mÛG’C½–éNŒ$ûº*=” 8%g™9ݲ =/a©£zÁ62í‰â9©¿ ÄuÀÈþ NÃlç=qÔ¤Ìì˜1.aCi·[Z:£·Ÿ²´Ýk?ìÌ‚§`i¶aféRݘi‘œãzÊÞoX4šÖ”„­ÑrðÛ!vÖSºF`N3Mš-ì1²z_arT·µQÖ5Üc¦´Ì!Í2xï²Ý®\ò)éá&* Ÿ´µÔ‰^-çÞ«Ùcd {¯„õZú»nÃ! ]«÷$E×锞s=°' r|Ë™¸4gé9ÍÒ÷yJ¬Ñƒ Y†„EÑ Ž€¬n· ts@òfÁJ•BU¢(Eò2æÈDK×ÒÒ²2t!cjé„'-BF–Y×&‹vÑÝÙ\ÁvŽwËø†Œ—d¼Lî×m¯z¤”^B<úÿd‰¬ )G£Go..?¤n.¶LÆ—Öaš6é§åz5¶K³lÝq hÖ8Y[ç#ƒ”0H M·(aɨþ-ÊÂW ÃvМ$›ç‘ûÜ`Pm¬‹Þ¬Ü?}U·b§ú4FÙásïN‘Òú˜VÈÜè\;ïéˆ/TÈÒ,P¡§©(ŽHždHW)¯(±MËî5òyb-Ù«$E;µ¸¤¢"6² Íÿ»vÈ o±JˆVð;Û6w»±ÔîT â›$Ú¯º™ö-†T|ß¡Æ]²y µI½XjZ]"%ðÈ)Y¿6¿>’6i›5íˆ~šªg#•M «”;•Šïâ{,í5Ÿ;¬¯ÃëUÀkUD· u=‚£*®ãû$$í)Õ-¯«ø^Q‘ÇI?dIe ÍžPñ#æø1ë½Ää„F/Q²0©â'Æi?e6õ!#—¤(莄Ÿ1õçeøLø%ê|º%y°Ó,dÒÂKÜ¢"§|j™“¡ÙS¿RqŒmý5ÿ¿Uñ;^ýG©Q¥Ëšh†&Ÿ…}#YÜŽI¯§7w<}EüAÅñ'æLÇQQñWüMÆßUüÿ”°¯ÏŒˆDœ2ì‰È }ʉx>§§Œ1COGŒ¬¯)7rƒ’a…W¡äTÖÖN{üRçÓ“Ë|88a™§œ÷«ÄÛïAXTY¬Öø¾oeÝ‚zfu”Ç‘´y±¥º®¡çtR³ý{…·»:‰íßvêý:ÉZ˜¯|`GË_8檫x†8󨊣¾¢êò~Ì•œ£7ó:§Ë+x‹µ@¤ü-I Ý:bäqJÞ»q(¸Kq6±Û·ßb¤…j &™šÐù˜Ïï};dm§?JßpõEö¤“›)º@a Ú¦¨ƒÅ•führ%’•Qßæ¦2&ÛÔxëg“lL¿->lDÚÜé×ÁM6øuF¿g–ôÊÛºߊ C±šþ!Ì£BµhÀ^ÜG»×Ю ›h¿Ï³_FûÏ~í;=ûU´ßïÙ7Ӿ˳_‹0·kZ‡¹c‹™z8ÍóIvz‰³v¨¡Ð0ixUñpõ,sÏ¢fò´€ë§Ña\‡ªs oе(ŽC´ÖØ BÏbùj‡ÃJà%Ì®Ž%¯@Åü«,,V.£ZÈX@3#Œ8šÐæ‘Õêš‘¼RMô`:B¥ûéB€N¦c³X@À xÑe,޵^F8¿Œº8isOÆ[¯`IìQfQ?ƒ¥b^ÆÓ –Ï¢aÎÙ ç¬Iœ­tÎV9gw‘‡"3Xí6;‡kc‹s¶Ö9['ÎÖ_@cŸpÃÇ qvCÛ,bW/’þ<…guÐE4n"kÖÐÿÅÍXBÿ™èeÛ(¦Û‰rÅ}îÇNLbÅnº¿—öà<îÅ ÿ„pa€öKq‡…K§éÆ0 VìHI¬8Cª„K—¢ê?RMÁ“Q%Ó¿Vš£tʯ<Z‹0«hn!çÅ{È£­×9o(g.¡nmt²‘rgíÓñRHÃ"2„¸ü ÑLòŽDÆrõ â.<€7’^¬MÒ«h–Éî7Ñ.@§#Ä}¬¨Éâ "áð¦l¾%Þ4‹-‡çp÷°XnŶÊÌê%úPG ”2kµ«‚›Yu™ è¸2Ÿ&"[²rÛ‡É÷ôÆ[g°ƒ~;/@éã¹M´–dÕ客ÔäT­¥P, Ia’UOs#ÍMä\Ö#"t[éf8¯80Œ´£HyCTÏ!âøÈHsˆôš¢ºcô£/··ÐÌÖ…œTÜUYÇÇ<¹0ýßîÞòýÊËãžËÁâåã8áú*C9ö­ŽôÝ»mñÊŒ=‹HN@N3XL¹Ìˆ[[Å\ mRH # SdL9¾\ö¸ÙŠÅ¥l¥ 9O†ŠC(ˆ.ÊH']¤„Tí µú!Ùž ތīS´ª˜§]ÌçhµDL…³yW !p 5 éÖk¶N¯<ÚXœzZ*%q3a0LQwxˆ|q†,8‹åx˜’é¢?æñcKQ—–¢.-®.¼š"öc#ÞLg‘d ª_EXÆ™`-q-z3AiÌ·šD#»7è6²á×þ¶^á—Ç=n*êÒäê"á-‚ÿáÿPK Aã…Ð_#gradle-wrapper-classpath.properties+(ÊÏJM.)¶M/JLÉIÕMÎÉä**Í+ÉÌMµPK Aorg/gradle/cli/PK AÕÜ?®<S1org/gradle/cli/AbstractCommandLineConverter.class•T]oA= ‹ëÚ"¶µ~C?”R*O¦Òh4!­ÒÄÇaY×m`— C£Âߢ/4ÑÄà2ÞP–´ôaçÞ9{ï¹sæÞÝ?þPFÙ@;:v D°c@ÇóÀ{xY9y†xÕõ\Ycˆfs§ Ú‘ß±V®g{m[´x»KHªá[¼{Ê…ì' &?»†bÃNɼӵKV×-ÕÛ)¸%ü^{€ìÈ÷Îm!mQaظÌõµÿŸ¯|¢j«U©›n†Ãl㌟óR—{Né…¬•ì¤}f[²’ C¤… ‡´¬-¢ k’ôÚ–Á=,È÷¹Ø‚ak^ÀÌÁß«Š^tÊê Ö”Âõ¥-JŒ×_,»/]ßèØc¸ÕtË¡ +;Xš¨rŠîCµuVQ CWˆ uÁhúCaÙoÜ ™«ú¶Ô1aà6Cúºë2Qľ‰LÜÃK†Â &„!9¯‰a{ Qá23Quá {¶'§M¡†Ð~rÕÝìõ3|i153 ¯mnžDevf¨èÎ߆J…£–š~-C…Hý;"d©9´š´«“edcù °äDq‡Ö¸SX¡Õ`I²w/!)²Œ:·FyÝ7²ÙÍ_ˆ|¼@ô8_AË #ÄöFˆŸVX! ÊK`öªR~œ;©xëô†)ï>=ŠNâRnpŽ´âØœœcÿhÿ˜âŸ¯òÏ”ô4=c/ƒ-e·ÿPK A׃µ³Xì ;org/gradle/cli/AbstractPropertiesCommandLineConverter.class­V[WUþN2ÉÀ0å H¡°Ô„¤ÄKKµIQJ©†‹¦‚Ø;L†0fâÌáOøîZ¾ûZ_¢t­ºúìÿñA—·}N.iÊ2Y9çì}öÞç;ûvòëßOð6¾Q0Œ÷e| `ó|¸£`w,â'?ä«û ÒøHÁÇÈô` Ë=˜Å V»ð‰>íB¶ƒxÀ‰Ïø°&cë.cCÆ Á”i™Þƒ?]cì¼ÁЗ1-c¹¼·i8´Í"qB[׊kšcrºÆ”¼mÓe¸™±B¢àhù¢‘Ћfb~ÓõM÷V»d8ži¸ öÞžfå¹ÙÛÚ'¦á$ F]èp¥ä™¶Å0‰fv´}-QÔ¬B"ë9¦U ёѻ†§™E#Ï0ÖfÏÕ³f±[·­-³PvòTä4ØÐV5Ç%\ÜÁ’X3L¾Xž¤íÚQgIW‘‘´¬W]Àp§0™?¡•¬:£ì™ÅÄ’VJFOѹ’MA`i Ò®q¸¦ËÆâAÉ1\W@ µó¦\ì¶AÜŠ€A)5"É“ã4‚¡æä8,ÕäF³hªJ+gŽ ^Èzš¾KÂŽŒ‡añ@7ª e<¢ fÍ‚¥y"¨ß¾´;D='þûš+›;†î%£­,†üW»’J /G¬dí²£÷L¶Xg<Ãm©x# ý§íªx ã*&0.ãKo 'ã+A“|gºŒ<ß¡o©(`[†©b»*ŠØSaÁ¦¼¾­¢„¯ Â«ÂC™û”%M—UÅ4¥Ü¹zÝù%ÜLEu|tššg·1qBuÞ)”÷ Ëk$1Ãø‹ú 5ÖÈÃÖxE;i1g¯÷Yu[së°¨ª¯D:2ÜKZMÍu6ò?Al©†T'¶[ô'\íL’z ½¢o’B‘“EŸ1]^„½Í†.³õ¡&…z6ðK®Z6<ñ¶ÒS+Y‚h~ßu.›VÞ8XÙb·»uš÷ù2©¿iÕî°•t»ežÔd£N§Û¾³áH;¾4A†Á?2/y/• ™jéŸÀ~¤…£43Œ1𺸄ˀ$ñ¾ æ‰Ú<Ég’yWjFK$í§ùj,ð ¾ ÿtþì†D“”­ °¯ ¸'R® kýøÔ$G è}/aŠNäƫ֪ÄjŠ~Œäú¨ýDH›ñæARüôßèô ͹?·‚î ”#ô0,_;‚Êðiqá9|·¤)Ô[Aßl øq"û0àÇú%ÊT‘Âéq¯Ô¶þù9þ„NêËäR7¦È3ä…wÈó„oƒ="\ü× Ó bôÓjŠèkDóÛæ·ÊQ0Þ¾Îá-úé#KuïsÎuâÜQ‘þÄ€ŒÙ¿ác¿cøÚº)Q‚á=áÐ[ýótx’V¿p¢2‹?Ç`á'g[©:¶é«YMᶘçþPK A}­ÎyGK1org/gradle/cli/CommandLineArgumentException.class•‘ÍJ1…Oú3£µ¶Zm+êÂî´UÜV " Âà–îÓi˜FfĘ́¯åªàÂð¡Ä$-U´fq“{rïwOÈûÇë€34K(`Ë„mu çœ žöê‡þ=}¤^DEèõSÅEØ=.å˜T}.Øm˜ÐQ¤•š/ ©â&Ÿ‹…t‚_ªÐ GÌ "î]Ê8¦bl *Ìb&Ò«ç€=¤\Š.³$¡¡¥þrAÐ^âí›2˜(ùdæ[ÃÅ€f‰&Õ—V”ú2S»æÆoë/c§PFŽ ‚Î?^E°û5ÿ.)Ùâ-äõ/˜•1ttuÖÓyNïN»3y±÷+:–¬ÚÔ•;XէƬJëk–â ŒuÍ0¬Êœu£gäõî¶;ÇSä~ÂötÓ¾…ÌÊ0w3§*6¬ÅMÛ]ûPK A³ßâúg)org/gradle/cli/CommandLineConverter.classQMKÃ@}ÓÖÆÔ¯ª'Ï"4 F<6¥ EQ($xߦë²%ÝÈvSúÛ<øüQâ6…L ]XvæÍ¾÷†™Ÿß¯o÷8wÐupJp’L-¸6„~/œ²óS¦„ÿb¸fã”%ìu<å‰ ¼*Dè<.þid¦æÎn$…b&לpW'<(a‘ÑR‰`ÄqàÙKxî…™¾Ðl’r?I¥ÿÆôœOFÙlÆÔ$”jçήwÚøºvRm_Uˆ%J¡¡ïÐÄýªñ°vJQ–ë„?ÉÔê_”äFë%p}»b.·;o¾ºÿ-7Û‰Zä3®ÌfSm¡Õi¶M´l¶g³–ÅÛplÔÀ~Qqk*[9Àa¯‘#ïÉPK ASf Õg&org/gradle/cli/CommandLineOption.classV[wUÝ“¦4™^ˆ´i¡\ä"iBµ´ ­ÜZ.Å^ÐÖŠÓdL¦™0™pïwü¼ø¦¼ð .UYË哾ùü.—¸Ïd:™Ü¤Ë‡œós¾³¿ÛþNæ÷~þÀËø&Œm8'ã|œkE–Zqo é¢Þ‰à.Eð .‹A•±AšŒwÃh/ÝÊ iEHzWœ¯Š…ª8ɉÁC^ܾ&KFA†-A6ó¶næ :¦®¨×ÕTÑÖÔœfJhÓ³9Õ.Zš„Ý•§c¥¥¡æ²©9ÛÒsÙÑü¡¨V¶¸ªåìù[y^ÚäÓ7ÔB*›«÷Æâf$£Ò–î8#!Z /!¬çÒÅeÕæJ‚´Dÿ²–YÌ/êöŠ„¡jÿL+›ÊZjÆÐRiCO›««j.3¥ç´YLjão8£å--­ÚZFB˘žÓíÃbqŸùI[³ÔeCí_73šHafŠ«Ëš5/΄ÃfZ5TKkw³Åtà Ú+:3¼ëÙNUæÇ³-¡»ÒÓë©çkƒê´ÍÙjúê´šw®Ê(ʸ.!¹a‘pV³g×)³)Þ_Cš½Õ{ œ‰¬¨…c.[$ Çk¨Ò¿‘lª¹'è´¡«{âRS|~2ävÆ?á§êæõx+ÉÚbi…¢ÁÈzkNu#£Y¢ j>¯å2ÓZ¡ fYËT¼¡òR­QŽ–ûxu¤Wx8R‹º± Eë1Ã0oøÐïgëmñަ¥ž74ŸŠ¢Ór_q9éë\…WO•w¸–/jÝh¼Šz"#ñÿåÐzÎ,Zií¤.Zª»FkP *Ø$}ÙÂiµ°B+ ¶c‡Œ› na·‚]bèÇïá¶‚÷1£à|(¡³º 2>Rð1>aÑÊ Sz´‰5 ‚‚½xAÁ$>UDœé¼P~Ã.*8…Ó ö•Êï%>Ä‚Ïñ…¸û¥‚¯ðµ‚;ÂôÎg¥¨ÂñÙå+ZšþEkߌõM' gÓ6-‡0 ë:ú ¦NVçÏŸ=!!¤{ŠÝLX`©e2zF»I«Áœ3Uö\É%ÑNµ§e5CC]ñZ]AáºmѸYC¶YÚb×Z.+ÈËØ&%ôÅÇÿëb Ý`¯ð)ð³sÜ4 º"((¼á{±j^×ð<ÿ¸·ñë QÁ*°>\¸ÄòÖ{ø#™åæœóÎü%ýNîíÇ׃\ý&9ŸI<†”x‚ÀùÇhzˆ`âG4?DKyGN®!$azÿZ%ÜÅV a ¿"2“ø Á5(,Þ{ú碑⸠!ŽÛ¹Š¡=èÆVú½£ôé$¥Ij¼Hôa¼Dÿ›„/üi;ÐßaÊ çÒÎ¥ƒ”»xÊšdôÉ8$ó‹¬ð«TŘfŠ+q½Yøúƒ£r²*6÷:^”ð›]Û%׸wG\788ˉ¤H€ir`ÂÎv?/'¨î’š†ì–ª†ØÙãç¨cæGaf„;B'”ˆFÖí|vévÊçrȵ#áx=Œ¶zCÄ8Pc.ÆÎÑ}‚vr cйëü JR̰i1!¤hô¹ÇØìˆ]ÑnŠÉGˆ•S³…†À¯Ö«ÓÁ¢ô0§»ì ƒ.§jÈ5"GO¥ú† ý™ªñ޹nÝæJ0¶·ï.b4Öó-ÂÉÎл˜n=ðŒw³"`9UZ®Ä;éÛ;:"@²¢¬ÍÈö§àx°v.UàkÊ®ÏÛ¤XRbI3Dª¹Ç -›¦¢Žk¢|Z*tzD®‚ãB!4q< b“ALáC›[j]y¡¯éÆ–~D=´' â*® Çf¨] Lßrœ »Ês ˆZ«ü(ÜšKŽ¡ïL=VMLŽÅÌ–lª‡c:N>}ÓPí»WщEà(QÉŠ¢‹‘$UioÑå´é¦¥ÔU¢Ã1¨óªÅÐQ>1rË«ªbíÝ-gqÌÑÜ:Ú»£fÍ9´cùЩ¶y§«š{Õ¢ý:Ãà9¹ÂOR/Àÿ•ºøiPÑF¿üFz°PH 4¢¼ðˆùúmÒi’Î^ÚƒÑØ'x¢±ø¼èìA3­ BÆ&PÃ&`Sh!^ ÉH—p°)šLÄc¸NÖÔ÷ðÃG{&úžÏðÅ¿ Æƒï¨íþð.øRŒ$þ(ÛAÝö.¤%¡·‹ÀR,N¬`÷ž°~ÛvX¸€lMlÍ,‡›·Ý‰:†öÝÉàÚÉ AÝ&ÊCA'ÁÂé ®ì7"µ!ÙYr8GRÃí °ƒ Ô (6^fŠï›âè"pfSQ;‚Š!nç¸ÛÆèÁeÚGÉl=ÆZ‰sƒö›> wDÈO7Rè‡x…¥0Dòí!Þo)Œú<˜¦=ë“þPK A¥D£¢&3org/gradle/cli/CommandLineParser$AfterOptions.class­•mOAÇÿ{-½r-´¨ >W+p€Š"ÆDð!$MFxa²´g9½î™í¡øü.¾D%ÑÄà‡2Î^ÏrÒ’cšìÎÌÎþffwnûó×·fqÛ€ŽQiŒu“4®£h ‰IS°tLë˜aÈT¼z‹jÉ6ÃPÉ“5«&yÕµ­ŠëXO¹lØÕ¥}Ÿ†ÔG8þ]†‘±x÷ñ2CrÉ«<§ +ÛõM[>ã›.YN”¼ wË\:JIËi0dï½ômùäïxB©ËBØrÉå†Mªu0r$f„Žî§¬óuþ~Ó^õ¹ô›F†þ±Ò+þ–[.5k՗ލ-Œo0$¸¬©äÚz<Aè˜eèkÊͨ´èS ÈbÅÑÆVçï…ùg<±â‰?ÕdþÊ`±Smññ¢‘t\cX>ÂÇcg‚>Ðv¦Õ@]7|”- ƪ·-+öCGõÅ@›Ï”ª0‹ ²j¸žE7 7æcékâµðÞ‰W7xØ’Š1§ãf·0Ï0y¬d˜8ÎÙ3Ì¿5èó?U†Ñ¶=ì¾ q~ :5úh˜hþkºmqéóåÕêƒ_ò2w·íC^€2 ô\¦é ¥G@õI]ÐTŸ‘¥‡´G¤i4gL¶Í,~Ab—T ½4ö"A;Ÿ£‹­Ã`È‘m éŽò:CóÙ¤ú÷3q‘æ‚äÓôhbÆoPK A¤ÇÇà› <org/gradle/cli/CommandLineParser$BeforeFirstSubCommand.classÅVëRÛFþÖ¬#‹Ä¸˜„¶¤5|ÁÜ’`›$š[qpZ'´&½ÉBql9#ËM^¡Ð·HgÚ!)Ó¤ÿ:Ó·èß¾C;=+9`bƒL&3ý£Ý=ûéœo?=:þûë sx c‹'è‘‘Á"GN†„%Y\â ®r|$Ë+ö± ×8®pƒã¦Œ[øDÆÖ8ò2ÂXç(pÜaè·¿3±†±|ݪ¤+–ºUÕÓZÕH¯Ök5ÕÜʦ~Gµº•#ô’aö†“Þð׎y« —›Ú`Vë[:Ã)aXoÖʺuW-WÉÎ×5µº¡Z†X·Œ’ ËYÑÔ-ýºa5ìb³ÜòÉ Ü2MÝZ­ª†N°EO’±®Žè¤AmÚEœÎ³0 ÔÍ¢­Zvá‘mÔMŽÏݹ‹6mòµ9™¨~¯¦«ªYImË0+¹NË”7õßÄÁ¯Z!]‡?úvuO"¹wƒ–…Ët¯÷¶IUhÅ8*›\ŒŒXkÛ·ÕGÎÇå(2l¿•¼ò>¬“{¾'3â1+s ±^Þc‹õ¦¥QΈ„îÀL íœÁˆ‚aœæ¸Ë:–¦âå{ 6ð9Ç JØdˆzé©à>¾dÈxFºgn›õÇf—ÌQíÁð.­nÒÚO£Oü_<‘Üÿ'Zûð=OŠ=6>¶€ »€÷É6L{„Ç(ù†3£jK6†q¾åõ/ÐG£¾ ©”H²ô­Ç†ïú“ÏÁ}ø¬4"ýY×|âG„w!—´ Æ ¯<ÝÅ@)|Rú §JþTñB;|¹‹pI¼‘‘^!ßyêJÐ= Nt3D5‹Q–Ã[B’]FŽ]¥æqÅ¡¿àÛ£¯c“D[̦hæC›ˆ#I>GIž¦©uM;õýƒ‡Ä Dœm·@X‰FîèÇöõëŽÙœ8îBösj”O;9æÅlœ/tÑñq иBjQ·|–,1Ç%ÑMg‘ ¦yF¸  ºéUˆ^9‹Û„‹Ðø©äÃW4~-ÉÿPK A´*«ZMïForg/gradle/cli/CommandLineParser$CaseInsensitiveStringComparator.class¥S]OA=wû±P·RˇŠ"ˆUhAx1¦„¨MLšÔ¤„÷¡êàv—Ìn‰ÅÿÀ‹/˜ø`|öñãÎîƒEkâCçÎÜ9÷Ü{Ng?ÿðÀ&6 °Q)`Ì,9Ü5Ë=K&½l£fcÅÆ*!¿¥|m2ËÕ]B¶t%a¢¥|ù|Ðß“zGìyœ)·‚Žðv…Væœ&³Ñ+æ"”M?”~¨"u$Û‘V~¯ô…Q  NÓ÷¥nx" %œ©6mÜÁ#¥nÔóÖ›uBå_Єñ¶êù"ñ[šf)ÏýåØÖ°àm¦*´ƒîȧÊH›j·fŠpÉÁ\ëp ¥ß©LbÊûúèÿÙsì‰ ÂÔEŠ‹£Ý"L¦ïd'höü@KÓŸ0}Á›1/dü MXEÏnØü…qsYXÆ'>9|r9Ç\í=¬w¼±Pä5o’ô—yï$L Ì‘Œ…i±ft–cyeõ™í¹·ÈÍ›}ö˜³™˜©lôy:E¾Á¡1k-©LYÍn3q§2®òÎâ\Ãuæ™M&:åâÒcî#íÿ€ï2‹µ•OÈ­òïù㿈(&íJ`æR’‡­ÔºØ™p6k·0Ï÷,ÄøÛXŒã\‰ç·Øî*w™ÅM/ýPK Aè2 Á=org/gradle/cli/CommandLineParser$KnownOptionParserState.classÝXûwÕÿÜd“ÙlFMH²yðbÚ˜‚6 6ñÁ°;n63qf6 ¾ÛZmëûQj”jikR Uµ­‡£çôôOèá¨ßïÌìn’]ØÄýåÎ÷~ï÷u¿Ï»ûÕ×ý€NL‡ÐµŒ–ý!„“!1ñ’àeˆ—LPB2ˆa F·Â AÆCa•ÆÃD©0ÊÛ1 ‡BX…'ƒx*„<Â3x–Ož a7~Ê„? âçŒy¾à¼¼ áE>þ%ÿª¿Æó^bÖ—%¼"áUÙqtÓèw,ÝHHx0;gahÛkšÕ“Tm[³Ú#¦•hOXj<©µÇ’z{9<¬ñˆnh»TËÖ¬ºÙüw ”zn¹«ÇCÔå±,2‹«">‹‘XJlGu4 o·gB?#Ú Û:‹žMU“)¾eEä€:ª¶§=ÙÑm‡ÎÊúõ„¡:)‹×Í;Þì퓪‘h÷ïÝÅâœ!Ý®ë¸þÍ= ˜z³nèN—À—…É…ž/ìèÅ9³i@ ÐcÆÉ[˘$šÞ¯Y»ÕýIÂTF̘šP-÷>2ÀÞ¨Þa˜c†gÕœhn*l@~VòmÈ4º­DjX3{sÃÕ´ØT ªy•¹â–aì`Ÿ:âßn)ÇBµœ¨6î)‹Ö¹4¡9ÛT;{“âÆ¦ÝËçHRc/•¸)L•`:CšµÓ/=yÄ gz›“`9Ñö³B›Þ’ð¶Àÿ¾YY˜z½›¹E㼬祓— ¼läå6.ÿˆ¡¸ô›)+¦mÕ9þÕ94mœ52ºð›qC¿X‘í,Ý–¥âöÂG‡e܉M2šÑ.£ëe<dlÄ2úh¾¶Mé„Ù2Óü Øà·&é\ñ:´ÒPo7(qS³ÃtG=¨)ª¡¤½Úb6Ñwî? ÅȲßâ6oBÆØÜm(Úðˆs(挩¶2b™£z\‹+™–»†ê6 Çd¼‹ã2v""ã¢2N"*áw·tyŸnÛ”U^æÐ•ý¶Q•Ï6ÿž¤FÍïb¨ŒS8-á=ï㌌?਌ð¡Œ?r$ºúRIG§z̈¶•1ÍÒ,ü,þ$ãÏ|ûpnŽ×½Â‘qžþ1þ"á¥PɘĔÀß± t.°®ç0-σk]TƒhYLu ¬[X[£–­²^G³TÇ´hJ®j†ÂmÐï!Ôœi-¥X«Ô«7å™:{#ó ŠQžaR•ob±ð¤f$œ!WW/͇¹¯B«ñø<î´š•4Nº“Is,3QhüJº½…ë÷ºiåÝS`;ŽêÀr5Ól»nýÆêÆ= Ö•éy<9ÿR9B=rZ:OÉãøÂS+g°_k¼Ò£ÇÖŸ`ŠÿíYÙØ”ûú¬ÍÄ*Ý\fÅ,¨gr¸zs:·I€4¤Úüö •†ûYÙØ”›ìôx<ûÀIí}–™Ù£sš-Ÿ#½_c†%sÄbiÃæh¦Ò꯶´¿ Ð¯0ýš*E%8‚*yʹ_tî—fû¥9».ÂÝ<<]Î"ž¥tòCÚF1a€–pó$ŠÂbÅá‹ N£d¥á–IHáÖIÃ5I”…k:ïJì¦u $@AH¼ƒ*qµâÖŠwQ/Ž£YœÀ½D³%,=ظÛ]äBly± ±íbëKȺ­¸Ï·ñ$iaúhx åG°ú"äÁÊ%ËX:XþRÿ,›FÅß›§°<}\™{Lpió Va ZyŽ$»·¨eˆSÄi²þ}¬gÐ%>@¯øÐ½Aµ§=sƒ(¶¡—lÛNpEk×¼ßÚ}„ô­'}Á)TM †5Ï Z`K.bÕ »ù†ssXÊŽÕ9(âcW±ì òowi…BHzÈøÚ:éËDA_ÛÙLlJOв‚‚¾ ÁÏ_¨ä[öûöíf™ê9²&¯#ËxµžÖÕíFz]Má&Ø8vÁštPÖæÊ ]}-3¸™ÕVp‹À§¸5ÚÜ:…º3ßü×S?C‘ÉÒݦkˆ²ADÚxæ›ÿÊ:µ“nq +ÄeÊÇO)ªŸáQñ9ÆÄôTÿ&Ä—8&þ…KâßøB|…Š+®¿Âä“·) wQœ‹q‰ªÄ=org/gradle/cli/CommandLineParser$OptionAwareParserState.class­UÛnÓ@=›¤qâ¸$”6\Ê%¤)MÝKÚ@)½p)E¡ E*oÇÓĮօOá xá$ ˆJ|…˜MÝ’*A./Þ™³çŒgf퟿¾ÿPĽ8È©Ð0*w×TzŒ©Èc\…Ž “*L+(¨ˆcVAQÁu†„á4›Ü®•,ÛdÈ–Q/Ô¯5̂Ѱ O¹pÍÚêÌCÔ{i¹¹™è\û èe˶¼; óÁð`ùñ CdÕ©Q²IéØh5«¦xÆ« ò ”ƒ7*\XÒö™.Cúɶg9öʾZÙãŵuÛ6Åjƒ»®I¸…À,s½™è]SMþ¶j’%¼} ÃP¾ôŠ¿æ…·ë…²',»¾4þœ!ÌE]&ܤ–8ö†c$Ž${¿]pÆGÓì§±õ˜oûRËNKæš%t×éi©¨!‰”†Ó˜ÓÐSnbXÁ¼†[XP°¨a Ë s™¬¼ðL±f ×+·ª~˜a°—[ªÝf˜:ç~½¨Z§)9höæOØS†É©­‚» cÁsž›mÏqÌrºœ |ê¯Õ¼ñ¯ðFËüËdUº©ºÔ©áÜ0L×ÍÍÍÐ-=ƽ”»õ_îïqk³Þ¥vr®l0.’¡Ï¥FÒå|©”œxò„¡!òJ„ÓšÒ'vÁtö!}ráOþYÐYг,T6‚$Ëaˆ|iŠÑZÏíÔç ûÌ‹dKTTŸø‚ȇC¾(ÅÁò<ÑCž(.âÅ.#ãóì ¯*êŸ&ª>ZÙ7Dß!½eSZ2B™ÇÞ#¹‡ø¦oªÛo+5UÉÀ¦cÓºÅCÝ¢¯{•ö B£*^ÙvÒ#8G«Ni$èy6¢˜Ž+ùÿÑ1Eˆ8­3$r£]‹ØoPK A˜%àÌ»ª7org/gradle/cli/CommandLineParser$OptionComparator.class•TmOÓP~îÖÑQ:¯ ¾€ Ý ƒ2@Š.Ñ,YÀd†Äe4³¤kIÛ†?„/~#‰á³ÿƨ_ç¶ N6).]ÏË}Îsî=çô~ýõù €E”%d0#¡Ÿ¿ú0+bN‚UÂJ"E,IHs;'"V8|UÄSk"Öz6LÛô7’eA(;íªi;­æ¾á¾Ñ÷-ò Vºníé®ÉíÈ)øïL!»{䛎]všGº«ûŽË WlÛpË–îy!–ªŽÛP®~`jÝ2UÂ6uû€§y­»žáN_åÐÄz`Q¢W…kÂH-¡TˆÓ ôÃT|À%|‘ÎÚ4yÔ`õP?ÖUK·jÍwM»¡…kÉÚw÷º¯uz”Š-ÇÖ¤¤ñž$Þ/0LßÍÐ[3¶î·xѪÿÚMË7-õO¥7â ±IÔRÍi¹uã¥É;?Ú‘~žSËÈb@Æž‰ ™Z½a×ÃB¶ÏÏh÷Οñ\ƶið®ö‚a+6eY÷ŒŠí¶gúæ±Ñ™{"!c /&ãªÆqã ¥ÿý¿vŽa¸[ëhŠãÇ‚Z×0ü0 }‹¥m j†¯]{–…a¤=¿eÑžBº$Í>•½Pí¶Þ}à4¥s2¯|=ѧÕéQ*t±e躣KŠ.@ >rd ’¥’d$S3gH|$%!z÷p'û†aÒå€Ü!Éx‹¢àD–"¹2{Šä9„·ì ©Oè¹€¸Sìp­ çHs»wnL8…tr™­I"þŽ!öyö3Ⱥ2GY¹v÷‚¬à>i<2‡˜ Ø<l’4!»M»{ín•Vˆ™™Ù ôé ùäš#fÂdYþä"’5’‰¨>¬{}FCÀåNS˜Æ#ZOâq€Ï£H·INQÍ2(RÔ8éô˦ÉSÄ<Ùi’Ëÿ PK AäfC˜§£8org/gradle/cli/CommandLineParser$OptionParserState.class•’ßJAÆ¿³Y³º¦ÿ4Õ¶Ö¨£×JoJ¤P¥… …H.¼›$Ã:²™•Ù‰ø }¯/ú}¨Ò3›€ˆ…4»ß™³ßùΜýýçá€#ÔB°ÂÇF€ÍUBñXie? õ½Áo¦}IXl)-O‡ƒ®4碛pf¹•öDÒF¹ó8éÛK•–ή­Jõa2iÚVXþTú®µ4ÍDd™dËÇVjâ(6¢ŸÈ¨—¨¨™B÷]ŸQ]í¤AXH5‡ÆžÊ[ûÅĶóOúÖ÷&£ŸBÃT3k8ÚNê­+q#¢Dè8j[£tܘš¸KûMdT¾Ì‹¼W^'ÒÊÛ„Ýúdð‡†[ƒw{H¨ý›»´Ó¡éɯÊm¤òÌsàÆ+aÅ;„£é÷@(?^ÑY÷JöxÂ÷Ó\a{ò(„ê$“_åÿׇ{ŠðÜL |ŠX‰ufÿÞfs'é'æ8. ñðygXÊu+¹®âe®—/;çÚþ‰ÕÃéßðÊÈ0‚çÑ:^çeorÿ[nÎø}‡y?Ä"k™õ•³—gÿPK A¢Æ÷E«¶3org/gradle/cli/CommandLineParser$OptionString.class•TÿNAþözåÊq”ZDQ‹´GËQÄŸ kLŒ&(ÿ[®—rx½kî£âø/$‰&>€ï¤qv[l“B“ÎîÌÎ|óÍÌîýúóý'€9<éE?LÄ´Ž4ŠB-¥0£ã, ³:4…( 1—Âmá;¯á®†{ Ö²ËÛü#·<î׬µ8týÚCOЈÝÀ§Í¢ë»ñÃT¾Ý¯ÝRXgP+AÕaXv}ge§¾é„oø¦çˆLͽuºBoÕxËŒU™° Cê ßwŠǣȡSk9kV-äUϱlϵ*A½ÎýªHñš‡‘æNÆSéš?s£†Ç?¯ð:幘/t*´-æö‡W¼!éh¸ÏŠƒæ±† /ÏTww~eÙåÓ¬e!ærg‰cèã¶íDQ®ä¹ŽÀOE„–;McBÒ»…ÛÉ-Ü!¹%Œá.ÕÌ"‡{ä©äN'Möë¬zz‹ÆÇY%¼B65[ümŽ~çèkÿE“T‡BZÆ“q‘5²<”]/h¦¸äŸÀ}LѾ‚>‡‡‘ÆM²c”ïGÃäMHxº¦) ˆ±ïPK A`M~U¸2org/gradle/cli/CommandLineParser$ParserState.class•SßoÒPþN) s€ÛÔ97Õ½Œ&MLÈf‚ÙÃÞ.а.åÖÜvFÿ'_|ÑÄÿÿ(ã¹-›Ý Aš´çG¿óïœÛþþóó€´mdQ³‘C-Ç6êxbaÇBƒ{áI/zIÈ4šÇ³Œ\ÂjÏ“îáùdàªbàs¦Ò †Â?ÊÓñ4iF§^H(¼*tU?'‹ï¤tU×aèòËv/Pcg¬ÄÈw¡ï9Ý`2r¤;$uõTy‡Pšˆ/—#}Œ¼@Ö½3ñI8¾c§)OŽ;ÍBÞ / ¡ÆZå Ž°È›…&¡œøWtŸÌi2§íâqf¸YC!‡¼ûzÞPÚ•h&ß—ûP2£»e²»gÆv¡nÓ‚$Ù$T@|„*>AŸÑ%¾ W|Å):ËT Ð3€¿â‚Â_qIÅ_q3!ŠžÅ¹ t–¯^= xÎc @椚ÙCäÍ!ð÷:°Z_ eªàYòÊqà>8YM¨ÝHÅEÿF‚Ÿw@³@9\"žÙ!µvÚC”œzÀ¨1‹ø‰vñ«®¥x••&Òƒá€k$}ËŒfÇö!¶uõÁÇÏTsj]Åp9Ð9†+Î1Œø:ó*…4ñ*4fEù!Š´“æ¿Ëœ¦./1YœŸÍ ®‡µ?PK AdZ›Ôl)&org/gradle/cli/CommandLineParser.classYi`\Å‘þJš™7zz¶eÙ²=`láë–1¶°åS>K6–±‘ÌXz’Fψ™¶8B¸ÂŽŽ``‡‚¹d ÙM¸ÂÈîØÍ²aÙƒ=€ !lÇÇ~ýÞ›ÑÌè‰üPwOwUuUuÕ×ÕO¯{ö€YòT:ñ±jþW5¿×±Ÿhøƒ/>Ññ)þ¨sú3 ÿ§áOùø >סã yøRÃa#ñç|ÁÑ|ìÇ1ÕׄW‹ø%GÇÉÕÄ£c¼xýâS¿5ÕøEžŽ]¢û%_ͪ¡fFúeu‘¿ŒÖ¤PÇt|ÂeŒ&cu”࿱—qª¯8&¨& œ¤äž¬š‰JO‹ï”|7#ñP"t‰™M$(°¹ÓùÎL8?²=ݱ×cq3Ö”&LMÖsÇsO°¶A0ÚeúAQC(çÖöj]¬ÝZ¢-um 3fÏÆ5iŒµfÎ Å≦îmÔkG0ÒJKͶhÌÌš×dcÊu;ƒ13cßM‚üŒ‰ÍÜ0Ý[‚1«×¬«_ݸµ±®aÅÖ5uëÖ­XÛ(¬ê ^¬îN„ÂÕ1³ÝÜU½&˜ V‘ù‚QQ[Ù¥=I£Ò¨‚]¤Ék µG‚‰î-\‘¹ºÀþFÚ«móWEcíÕí±`kجn ‡ªÛV…"¦­ìüE”9:Gw6„v™­Ž»Êú1Ö|ÆyqeÌ41ë×òP<¸-lÒ‰¾¡H(±H[RÊsô,‹¶šJîÔØ½c›[§…«¢-Áðú`,¤~;“žDGˆ’§|…º¶³©¬·Kg–lloi¶‹­5M%ä· ü¤9.bˆI+vµ˜ÉÐÙ"˜[’FUÏóRŠo;ÃRØñ¬`öFNç”â3#­ŒmL=ƒ šŒ4åPõ%$Ðl¢ÓÉuöÎ * cÝLate+ïr"n꣓uUC›—iظ̀èéJ…›Ç]B\ð kÙΰX5¹P°jØìÃ:ÄÉ)Bˆp(^H˜i%ƒ¹…¯n ZÍükn »‰Ý’É_>N¶§¢‚ Ïœ&3A†32g R4ìÑd«Š Z”8?lçyÒO¤®«‹m'áˆf@çØh¬ÕŒ%sÆžUÊuÅÌ6ë’3iÊ­ Å•¾¹ÛÍ¢Ä%Áp77õš‘DLý^a÷E™9ÍšV\ÑEW ™p¼ vX8)â¬ä4iFf(Må¼aú„}îŽà.ÁÔl?ºFò´,ƒN@6ßÍ 7üwåž3ô½á§ÉEš5ÙF¼îŒ†p JÒ-‹†Ãf‹n1íR^¢¾:ít[½­“BÞY‹ñÔ™dïÁ3‰›©R÷­»­M΄A-µVÔvmê‚ϼ.(SžYìn‘Z¦Q_;¥S™©[ZÌx|Úœ™3ÓK†FR^Ñ9»fpÎUœg ‡sPY‘1O‰ð/ ›}›ëMÑîX k#…ÈãIªRr ÜŠ[ Ü€ ܬFßÁíD¨-Î Æ;¸&-†´Šià{¸OP<ì’Á´1¤MÚ¹ƒt¨†·\Í×ku§¸;5ÙnHXv‘¨!]r1%ûð ‰ Ã0§²Ò„t *‡Ü1½ðT]BØ­¬ÜtáÂ-å†ì”¸!»¤ÇKå2C.—+%‹ã¥Ū2C¾!W*¢or•\Mx´ÖÕ²ZÅm¸…UŒ3W¹¥ªŒqŸ\ÉêlE,rRzüà´…[UÆíºV®3ä[r½!7(GÜ(Wr“|Û›åjCnÁí†Ü*·ò%*ûÜŲ!·ËwYX¹À¤Š2Îu]Ì4y®‚Ó‡Y <'”kïP͆Ü%w't°3²ÝluY9LáÙC¾'÷d˜R‹{23$*Š ¼ƒ0d·\/€!{ä^C¾/÷hrŸ7å†ÜŸÅžkCPáæ™ŸɈ: ù¡\lȃò÷™nÑEñâbÅ`ÈÃ*ÅÆ¹c&{ý>Vi%±¬=f Ù½ƒwbª¼eic›^ÏRĉ^ÒÉw÷w¶`Ö× „OðFŸ3<,ôdn>g?Ü_çy2°Ï|ô—Ÿ˜Þ%õ €Áz¢Xç>"£Nd1ìV“fY72³pLbÊh1s}Á¸½6=£JqŠ®ÒÁÅ´Ï*£É9¡¤ôDuXàU ªëÇ»?›¹²}eÊг¡›§[»Ö‚eN(åóqæ%ÏB=—:‚ñFsWÂú®Áz˱~Œ-)u+Z v{¶©—p,‘|”•¸”ƒÕ{þâî`8žE< ÔrÐ_n¾ÆÛ·¥Cc^¼{[܉բ’z×v„ ç46º˜ð—<[]¿kŒt6SN¶¾oÌÆ;:낊´š»ÔƒÚC“êÕqÖ»›¦[àc¥¡`©ÛÑ|ݽóÛ(~®zvú‚V†7\eŸ £"šzü–¸ª>²ÝL°žP_·k¡°©pÊ6#í‰+Lé€üh¤1I`E™4c…Ò/·]AËin±çع¼™<í±hw׆ڧ0=ëÕ—g3†Nj'"³@#yëYk>nV²0=tziÎH_û»…ò×r3Þ %?~u©'þ\“‡éßv³ÇBä‘‹ Aå ¯Š7ºÝo}m°hüÜ~½ý ÂÇ¡öW„‡sú Èé_&º%î@,yÛÂÝñŽäÅ‘å<ހà MçÙ<ïkéš³®àÇÖ­²0nGRZÕžñA<[1ëQ; hK½&§i13|d³7ØLó]$7$åJ“¦þÙAÈh5㡘ٚz=©ïæ‚ÖÂè´ž¿_‘Ó.Ÿóq*:±€'©ª—£õF†à&kümþñ¹loU}Áõ²ãï¤ášíwùkr9ârÙxÊúám>ß3ÈyÂ⼃­Î˜æâNŽ ›wánöWñ¹})”¬…ìm^YùAh½ðïO ñYL+,ãl"G€íÆ®ß˱‡ý÷ùÇ7<£ÐÜ7hb>Åxú‘×ܽ¹ìiäô!_pÆŒhèÇÈæ² 9€Qå}(à Âðôa´`·¼®F…‚¿Â˜ZoeÀÛ‹±»å±€·°¨ãv£ ã›ë„Æ}r§½8i7N"eÀKâ“{1±Öðõâ\N‚IAUÀ[°°“k|6e)Š­Ðüå¹Èâ=•Lg“iŠÅtªEëñ:¤ðúRt“ŸÄÔ=("õ4RïA~?¦ó(N{,$ªõ)³¾>ÌÈ¡»Æ)Y>gGK;¼åÈ®Õ,JÍ¡¼ª²%TZXÖ‹rE\Þ‹ ÕO¬õü½¨Ü€?i.UÁMjºªÑ[“W”§\Vý æÒ*þRv×ê™"uG¤žYÕxmžì;þâ>,¦.’®®³¾Ó‡ÒKéÖ‘ÍlÜwlfe/N¯ØoEˆŠ§'QÁöÛõb¶ãô Wb#Ó`cm3Æ< ñרŠ_ã"¼KÊ÷° Ÿ£ÇÑ*#`Êx´É)h—btH):åLl—&„evH'¢Ò….¹ËMˆÉ^ÄåQþ~;å9ôÈ˸TÞÄ7äC\)À5ò®“?ãz9†sr˜–*öÅhêåÃp?Û»0à‡=ŒQÖœFÍ {•ºØtw›‚ñt‰c1~DŽÌÎÁ†k½ŒûßUôaŽ ±Ò!Œ¯t0¨F!SE/ÎÜwüƒ²XžÂSýá'æMâ©Íd_ø8ç¼ç¾‘g¦ôMÍ'¡Ð9Íóø×K ô(=SXº-,õ3úð,-Nž¡=ÓÏu†Sá9ÎPôièÔðœ†çÙ Ýñ¦Q³ûc"™áÛ%¹Ïp;°üªs›Ë`q·–x<¿™ð¹à6V¦€¹‹è‹~,¦ï–Ôz*-wÔü‡¼®FŽG|¶˜:%f)ÅXJ¨X–²œBV4[J^ Ï‘²^l×úT{À”€ß œúp…íÃäå¢ÁËÇ÷ü…gÄ9Ü…*Ô+±/#ß’½ZáJNxy½çæ*ú™ŒuìR6+í|*,í&©‘£VäUÀV} 5^ƇbiÌÒ•bY­¼Ð‡5»µùÉ…çyžÇÚæ\µÐ$hêÅ:4¯"iÏù4¥ˆh¹¾pƒm”7ƒ¼ÙãH´ßÌ8¼à‰T ^ÊÈRè”Çx 0ÓK%³°k˜ŸAæg„鵓r7sä~ÆÝ!ÆÙo_ÿŒçðžÇÇœ9Ì`9†Ÿ‹Ž_K_”¼$³ñ²,Á+² ¯J;~);ñšÜ†×å%¼!¯âMyxw§•Ø#){9í%ÊqÇGˆÒÏ2wR»ŸãŒÞ0 /r5{‚—,º5¤ÙËðqÃBH»\ˆ—‰ƒš Öd^pôK¼ÆPΓñ7xY§ñ+òçb–Ü‹7X:y¨ñóx“Yçµ²F园ɯSšü-1ÍÞáï8gËèOÉø{zSe× yµNv½¥a®•`¿aZx¼úà 5Öøm‹èCãd"æQL´ðtLîq:ɛŠeÍc%,3w„…Çä]}sÚêê²Sž}ÆÞÇ~e?š2<‹Ê_¯p媲>lJ¯›0Ý©›j½§ìA^Ãió† uoQ£ÜEûŽ¿Ãø¹pê8Ð~?ÞâžoSÑw/¿å-ýOijw‰g¿ÃÞ¶Kñ/´ÿýžU°üGÒy•^¤}×B±•Œ«‡,ÌZJ¾÷,;–ó–ô;É¢Ÿ½òøxŽb´†f9Ír¶öKêaß2ÿJ|ß‹sð=ijSž8TÞPqhQn§ÈsʃØYQä™Uëµ@Ýë”O~lm.¼ÈI=oÓA`‹2/-ÉõÖìõ'a*oµõ¢}CÓ‘Ms­‡wÅý¨iVÕò„*,ØK¿:&U¦@Äcéå©HbÏ{V5”ky¿†E=ð!Æâ#Þ&³Pÿ==÷ k Oц?âr®]?1Ë>gŽAäù’y{8u cÑaÝ*^®Ž°òHÝ*‡R·Ê!çV¹•g©ò-y‡hÇà·.Ž#¨f€N>Œ©_À{EV43$§øñïøçf®f¯N¹8÷Ѭ·Áœ´;ÙËlçÎdþOü— sNöÃÂù¿]w–aìÌÈûŸÔi‰µ ;{±g<¹Oajaø v<sð[©€Gò¸%.ÇX"œüÐ"ùQ kGOa©XÇg\Ÿp³±ŸÏ>Î>Á¾›â.a¿“œ»Ø÷xtòvâ2Îg9û+؃ë#Ù_Éþ›ì¯òäð´;q é¯eéV)^ñåý?PK A‹å>É&org/gradle/cli/ParsedCommandLine.class•Wiwg~FÛÈòÄ‹ê%v“TMc[–å’ñR·Ž›8¶SâÆÆ)-L¬‰¬TÖ(£‘·”.PhÙ¡liÙ7 ’`rX¾Áá;ßøÆŸ œœ˜ç}g$KÖ¸1GçÌÜ÷Î}Ÿ÷Þç.3úǽ?þÀü.‚v˜*òø`Ö!‰‹*¬‚΢ .¶ŠbuŽf¹¸T“¸,.+*žWñBM0#hÄ'ëñ".©øT=^ÂËa¼¢âÕ·}:‚|FÅkt ã³âþ¹0^÷7„ÅçÅÎ/Ô㋸$–__Vñ•0¾A¾V¯ãMaó qù¦¸¼©â[ ͼ1s…#+3¶•É¥©™¼ /ëE;“˜Òóà êf2éœn-CÁÉê§#Î2«çÒÀð¤i¥Ò–žÊ ÙÌÀ“ºU0RãæÒ’žKMfrÆ)yâð(‘ò–Q0r¶£*T>cØ4y¤Zãq ²Œ%sÙH•ŒË¶¥Yéâñ©hªÀ™Ìô¾Mª-°C#™\ÆUЯ08a–~.k ÷Î*Œ›)CxÏð¦‹Kç ë)ñLAtÒ\г³º•kWYçpÎ#„AÍ™ ´¼äÌ FA|»”ÒWÓݳwó/뀽˜)xØÖàÓV5KÔ¶x±  ­:Ô•|)ÜÃö#÷wOP¿cÆÖžcI(ßVñÃ^yØ¢ÈUØ6K¥Þïõ¤ÿbÑ´±\jÂÌú½Óîµ3Tp‘UG(ˆŒí|ÑVÐQ³áH1“M– 7S8–± ´RΊ|{…çY›#Û¶õô·nQ/”ª¬5^kÑKošu·O;=F‚¸m,·RÚÙ¯h¤q3›5$ßbwcÖLOËF¶Ü™mÞÆ ž¶¼ßûLïÐÏn"ªÝöûª9mØG7M”h©z*gJwr‹vè©”DœÕ³Ec úY®ÁeçyíK„?ëa{ÿòÿ?ÂÕœqZ:¯«fy Ó×ÈŒY´ŒcÑöm5ðû…Óã Ý é¸^Xd‹kèÇþšùÞဂ6žŽY–¾"Öð|PÃ[x[Ãwñ= ßÇÄîç1sµ=>4ü?Rñc¶ÂfÖUüDÃOñ3Ýñ8ë*$cÕ/GWý†º*ÀSç.°„5œÂ“~ŽU¾n¶˜ |ɘ†_à—=¦0­a ç4ü WU\Ó0³~ßp´WLöHZÏ–¼:zyÁpyØéøëé*ôÄr¦Kç}j¿Ècü­†ë¸ªážÑð®Ö’[û£v.•”2}Ri›ŒÆ—c9SV´UõPÉPŒIÎir+÷°©9¹¨ã‘´Ž°gËS§¹ Óù´ØQ¥¨Z³yˆœÛ‡ãµàµOBçMkI'Æ GÃ>ýÞ ï=Ÿ7r©‘W=¶~©„Ìœ­gDô­1[¼f(O :º½6y…ÙP=𸟳J8žJe³œÒÇÃü2mç‡sQÑëP0À•ïãš-^^äúЦ5[¼¼þêy?ŒAÊC€2?TjÞH܆’¸ßümøo"@1H1tꆦXG1rõ}kÐL%×°CÁœ¤Ð à¯hœ¾ƒ&Ú4úo!º† ;‚®]LHÒ°e(”ø=¡ŽÀZý˜[]ÿ×êú;7dÃò?‚Æk'W­ü¾o£ÔÎÏñ ùAþØ…ì†=xá5Äð:IáŽCüa£b!ZÀcxœ(DÃÌp1Ž')Å1ÒóaÊïŽæ8¥”÷!°NÎü*’*&TþïÀ=t«hTÑÄÕÐý_éP;É=œ'¼’XœáÙ­/ÚúÚçý F«ÞÆÎ™ù€ë¥bXˆ@Çu #Bw¶vÉp§ú\‡}bÈ9¹Ã»¼‡x?}düÁ©À¨“•¡€àTò}HH.ßÁÝo!’Œîº…ÝsÉèyëV¬ü£«ëOÞÂC×ËIØ/ë¥a$¡qÖa’xA1c¬¾ã¤x‚š)R_J@{ñ& (ü+“}š?Av˜ö3xŠþG¸û f™”«97­ðßCTE§Bºï"¦¢å]t¸Œ”Fœ×.ã'¨ññޜ軅؜ ›t<ìõ2¯i Êâ1éi›³¡ì_3ã%œ‚§ß6ì ;AØ“÷ýžq“÷6ïA-ÁöV4Rg©‘Z¦l G® ¸¶ºþoÿµrNÚ$«gسdyŽE:ú+ŽŽ‘ÉN:$ôËÌ•œèųøxU¡ Í'\ž5øïB%Ç»6 Zç3¾]^ᜈ¢kéô>lšJþ ;ï k>ÚeÞ'*ù6zþ’Eä—Ge¤)ö¤Aù<],;[í¢ÃS;\ô¬Oº†r=l8>Y ŠÃ߀äŠ^ÚÜ9ÙŠÎ ºðNL¯ç‘vczÂÍ­&@S܇¹›Òšg\¬H«VvWc£òŒ .¸ˆ97­{ªXšŘ”ã°—GôoøÛ )ãªÈ‘¶,ÏI8åsöÈQ¦HI 0­›$AbïsŒÖ9ûŠ{ö`_ið–«*^QUt¥ Õ ¢š¹èó‰ñûÏåŒ9%ö<'ì tçE¾B^âKãårÖvs?ê–Ø`ÙÑAé^EAEXP QP –dȹÿPK AyßtÚE,org/gradle/cli/ParsedCommandLineOption.classS]OÔ@=ݯîGeùPa„eQª¨ø"ˆhHV1YƒÁ·awR»í¦íá§ðl⋘¨IÔg”ñN[`Y$ñ¡Ó™Û{Ï=çÜéï?ߘ“4²(ª˜H#‚b ¸ž¦å†ŠÉ$ô4¸™Á-L%q[¾ï¨¸+ßÓr¹§â¾Š [ÌlpWA¶´É¶˜Þð„©—„ëÍ(H•…a1¯áp#-Ÿgƒ³É,C/{ްŒ™9*IÌ Kxs ¢…ñU±E»JÅ%añ—Ú:w^³u“"¹’]aæ*s„<‡Á˜·!ˆI¡d;†n8¬jr½b ýs\^]´k5fU%ÔJݶEí’÷V¥Ý…ñ³”´•=Vy÷‚Õé£ j”;*i=z&xŽÔ «V£Qã–§ §p6K:dÇ)¹ñKn07T@–½U.Û §ÂŸ Évàé“ICzt°]p¶-)kèDNÃ(Æ t]6Mn0“,ñøÒû ÷±(#ÍWmîæ-ÛËo°-žgÖvÞ¿“²Ñ°Š‡f0« ?L'æùZÃôDÝäA¦K©@Ó϶*Õðó$¡Ñÿï)”•õM^!ÛO†îŒ+vï–i¥áÊQ,7_… ”¬ŽÒÀZ~“¾«Â]ªÕ½m\¡(K? LºHï.:EÐ8íÉrZ/PdQÚÙâ>”â!"kûˆ~E쳟}‘Vù_‚*bTÓG;-ÈÇ%ôûø¸bí„XÓÅoˆï¢í‰µœºäÏâÄ"¡Âpú(=@&‚_Ðö¨2êwì%Ž ^*õè$üAêPÀPS÷é°û =1D:¥š!䉩ä¡ÓIfÅ%þÞ±„n‚‰‡05W(v•¾bžRD ×$ÈÄÚ"xÓjÊ2D¬Ï§ìç†xr7‚k> º½!âóV.p£]Á.ÔØG²àÓ±ô€ãDÇ\“Ô8"Ùy Rð‰ŒÿPK A\vÆB| :org/gradle/cli/ProjectPropertiesCommandLineConverter.class’KOÂ@…ÏD|?PâìÀšuã#QŒ+¢$÷C;–1m‡  ÿJW&.üþ(ãª1ØDã,îéœ9ßôv¦oï/¯ö±[@yl汕G)‡ívÙ }FHWkw„LSºœ°Ü!¿]®nY×7ÎZK:Ì¿cJDóØÌ螎ZRy¶§˜ësÛñ…ÝVò;ÚHŸ+-ø )ƒ€…n´kS†#cruLXõøgh|Ó×B†„j­õÀFÌöYèÙ­Dè™èÎè%×LøÜ%”ÖŽñŽ…Ž*‡_‰¨å½?õÖˆ:("‡<Ú„bJÕö ®­ØŠtòfë^*K÷¸Õ ßµ¦ XUÞðV½Œ£Üi01Èk ÂÁp8ƒwZ±ß8T0gî?Pôa¦Î›™m”ŒÎí=ƒžÌC S³s ¦§£‹| Ë1\áôZêq-}CÓ_èJšžEˉèjš™E+ ¨ùw'©õPK A Ï8=|ü9org/gradle/cli/SystemPropertiesCommandLineConverter.class’ËJÃ@†ÏØ«mµ¶ÖjÕEÜ5BPÄ…R/Pé~šÓ‘$&ÓBÞJW‚ À‡'i©AÄYœ3óÏÿÍœ¹¼¼¾Àl— "l¡Y„Íl E Ê<&Ï dÚú@¶ËÇH ÚgÞLÝŠ{:r”Rïs‹:C*X4NĬœ°€ÀQŸ Û´;hZ3a ѽÜG!]îºÔG‹v¹7S"Š5eb o}ɸG ÑÖûtFM‡z¶9‚y¶²¶~X{()spL`7e.°KV, øTXxÉ¢Šõ¿”fDT E¤G ÄPÇWãJm®h~²­Æ49Aíjx­µÑ° ­ÓsÃhöÌ gÔ™¢n8üÇ5©Û] .FÔ’¿s°9õàQˉ΢ⲙ*•sû/@žUg J*æc±e+sƒÊ+1¾ Õî$p¦¾ô´€6¿¡™/t-Í,¢;©h-Í.¢Z ª>kìZÿPK AÿÃWgradle-cli-classpath.properties+(ÊÏJM.)¶å**Í+ÉÌMµPK A íAMETA-INF/PK Am±>=@?¤)META-INF/MANIFEST.MFPK AíA›org/PK A íA¿org/gradle/PK AíAêorg/gradle/wrapper/PK AªÙfØê -¤org/gradle/wrapper/BootstrapMainStarter.classPK AhQþ}¢Ò#¤korg/gradle/wrapper/Download$1.classPK AÇåî©L4¤Norg/gradle/wrapper/Download$ProxyAuthenticator.classPK A5¶<›Àœ!¤» org/gradle/wrapper/Download.classPK AyL¢¡Ê1¤ºorg/gradle/wrapper/DownloadProgressListener.classPK A!9|¶„ 3¤ªorg/gradle/wrapper/ExclusiveFileAccessManager.classPK Aì„,y†-¤± org/gradle/wrapper/GradleUserHomeLookup.classPK AÀ!lá7 "*¤u#org/gradle/wrapper/GradleWrapperMain.classPK AúâæªÛ"¤ô,org/gradle/wrapper/IDownload.classPK Ap@áõc "¤Þ-org/gradle/wrapper/Install$1.classPK AT¨,-t+ ¤5org/gradle/wrapper/Install.classPK Að¿:öo4¤ìIorg/gradle/wrapper/Logger.classPK Aon¶`8¤˜Lorg/gradle/wrapper/PathAssembler$LocalDistribution.classPK AJØâ[&¤¤Norg/gradle/wrapper/PathAssembler.classPK A„ÍëÂ| 0¤þUorg/gradle/wrapper/SystemPropertiesHandler.classPK Aª=©°?-¤[org/gradle/wrapper/WrapperConfiguration.classPK AGü¨ (¤ ^org/gradle/wrapper/WrapperExecutor.classPK Aã…Ð_#¤dggradle-wrapper-classpath.propertiesPK AíAÃgorg/gradle/cli/PK AÕÜ?®<S1¤ògorg/gradle/cli/AbstractCommandLineConverter.classPK A׃µ³Xì ;¤}jorg/gradle/cli/AbstractPropertiesCommandLineConverter.classPK A}­ÎyGK1¤.oorg/gradle/cli/CommandLineArgumentException.classPK A³ßâúg)¤Äporg/gradle/cli/CommandLineConverter.classPK ASf Õg&¤$rorg/gradle/cli/CommandLineOption.classPK Aü튯¥å(¤jxorg/gradle/cli/CommandLineParser$1.classPK A™ÐÆ­Nå ;¤Uyorg/gradle/cli/CommandLineParser$AfterFirstSubCommand.classPK A¥D£¢&3¤ü|org/gradle/cli/CommandLineParser$AfterOptions.classPK A¤ÇÇà› <¤ïorg/gradle/cli/CommandLineParser$BeforeFirstSubCommand.classPK A´*«ZMïF¤J„org/gradle/cli/CommandLineParser$CaseInsensitiveStringComparator.classPK Aè2 Á=¤û†org/gradle/cli/CommandLineParser$KnownOptionParserState.classPK A$ľ¢¥ô<¤ZŽorg/gradle/cli/CommandLineParser$MissingOptionArgState.classPK ATK>ªÄ=¤Y‘org/gradle/cli/CommandLineParser$OptionAwareParserState.classPK A˜%àÌ»ª7¤^”org/gradle/cli/CommandLineParser$OptionComparator.classPK AäfC˜§£8¤n—org/gradle/cli/CommandLineParser$OptionParserState.classPK A¢Æ÷E«¶3¤k™org/gradle/cli/CommandLineParser$OptionString.classPK AgAq²”x=¤gœorg/gradle/cli/CommandLineParser$OptionStringComparator.classPK A`M~U¸2¤VŸorg/gradle/cli/CommandLineParser$ParserState.classPK ApÍX Ýk?¤ª¡org/gradle/cli/CommandLineParser$UnknownOptionParserState.classPK AdZ›Ôl)&¤ä¤org/gradle/cli/CommandLineParser.classPK A‹å>É&¤>·org/gradle/cli/ParsedCommandLine.classPK AyßtÚE,¤K¿org/gradle/cli/ParsedCommandLineOption.classPK A\vÆB| :¤oÂorg/gradle/cli/ProjectPropertiesCommandLineConverter.classPK A Ï8=|ü9¤CÄorg/gradle/cli/SystemPropertiesCommandLineConverter.classPK AÿÃW¤Ægradle-cli-classpath.propertiesPK11gÆlibmongocrypt-1.3.0/bindings/java/mongocrypt/gradle/wrapper/gradle-wrapper.properties000066400000000000000000000003121414105245100312630ustar00rootroot00000000000000distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists libmongocrypt-1.3.0/bindings/java/mongocrypt/gradlew000077500000000000000000000122711414105245100226750ustar00rootroot00000000000000#!/usr/bin/env sh ############################################################################## ## ## Gradle start up script for UN*X ## ############################################################################## # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" # Need this for relative symlinks. while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done SAVED="`pwd`" cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" warn () { echo "$*" } die () { echo echo "$*" echo exit 1 } # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false case "`uname`" in CYGWIN* ) cygwin=true ;; Darwin* ) darwin=true ;; MINGW* ) msys=true ;; NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD="java" which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add options to specify how the application appears in the dock if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin, switch paths to Windows format before running java if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=$((i+1)) done case $i in (0) set -- ;; (1) set -- "$args0" ;; (2) set -- "$args0" "$args1" ;; (3) set -- "$args0" "$args1" "$args2" ;; (4) set -- "$args0" "$args1" "$args2" "$args3" ;; (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi # Escape application args save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } APP_ARGS=$(save "$@") # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then cd "$(dirname "$0")" fi exec "$JAVACMD" "$@" libmongocrypt-1.3.0/bindings/java/mongocrypt/gradlew.bat000066400000000000000000000042111414105245100234320ustar00rootroot00000000000000@if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :init @rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args :win9xME_args @rem Slurp the command line arguments. set CMD_LINE_ARGS= set _SKIP=2 :win9xME_args_slurp if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal :omega libmongocrypt-1.3.0/bindings/java/mongocrypt/src/000077500000000000000000000000001414105245100221065ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/000077500000000000000000000000001414105245100230325ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/000077500000000000000000000000001414105245100237535ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/000077500000000000000000000000001414105245100245315ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/000077500000000000000000000000001414105245100261565ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/000077500000000000000000000000001414105245100273175ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/000077500000000000000000000000001414105245100302335ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/BinaryHolder.java000066400000000000000000000026041414105245100334620ustar00rootroot00000000000000/* * Copyright 2008-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import com.mongodb.crypt.capi.CAPI.mongocrypt_binary_t; import static com.mongodb.crypt.capi.CAPI.mongocrypt_binary_destroy; // Wrap JNA memory and a mongocrypt_binary_t that references that memory, in order to ensure that the JNA Memory is not GC'd before the // mongocrypt_binary_t is destroyed class BinaryHolder implements AutoCloseable { private final DisposableMemory memory; private final mongocrypt_binary_t binary; BinaryHolder(final DisposableMemory memory, final mongocrypt_binary_t binary) { this.memory = memory; this.binary = binary; } mongocrypt_binary_t getBinary() { return binary; } @Override public void close() { mongocrypt_binary_destroy(binary); memory.dispose(); } } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPI.java000066400000000000000000000705031414105245100316170ustar00rootroot00000000000000/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import com.sun.jna.Callback; import com.sun.jna.Memory; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.PointerType; import com.sun.jna.ptr.PointerByReference; //CHECKSTYLE:OFF /** * For internal use only. Not part of the public API. */ @SuppressWarnings("WeakerAccess") public class CAPI { public static class cstring extends PointerType { public cstring() { super(); } public cstring(String string) { Pointer m = new Memory(string.length() + 1); m.setString(0, string); setPointer(m); } public String toString() { return getPointer().getString(0); } } /** * Indicates success or contains error information. *

* Functions like @ref mongocrypt_ctx_encrypt_init follow a pattern to expose a * status. A boolean is returned. True indicates success, and false indicates * failure. On failure a status on the handle is set, and is accessible with a * corresponding status function. E.g. @ref mongocrypt_ctx_status. */ public static class mongocrypt_status_t extends PointerType { } /** * Contains all options passed on initialization of a @ref mongocrypt_ctx_t. */ public static class mongocrypt_opts_t extends PointerType { } /** * A non-owning view of a byte buffer. *

* Functions returning a mongocrypt_binary_t* expect it to be destroyed with * mongocrypt_binary_destroy. */ public static class mongocrypt_binary_t extends PointerType { } /** * The top-level handle to libmongocrypt. *

* Create a mongocrypt_t handle to perform operations within libmongocrypt: * encryption, decryption, registering log callbacks, etc. *

* Functions on a mongocrypt_t are thread safe, though functions on derived * handle (e.g. mongocrypt_encryptor_t) are not and must be owned by a single * thread. See each handle's documentation for thread-safety considerations. *

* Multiple mongocrypt_t handles may be created. */ public static class mongocrypt_t extends PointerType { } /** * Manages the state machine for encryption or decryption. */ public static class mongocrypt_ctx_t extends PointerType { } /** * Manages a single KMS HTTP request/response. */ public static class mongocrypt_kms_ctx_t extends PointerType { } /** * Returns the version string x.y.z for libmongocrypt. * * @param len, an optional length of the returned string. May be NULL. * @return the version string x.y.z for libmongocrypt. */ public static native cstring mongocrypt_version(Pointer len); /** * Create a new non-owning view of a buffer (data + length). *

* Use this to create a mongocrypt_binary_t used for output parameters. * * @return A new mongocrypt_binary_t. */ public static native mongocrypt_binary_t mongocrypt_binary_new(); /** * Create a new non-owning view of a buffer (data + length). * * @param data A pointer to an array of bytes. This is not copied. data must outlive the binary object. * @param len The length of the @p data byte array. * @return A new mongocrypt_binary_t. */ public static native mongocrypt_binary_t mongocrypt_binary_new_from_data(Pointer data, int len); /** * Get a pointer to the referenced data. * * @param binary The @ref mongocrypt_binary_t. * @return A pointer to the referenced data. */ public static native Pointer mongocrypt_binary_data(mongocrypt_binary_t binary); /** * Get the length of the referenced data. * * @param binary The @ref mongocrypt_binary_t. * @return The length of the referenced data. */ public static native int mongocrypt_binary_len(mongocrypt_binary_t binary); /** * Free the @ref mongocrypt_binary_t. *

* This does not free the referenced data. Refer to individual function * documentation to determine the lifetime guarantees of the underlying * data. * * @param binary The mongocrypt_binary_t destroy. */ public static native void mongocrypt_binary_destroy(mongocrypt_binary_t binary); public static final int MONGOCRYPT_STATUS_OK = 0; public static final int MONGOCRYPT_STATUS_ERROR_CLIENT = 1; public static final int MONGOCRYPT_STATUS_ERROR_KMS = 2; /** * Create a new status object. *

* Use a new status object to retrieve the status from a handle by passing * this as an out-parameter to functions like @ref mongocrypt_ctx_status. * When done, destroy it with @ref mongocrypt_status_destroy. * * @return A new status object. */ public static native mongocrypt_status_t mongocrypt_status_new(); /** * Set a status object with message, type, and code. *

* Use this to set the mongocrypt_status_t given in the crypto hooks. * * @param status The status. * @param type The status type. * @param code The status code. * @param message The message. * @param message_len The length of @p message. Pass -1 to determine the * string length with strlen (must * be NULL terminated). */ public static native void mongocrypt_status_set(mongocrypt_status_t status, int type, int code, cstring message, int message_len); /** * Indicates success or the type of error. * * @param status The status object. * @return A @ref mongocrypt_status_type_t. */ public static native int mongocrypt_status_type(mongocrypt_status_t status); /** * Get an error code or 0. * * @param status The status object. * @return An error code. */ public static native int mongocrypt_status_code(mongocrypt_status_t status); /** * Get the error message associated with a status, or an empty string. * * @param status The status object. * @param len, an optional length of the returned string. May be NULL. * @return An error message or an empty string. */ public static native cstring mongocrypt_status_message(mongocrypt_status_t status, Pointer len); /** * Returns true if the status indicates success. * * @param status The status to check. * @return A boolean indicating success. */ public static native boolean mongocrypt_status_ok(mongocrypt_status_t status); /** * Free the memory for a status object. * * @param status The status to destroy. */ public static native void mongocrypt_status_destroy(mongocrypt_status_t status); public static final int MONGOCRYPT_LOG_LEVEL_FATAL = 0; public static final int MONGOCRYPT_LOG_LEVEL_ERROR = 1; public static final int MONGOCRYPT_LOG_LEVEL_WARNING = 2; public static final int MONGOCRYPT_LOG_LEVEL_INFO = 3; public static final int MONGOCRYPT_LOG_LEVEL_TRACE = 4; /** * A log callback function. Set a custom log callback with mongocrypt_setopt_log_handler. */ public interface mongocrypt_log_fn_t extends Callback { void log(int level, cstring message, int message_len, Pointer ctx); } public interface mongocrypt_crypto_fn extends Callback { boolean crypt(Pointer ctx, mongocrypt_binary_t key, mongocrypt_binary_t iv, mongocrypt_binary_t in, mongocrypt_binary_t out, Pointer bytesWritten, mongocrypt_status_t status); } public interface mongocrypt_hmac_fn extends Callback { boolean hmac(Pointer ctx, mongocrypt_binary_t key, mongocrypt_binary_t in, mongocrypt_binary_t out, mongocrypt_status_t status); } public interface mongocrypt_hash_fn extends Callback { boolean hash(Pointer ctx, mongocrypt_binary_t in, mongocrypt_binary_t out, mongocrypt_status_t status); } public interface mongocrypt_random_fn extends Callback { boolean random(Pointer ctx, mongocrypt_binary_t out, int count, mongocrypt_status_t status); } /** * Allocate a new @ref mongocrypt_t object. *

* Initialize with @ref mongocrypt_init. When done, free with @ref * mongocrypt_destroy. * * @return A new @ref mongocrypt_t object. */ public static native mongocrypt_t mongocrypt_new(); /** * Set a handler to get called on every log message. * * @param crypt The @ref mongocrypt_t object. * @param log_fn The log callback. * @param log_ctx A context passed as an argument to the log callback every * invokation. * @return A boolean indicating success. */ public static native boolean mongocrypt_setopt_log_handler(mongocrypt_t crypt, mongocrypt_log_fn_t log_fn, Pointer log_ctx); public static native boolean mongocrypt_setopt_crypto_hooks(mongocrypt_t crypt, mongocrypt_crypto_fn aes_256_cbc_encrypt, mongocrypt_crypto_fn aes_256_cbc_decrypt, mongocrypt_random_fn random, mongocrypt_hmac_fn hmac_sha_512, mongocrypt_hmac_fn hmac_sha_256, mongocrypt_hash_fn sha_256, Pointer ctx); public static native boolean mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5( mongocrypt_t crypt, mongocrypt_hmac_fn sign_rsaes_pkcs1_v1_5, Pointer sign_ctx); /** * Set a handler to get called on every log message. * * @param crypt The @ref mongocrypt_t object. * @param aws_access_key_id The AWS access key ID used to generate KMS * messages. * @param aws_access_key_id_len The string length (in bytes) of @p * * aws_access_key_id. Pass -1 to determine the string length with strlen (must * * be NULL terminated). * @param aws_secret_access_key The AWS secret access key used to generate * KMS messages. * @param aws_secret_access_key_len The string length (in bytes) of @p * aws_secret_access_key. Pass -1 to determine the string length with strlen * (must be NULL terminated). * @return A boolean indicating success. */ public static native boolean mongocrypt_setopt_kms_provider_aws(mongocrypt_t crypt, cstring aws_access_key_id, int aws_access_key_id_len, cstring aws_secret_access_key, int aws_secret_access_key_len); /** * Configure a local KMS provider on the @ref mongocrypt_t object. * * @param crypt The @ref mongocrypt_t object. * @param key A 64 byte master key used to encrypt and decrypt key vault keys. * @return A boolean indicating success. */ public static native boolean mongocrypt_setopt_kms_provider_local(mongocrypt_t crypt, mongocrypt_binary_t key); /** * Configure KMS providers with a BSON document. * * @param crypt The @ref mongocrypt_t object. * @param kms_providers A BSON document mapping the KMS provider names to credentials. * @return A boolean indicating success. If false, an error status is set. * @since 1.1 */ public static native boolean mongocrypt_setopt_kms_providers(mongocrypt_t crypt, mongocrypt_binary_t kms_providers); /** * Set a local schema map for encryption. * * @param crypt The @ref mongocrypt_t object. * @param schema_map A BSON document representing the schema map supplied by * the user. The keys are collection namespaces and values are JSON schemas. * @return A boolean indicating success. If false, an error status is set. * Retrieve it with @ref mongocrypt_status */ public static native boolean mongocrypt_setopt_schema_map (mongocrypt_t crypt, mongocrypt_binary_t schema_map); /** * Initialize new @ref mongocrypt_t object. * * @param crypt The @ref mongocrypt_t object. * @return A boolean indicating success. Failure may occur if previously set options are invalid. */ public static native boolean mongocrypt_init(mongocrypt_t crypt); /** * Get the status associated with a @ref mongocrypt_t object. * * @param crypt The @ref mongocrypt_t object. * @param status Receives the status. * @return A boolean indicating success. */ public static native boolean mongocrypt_status(mongocrypt_t crypt, mongocrypt_status_t status); /** * Destroy the @ref mongocrypt_t object. * * @param crypt The @ref mongocrypt_t object to destroy. */ public static native void mongocrypt_destroy(mongocrypt_t crypt); /** * Set the key id to use for explicit encryption. * * @param ctx The @ref mongocrypt_ctx_t object. * @param key_id The key_id to use. * @return A boolean indicating success. */ public static native boolean mongocrypt_ctx_setopt_key_id (mongocrypt_ctx_t ctx, mongocrypt_binary_t key_id); /** * Set the keyAltName to use for explicit encryption. * keyAltName should be a binary encoding a bson document * with the following format: { "keyAltName" : >BSON UTF8 value< } * *

It is an error to set both this and the key id.

* * @param ctx The @ref mongocrypt_ctx_t object. * @param key_alt_name The name to use. * @return A boolean indicating success. If false, an error status is set. * Retrieve it with @ref mongocrypt_ctx_status */ public static native boolean mongocrypt_ctx_setopt_key_alt_name (mongocrypt_ctx_t ctx, mongocrypt_binary_t key_alt_name); /** * Set the algorithm used for encryption to either * deterministic or random encryption. This value * should only be set when using explicit encryption. * * If -1 is passed in for "len", then "algorithm" is * assumed to be a null-terminated string. * * Valid values for algorithm are: * "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" * "AEAD_AES_256_CBC_HMAC_SHA_512-Randomized" * * @param ctx The @ref mongocrypt_ctx_t object. * @param algorithm A string specifying the algorithm to * use for encryption. * @param len The length of the algorithm string. * @return A boolean indicating success. */ public static native boolean mongocrypt_ctx_setopt_algorithm (mongocrypt_ctx_t ctx, cstring algorithm, int len); /** * Create a new uninitialized @ref mongocrypt_ctx_t. *

* Initialize the context with functions like @ref mongocrypt_ctx_encrypt_init. * When done, destroy it with @ref mongocrypt_ctx_destroy. * * @param crypt The @ref mongocrypt_t object. * @return A new context. */ public static native mongocrypt_ctx_t mongocrypt_ctx_new(mongocrypt_t crypt); /** * Get the status associated with a @ref mongocrypt_ctx_t object. * * @param ctx The @ref mongocrypt_ctx_t object. * @param status Receives the status. * @return A boolean indicating success. */ public static native boolean mongocrypt_ctx_status(mongocrypt_ctx_t ctx, mongocrypt_status_t status); /** * Identify the AWS KMS master key to use for creating a data key. * * @param ctx The @ref mongocrypt_ctx_t object. * @param region The AWS region. * @param region_len The string length of @p region. Pass -1 to determine * the string length with strlen (must be NULL terminated). * @param cmk The Amazon Resource Name (ARN) of the customer master key * (CMK). * @param cmk_len The string length of @p cmk_len. Pass -1 to determine the * string length with strlen (must be NULL terminated). * @return A boolean indicating success. */ public static native boolean mongocrypt_ctx_setopt_masterkey_aws (mongocrypt_ctx_t ctx, cstring region, int region_len, cstring cmk, int cmk_len); /** * Identify a custom AWS endpoint when creating a data key. * This is used internally to construct the correct HTTP request * (with the Host header set to this endpoint). This endpoint * is persisted in the new data key, and will be returned via * mongocrypt_kms_ctx_endpoint. * * @param ctx The @ref mongocrypt_ctx_t object. * @param endpoint The endpoint. * @param endpoint_len The string length of @p endpoint. Pass -1 to * determine the string length with strlen (must be NULL terminated). * @return A boolean indicating success. If false, an error status is set. * Retrieve it with @ref mongocrypt_ctx_status */ public static native boolean mongocrypt_ctx_setopt_masterkey_aws_endpoint (mongocrypt_ctx_t ctx, cstring endpoint, int endpoint_len); /** * Set the master key to "local" for creating a data key. * * @param ctx The @ref mongocrypt_ctx_t object. * @return A boolean indicating success. */ public static native boolean mongocrypt_ctx_setopt_masterkey_local (mongocrypt_ctx_t ctx); /** * Set key encryption key document for creating a data key. * * @param ctx The @ref mongocrypt_ctx_t object. * @param keyDocument BSON representing the key encryption key document. * @return A boolean indicating success. If false, and error status is set. * @since 1.1 */ public static native boolean mongocrypt_ctx_setopt_key_encryption_key(mongocrypt_ctx_t ctx, mongocrypt_binary_t keyDocument); /** * Initialize a context to create a data key. * * Set options before using @ref mongocrypt_ctx_setopt_masterkey_aws and * mongocrypt_ctx_setopt_masterkey_local. * * @param ctx The @ref mongocrypt_ctx_t object. * @return A boolean indicating success. * * Assumes a master key option has been set, and an associated KMS provider * has been set on the parent @ref mongocrypt_t. */ public static native boolean mongocrypt_ctx_datakey_init (mongocrypt_ctx_t ctx); /** * Initialize a context for encryption. * * Associated options: * - @ref mongocrypt_ctx_setopt_cache_noblock * - @ref mongocrypt_ctx_setopt_schema * * @param ctx The @ref mongocrypt_ctx_t object. * @param db The database name. * @param db_len The byte length of @p db. Pass -1 to determine the string length with strlen (must be NULL terminated). * @param cmd The BSON command to be encrypted. * @return A boolean indicating success. If false, an error status is set. * Retrieve it with @ref mongocrypt_ctx_status */ public static native boolean mongocrypt_ctx_encrypt_init(mongocrypt_ctx_t ctx, cstring db, int db_len, mongocrypt_binary_t cmd); /** * Explicit helper method to encrypt a single BSON object. Contexts * created for explicit encryption will not go through mongocryptd. * * To specify a key_id, algorithm, or iv to use, please use the * corresponding mongocrypt_setopt methods before calling this. * * This method expects the passed-in BSON to be of the form: * { "v" : BSON value to encrypt } * * @param ctx A @ref mongocrypt_ctx_t. * @param msg A @ref mongocrypt_binary_t the plaintext BSON value. * @return A boolean indicating success. */ public static native boolean mongocrypt_ctx_explicit_encrypt_init (mongocrypt_ctx_t ctx, mongocrypt_binary_t msg); /** * Initialize a context for decryption. * * @param ctx The mongocrypt_ctx_t object. * @param doc The document to be decrypted. * @return A boolean indicating success. */ public static native boolean mongocrypt_ctx_decrypt_init(mongocrypt_ctx_t ctx, mongocrypt_binary_t doc); /** * Explicit helper method to decrypt a single BSON object. * * @param ctx A @ref mongocrypt_ctx_t. * @param msg A @ref mongocrypt_binary_t the encrypted BSON. * @return A boolean indicating success. */ public static native boolean mongocrypt_ctx_explicit_decrypt_init (mongocrypt_ctx_t ctx, mongocrypt_binary_t msg); public static final int MONGOCRYPT_CTX_ERROR = 0; public static final int MONGOCRYPT_CTX_NEED_MONGO_COLLINFO = 1; /* run on main MongoClient */ public static final int MONGOCRYPT_CTX_NEED_MONGO_MARKINGS = 2; /* run on mongocryptd. */ public static final int MONGOCRYPT_CTX_NEED_MONGO_KEYS = 3; /* run on key vault */ public static final int MONGOCRYPT_CTX_NEED_KMS = 4; public static final int MONGOCRYPT_CTX_READY = 5; /* ready for encryption/decryption */ public static final int MONGOCRYPT_CTX_DONE = 6; /** * Get the current state of a context. * * @param ctx The @ref mongocrypt_ctx_t object. * @return A @ref mongocrypt_ctx_state_t. */ public static native int mongocrypt_ctx_state(mongocrypt_ctx_t ctx); /** * Get BSON necessary to run the mongo operation when mongocrypt_ctx_t * is in MONGOCRYPT_CTX_NEED_MONGO_* states. * *

* op_bson is a BSON document to be used for the operation. * - For MONGOCRYPT_CTX_NEED_MONGO_COLLINFO it is a listCollections filter. * - For MONGOCRYPT_CTX_NEED_MONGO_KEYS it is a find filter. * - For MONGOCRYPT_CTX_NEED_MONGO_MARKINGS it is a JSON schema to append. *

* * @param ctx The @ref mongocrypt_ctx_t object. * @param op_bson A BSON document for the MongoDB operation. * @return A boolean indicating success. */ public static native boolean mongocrypt_ctx_mongo_op(mongocrypt_ctx_t ctx, mongocrypt_binary_t op_bson); /** * Feed a BSON reply or result when when mongocrypt_ctx_t is in * MONGOCRYPT_CTX_NEED_MONGO_* states. This may be called multiple times * depending on the operation. *

* op_bson is a BSON document to be used for the operation. * - For MONGOCRYPT_CTX_NEED_MONGO_COLLINFO it is a doc from a listCollections * cursor. * - For MONGOCRYPT_CTX_NEED_MONGO_KEYS it is a doc from a find cursor. * - For MONGOCRYPT_CTX_NEED_MONGO_MARKINGS it is a reply from mongocryptd. * * @param ctx The @ref mongocrypt_ctx_t object. * @param reply A BSON document for the MongoDB operation. * @return A boolean indicating success. */ public static native boolean mongocrypt_ctx_mongo_feed(mongocrypt_ctx_t ctx, mongocrypt_binary_t reply); /** * Call when done feeding the reply (or replies) back to the context. * * @param ctx The @ref mongocrypt_ctx_t object. * @return A boolean indicating success. */ public static native boolean mongocrypt_ctx_mongo_done(mongocrypt_ctx_t ctx); /** * Get the next KMS handle. *

* Multiple KMS handles may be retrieved at once. Drivers may do this to fan * out multiple concurrent KMS HTTP requests. Feeding multiple KMS requests * is thread-safe. *

* Is KMS handles are being handled synchronously, the driver can reuse the same * TLS socket to send HTTP requests and receive responses. * * @param ctx A @ref mongocrypt_ctx_t. * @return a new @ref mongocrypt_kms_ctx_t or NULL. */ public static native mongocrypt_kms_ctx_t mongocrypt_ctx_next_kms_ctx(mongocrypt_ctx_t ctx); /** * Get the KMS provider identifier associated with this KMS request. * * This is used to conditionally configure TLS connections based on the KMS * request. It is useful for KMIP, which authenticates with a client * certificate. * * @param kms The mongocrypt_kms_ctx_t object. * @param len Receives the length of the returned string. * * @return The name of the KMS provider */ public static native cstring mongocrypt_kms_ctx_get_kms_provider(mongocrypt_kms_ctx_t kms, Pointer len); /** * Get the HTTP request message for a KMS handle. * * @param kms A @ref mongocrypt_kms_ctx_t. * @param msg The HTTP request to send to KMS. * @return A boolean indicating success. */ public static native boolean mongocrypt_kms_ctx_message(mongocrypt_kms_ctx_t kms, mongocrypt_binary_t msg); /** * Get the hostname from which to connect over TLS. *

* The storage for @p endpoint is not owned by the caller, but * is valid until calling @ref mongocrypt_ctx_kms_done on the * parent @ref mongocrypt_ctx_t. * * @param kms A @ref mongocrypt_kms_ctx_t. * @param endpoint The output hostname. * @return A boolean indicating success. */ public static native boolean mongocrypt_kms_ctx_endpoint(mongocrypt_kms_ctx_t kms, PointerByReference endpoint); /** * Indicates how many bytes to feed into @ref mongocrypt_kms_ctx_feed. * * @param kms The @ref mongocrypt_kms_ctx_t. * @return The number of requested bytes. */ public static native int mongocrypt_kms_ctx_bytes_needed(mongocrypt_kms_ctx_t kms); /** * Feed bytes from the HTTP response. *

* Feeding more bytes than what has been returned in @ref * mongocrypt_kms_ctx_bytes_needed is an error. * * @param kms The @ref mongocrypt_kms_ctx_t. * @param bytes The bytes to feed. * @return A boolean indicating success. */ public static native boolean mongocrypt_kms_ctx_feed(mongocrypt_kms_ctx_t kms, mongocrypt_binary_t bytes); /** * Get the status associated with a @ref mongocrypt_kms_ctx_t object. * * @param kms The @ref mongocrypt_kms_ctx_t object. * @param status Receives the status. * @return A boolean indicating success. */ public static native boolean mongocrypt_kms_ctx_status(mongocrypt_kms_ctx_t kms, mongocrypt_status_t status); /** * Call when done handling all KMS contexts. * * @param ctx The @ref mongocrypt_ctx_t object. * @return A boolean indicating success. */ public static native boolean mongocrypt_ctx_kms_done(mongocrypt_ctx_t ctx); /** * Perform the final encryption or decryption. * * @param ctx A @ref mongocrypt_ctx_t. * @param out The final BSON to send to the server. * @return a boolean indicating success. */ public static native boolean mongocrypt_ctx_finalize(mongocrypt_ctx_t ctx, mongocrypt_binary_t out); /** * Destroy and free all memory associated with a @ref mongocrypt_ctx_t. * * @param ctx A @ref mongocrypt_ctx_t. */ public static native void mongocrypt_ctx_destroy(mongocrypt_ctx_t ctx); static final String NATIVE_LIBRARY_NAME = "mongocrypt"; static { Native.register(CAPI.class, NATIVE_LIBRARY_NAME); } } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPIHelper.java000066400000000000000000000072651414105245100327640ustar00rootroot00000000000000/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import com.mongodb.crypt.capi.CAPI.mongocrypt_binary_t; import com.sun.jna.Pointer; import org.bson.BsonBinaryWriter; import org.bson.BsonDocument; import org.bson.RawBsonDocument; import org.bson.codecs.BsonValueCodecProvider; import org.bson.codecs.Codec; import org.bson.codecs.EncoderContext; import org.bson.codecs.configuration.CodecRegistries; import org.bson.codecs.configuration.CodecRegistry; import org.bson.io.BasicOutputBuffer; import java.nio.ByteBuffer; import static com.mongodb.crypt.capi.CAPI.mongocrypt_binary_data; import static com.mongodb.crypt.capi.CAPI.mongocrypt_binary_len; import static com.mongodb.crypt.capi.CAPI.mongocrypt_binary_new_from_data; import static java.lang.String.format; final class CAPIHelper { private static final CodecRegistry CODEC_REGISTRY = CodecRegistries.fromProviders(new BsonValueCodecProvider()); @SuppressWarnings("unchecked") static BinaryHolder toBinary(final BsonDocument document) { BasicOutputBuffer buffer = new BasicOutputBuffer(); BsonBinaryWriter writer = new BsonBinaryWriter(buffer); ((Codec) CODEC_REGISTRY.get(document.getClass())).encode(writer, document, EncoderContext.builder().build()); DisposableMemory memory = new DisposableMemory(buffer.size()); memory.write(0, buffer.getInternalBuffer(), 0, buffer.size()); return new BinaryHolder(memory, mongocrypt_binary_new_from_data(memory, buffer.getSize())); } static RawBsonDocument toDocument(final mongocrypt_binary_t binary) { ByteBuffer byteBuffer = toByteBuffer(binary); byte[] bytes = new byte[byteBuffer.remaining()]; byteBuffer.get(bytes); return new RawBsonDocument(bytes); } static BinaryHolder toBinary(final ByteBuffer buffer) { byte[] message = new byte[buffer.remaining()]; buffer.get(message, 0, buffer.remaining()); DisposableMemory memory = new DisposableMemory(message.length); memory.write(0, message, 0, message.length); return new BinaryHolder(memory, mongocrypt_binary_new_from_data(memory, message.length)); } static ByteBuffer toByteBuffer(final mongocrypt_binary_t binary) { Pointer pointer = mongocrypt_binary_data(binary); int length = mongocrypt_binary_len(binary); return pointer.getByteBuffer(0, length); } static byte[] toByteArray(final mongocrypt_binary_t binary) { ByteBuffer byteBuffer = toByteBuffer(binary); byte[] byteArray = new byte[byteBuffer.remaining()]; byteBuffer.get(byteArray); return byteArray; } static void writeByteArrayToBinary(final mongocrypt_binary_t binary, byte[] bytes) { if (mongocrypt_binary_len(binary) < bytes.length) { throw new IllegalArgumentException(format("mongocrypt binary of length %d is not large enough to hold %d bytes", mongocrypt_binary_len(binary), bytes.length)); } Pointer outPointer = mongocrypt_binary_data(binary); outPointer.write(0, bytes, 0, bytes.length); } private CAPIHelper() { } } CipherCallback.java000066400000000000000000000050661414105245100336550ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2008-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import com.mongodb.crypt.capi.CAPI.cstring; import com.mongodb.crypt.capi.CAPI.mongocrypt_binary_t; import com.mongodb.crypt.capi.CAPI.mongocrypt_crypto_fn; import com.mongodb.crypt.capi.CAPI.mongocrypt_status_t; import com.sun.jna.Pointer; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import static com.mongodb.crypt.capi.CAPI.MONGOCRYPT_STATUS_ERROR_CLIENT; import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_set; import static com.mongodb.crypt.capi.CAPIHelper.toByteArray; import static com.mongodb.crypt.capi.CAPIHelper.writeByteArrayToBinary; class CipherCallback implements mongocrypt_crypto_fn { private final String algorithm; private final String transformation; private final int mode; CipherCallback(final String algorithm, final String transformation, final int mode) { this.algorithm = algorithm; this.transformation = transformation; this.mode = mode; } @Override public boolean crypt(final Pointer ctx, final mongocrypt_binary_t key, final mongocrypt_binary_t iv, final mongocrypt_binary_t in, final mongocrypt_binary_t out, final Pointer bytesWritten, final mongocrypt_status_t status) { try { IvParameterSpec ivParameterSpec = new IvParameterSpec(toByteArray(iv)); SecretKeySpec secretKeySpec = new SecretKeySpec(toByteArray(key), algorithm); Cipher cipher = Cipher.getInstance(transformation); cipher.init(mode, secretKeySpec, ivParameterSpec); byte[] result = cipher.doFinal(toByteArray(in)); writeByteArrayToBinary(out, result); bytesWritten.setInt(0, result.length); return true; } catch (Exception e) { mongocrypt_status_set(status, MONGOCRYPT_STATUS_ERROR_CLIENT, 0, new cstring(e.toString()), -1); return false; } } } DisposableMemory.java000066400000000000000000000016271414105245100343030ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2008-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import com.sun.jna.Memory; // Subclass of JNA's Memory class so that we can call its protected dispose method class DisposableMemory extends Memory { DisposableMemory(final int size) { super(size); } public void dispose() { super.dispose(); } } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/JULLogger.java000066400000000000000000000056561414105245100327040ustar00rootroot00000000000000 /* * Copyright 2008-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import java.util.logging.Level; import static java.util.logging.Level.FINE; import static java.util.logging.Level.FINER; import static java.util.logging.Level.INFO; import static java.util.logging.Level.SEVERE; import static java.util.logging.Level.WARNING; class JULLogger implements Logger { private final java.util.logging.Logger delegate; JULLogger(final String name) { this.delegate = java.util.logging.Logger.getLogger(name); } @Override public String getName() { return delegate.getName(); } @Override public boolean isTraceEnabled() { return isEnabled(FINER); } @Override public void trace(final String msg) { log(FINER, msg); } @Override public void trace(final String msg, final Throwable t) { log(FINER, msg, t); } @Override public boolean isDebugEnabled() { return isEnabled(FINE); } @Override public void debug(final String msg) { log(FINE, msg); } @Override public void debug(final String msg, final Throwable t) { log(FINE, msg, t); } @Override public boolean isInfoEnabled() { return delegate.isLoggable(INFO); } @Override public void info(final String msg) { log(INFO, msg); } @Override public void info(final String msg, final Throwable t) { log(INFO, msg, t); } @Override public boolean isWarnEnabled() { return delegate.isLoggable(WARNING); } @Override public void warn(final String msg) { log(WARNING, msg); } @Override public void warn(final String msg, final Throwable t) { log(WARNING, msg, t); } @Override public boolean isErrorEnabled() { return delegate.isLoggable(SEVERE); } @Override public void error(final String msg) { log(SEVERE, msg); } @Override public void error(final String msg, final Throwable t) { log(SEVERE, msg, t); } private boolean isEnabled(final Level level) { return delegate.isLoggable(level); } private void log(final Level level, final String msg) { delegate.log(level, msg); } public void log(final Level level, final String msg, final Throwable t) { delegate.log(level, msg, t); } } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/Logger.java000066400000000000000000000073741414105245100323300ustar00rootroot00000000000000 /* * Copyright 2008-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; /** * Not part of the public API */ public interface Logger { /** * Return the name of this Logger instance. * * @return name of this logger instance */ String getName(); /** * Is the logger instance enabled for the TRACE level? * * @return True if this Logger is enabled for the TRACE level, false otherwise. */ boolean isTraceEnabled(); /** * Log a message at the TRACE level. * * @param msg the message string to be logged */ void trace(String msg); /** * Log an exception (throwable) at the TRACE level with an accompanying message. * * @param msg the message accompanying the exception * @param t the exception (throwable) to log */ void trace(String msg, Throwable t); /** * Is the logger instance enabled for the DEBUG level? * * @return True if this Logger is enabled for the DEBUG level, false otherwise. */ boolean isDebugEnabled(); /** * Log a message at the DEBUG level. * * @param msg the message string to be logged */ void debug(String msg); /** * Log an exception (throwable) at the DEBUG level with an accompanying message. * * @param msg the message accompanying the exception * @param t the exception (throwable) to log */ void debug(String msg, Throwable t); /** * Is the logger instance enabled for the INFO level? * * @return True if this Logger is enabled for the INFO level, false otherwise. */ boolean isInfoEnabled(); /** * Log a message at the INFO level. * * @param msg the message string to be logged */ void info(String msg); /** * Log an exception (throwable) at the INFO level with an accompanying message. * * @param msg the message accompanying the exception * @param t the exception (throwable) to log */ void info(String msg, Throwable t); /** * Is the logger instance enabled for the WARN level? * * @return True if this Logger is enabled for the WARN level, false otherwise. */ boolean isWarnEnabled(); /** * Log a message at the WARN level. * * @param msg the message string to be logged */ void warn(String msg); /** * Log an exception (throwable) at the WARN level with an accompanying message. * * @param msg the message accompanying the exception * @param t the exception (throwable) to log */ void warn(String msg, Throwable t); /** * Is the logger instance enabled for the ERROR level? * * @return True if this Logger is enabled for the ERROR level, false otherwise. */ boolean isErrorEnabled(); /** * Log a message at the ERROR level. * * @param msg the message string to be logged */ void error(String msg); /** * Log an exception (throwable) at the ERROR level with an accompanying message. * * @param msg the message accompanying the exception * @param t the exception (throwable) to log */ void error(String msg, Throwable t); } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/Loggers.java000066400000000000000000000024601414105245100325020ustar00rootroot00000000000000/* * Copyright 2008-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; /** * This class is not part of the public API. */ public final class Loggers { private static final String NAME = "org.mongodb.driver.crypt"; private static final boolean USE_SLF4J = shouldUseSLF4J(); /** * @return the logger */ public static Logger getLogger() { if (USE_SLF4J) { return new SLF4JLogger(NAME); } else { return new JULLogger(NAME); } } private Loggers() { } private static boolean shouldUseSLF4J() { try { Class.forName("org.slf4j.Logger"); return true; } catch (ClassNotFoundException e) { return false; } } } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MacCallback.java000066400000000000000000000041151414105245100332140ustar00rootroot00000000000000/* * Copyright 2008-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import com.mongodb.crypt.capi.CAPI.cstring; import com.mongodb.crypt.capi.CAPI.mongocrypt_binary_t; import com.mongodb.crypt.capi.CAPI.mongocrypt_hmac_fn; import com.mongodb.crypt.capi.CAPI.mongocrypt_status_t; import com.sun.jna.Pointer; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import static com.mongodb.crypt.capi.CAPI.MONGOCRYPT_STATUS_ERROR_CLIENT; import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_set; import static com.mongodb.crypt.capi.CAPIHelper.toByteArray; import static com.mongodb.crypt.capi.CAPIHelper.writeByteArrayToBinary; class MacCallback implements mongocrypt_hmac_fn { private final String algorithm; MacCallback(final String algorithm) { this.algorithm = algorithm; } @Override public boolean hmac(final Pointer ctx, final mongocrypt_binary_t key, final mongocrypt_binary_t in, final mongocrypt_binary_t out, final mongocrypt_status_t status) { try { Mac mac = Mac.getInstance(algorithm); SecretKeySpec keySpec = new SecretKeySpec(toByteArray(key), algorithm); mac.init(keySpec); mac.update(toByteArray(in)); byte[] result = mac.doFinal(); writeByteArrayToBinary(out, result); return true; } catch (Exception e) { mongocrypt_status_set(status, MONGOCRYPT_STATUS_ERROR_CLIENT, 0, new cstring(e.toString()), -1); return false; } } } MessageDigestCallback.java000066400000000000000000000037411414105245100351650ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2008-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import com.mongodb.crypt.capi.CAPI.cstring; import com.mongodb.crypt.capi.CAPI.mongocrypt_binary_t; import com.mongodb.crypt.capi.CAPI.mongocrypt_hash_fn; import com.mongodb.crypt.capi.CAPI.mongocrypt_status_t; import com.sun.jna.Pointer; import java.security.MessageDigest; import static com.mongodb.crypt.capi.CAPI.MONGOCRYPT_STATUS_ERROR_CLIENT; import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_set; import static com.mongodb.crypt.capi.CAPIHelper.toByteArray; import static com.mongodb.crypt.capi.CAPIHelper.writeByteArrayToBinary; class MessageDigestCallback implements mongocrypt_hash_fn { private final String algorithm; MessageDigestCallback(final String algorithm) { this.algorithm = algorithm; } @Override public boolean hash(final Pointer ctx, final mongocrypt_binary_t in, final mongocrypt_binary_t out, final mongocrypt_status_t status) { try { MessageDigest messageDigest = MessageDigest.getInstance(algorithm); messageDigest.update(toByteArray(in)); byte[] digest = messageDigest.digest(); writeByteArrayToBinary(out, digest); return true; } catch (Exception e) { mongocrypt_status_set(status, MONGOCRYPT_STATUS_ERROR_CLIENT, 0, new cstring(e.toString()), -1); return false; } } } MongoAwsKmsProviderOptions.java000066400000000000000000000052261414105245100363200ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import static org.bson.assertions.Assertions.notNull; /** * The options for configuring the AWS KMS provider. */ public class MongoAwsKmsProviderOptions { private final String accessKeyId; private final String secretAccessKey; /** * Construct a builder for the options * * @return the builder */ public static Builder builder() { return new Builder(); } /** * Gets the access key id * * @return the access key id, which may not be null */ public String getAccessKeyId() { return accessKeyId; } /** * Gets the secret access key * * @return the secret access key, which may not be null */ public String getSecretAccessKey() { return secretAccessKey; } /** * The builder for the options */ public static class Builder { private String accessKeyId; private String secretAccessKey; private Builder() { } /** * Sets the access key id. * * @param accessKeyId the access key id * @return this */ public Builder accessKeyId(final String accessKeyId) { this.accessKeyId = accessKeyId; return this; } /** * Sets the secret access key. * * @param secretAccessKey the secret access key * @return this */ public Builder secretAccessKey(final String secretAccessKey) { this.secretAccessKey = secretAccessKey; return this; } /** * Build the options. * * @return the options */ public MongoAwsKmsProviderOptions build() { return new MongoAwsKmsProviderOptions(this); } } private MongoAwsKmsProviderOptions(final Builder builder) { this.accessKeyId = notNull("AWS KMS provider accessKeyId", builder.accessKeyId); this.secretAccessKey = notNull("AWS KMS provider secretAccessKey", builder.secretAccessKey); } } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCrypt.java000066400000000000000000000044061414105245100332030ustar00rootroot00000000000000/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import org.bson.BsonDocument; import java.io.Closeable; /** * A context for encryption/decryption operations. */ public interface MongoCrypt extends Closeable { /** * Create a context to use for encryption * * @param database the namespace * @param command the document representing the command to encrypt * @return the context */ MongoCryptContext createEncryptionContext(String database, final BsonDocument command); /** * Create a context to use for decryption * * @param document the document to decrypt * @return the context */ MongoCryptContext createDecryptionContext(BsonDocument document); /** * Create a context to use for creating a data key * @param kmsProvider the KMS provider * @param options the data key options * @return the context */ MongoCryptContext createDataKeyContext(String kmsProvider, MongoDataKeyOptions options); /** * Create a context to use for encryption * * @param document the document to encrypt, which must be in the form { "v" : BSON value to encrypt }} * @param options the explicit encryption options * @return the context */ MongoCryptContext createExplicitEncryptionContext(BsonDocument document, MongoExplicitEncryptOptions options); /** * Create a context to use for encryption * * @param document the document to decrypt,which must be in the form { "v" : encrypted BSON value } * @return the context */ MongoCryptContext createExplicitDecryptionContext(BsonDocument document); @Override void close(); } MongoCryptContext.java000066400000000000000000000056231414105245100344730ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import org.bson.BsonDocument; import org.bson.RawBsonDocument; import java.io.Closeable; /** * An interface representing the lifecycle of an encryption or decryption request. It's modelled as a state machine. */ public interface MongoCryptContext extends Closeable { /** * The possible states. */ enum State { /** * Needs collection information from the cluster encrypting to */ NEED_MONGO_COLLINFO(CAPI.MONGOCRYPT_CTX_NEED_MONGO_COLLINFO), /** * Need to mark command with encryption markers */ NEED_MONGO_MARKINGS(CAPI.MONGOCRYPT_CTX_NEED_MONGO_MARKINGS), /** * Need keys from the key vault */ NEED_MONGO_KEYS(CAPI.MONGOCRYPT_CTX_NEED_MONGO_KEYS), /** * Need the key management service */ NEED_KMS(CAPI.MONGOCRYPT_CTX_NEED_KMS), /** * Ready for encryption/decryption */ READY(CAPI.MONGOCRYPT_CTX_READY), /** * Done */ DONE(CAPI.MONGOCRYPT_CTX_DONE); private final int index; State(final int index) { this.index = index; } static State fromIndex(final int index) { for (State state : State.values()) { if (state.index == index) { return state; } } throw new MongoCryptException("Unknown context state " + index); } } /** * Gets the current state. * * @return the current state */ State getState(); /** * * @return the operation to execute */ RawBsonDocument getMongoOperation(); /** * * @param document a result of the operation */ void addMongoOperationResult(BsonDocument document); /** * Signal completion of the operation */ void completeMongoOperation(); /** * * @return the next key decryptor, or null if there are no more */ MongoKeyDecryptor nextKeyDecryptor(); /** * Indicate that all key decryptors have been completed */ void completeKeyDecryptors(); /** * * @return the encrypted or decrypted document */ RawBsonDocument finish(); @Override void close(); } MongoCryptContextImpl.java000066400000000000000000000116451414105245100353160ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import com.mongodb.crypt.capi.CAPI.mongocrypt_binary_t; import com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_t; import com.mongodb.crypt.capi.CAPI.mongocrypt_kms_ctx_t; import org.bson.BsonDocument; import org.bson.RawBsonDocument; import static com.mongodb.crypt.capi.CAPI.mongocrypt_binary_destroy; import static com.mongodb.crypt.capi.CAPI.mongocrypt_binary_new; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_destroy; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_finalize; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_kms_done; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_mongo_done; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_mongo_feed; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_mongo_op; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_next_kms_ctx; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_state; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_status; import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_destroy; import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_new; import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_t; import static com.mongodb.crypt.capi.CAPIHelper.toBinary; import static com.mongodb.crypt.capi.CAPIHelper.toDocument; import static org.bson.assertions.Assertions.isTrue; import static org.bson.assertions.Assertions.notNull; class MongoCryptContextImpl implements MongoCryptContext { private final mongocrypt_ctx_t wrapped; private volatile boolean closed; MongoCryptContextImpl(final mongocrypt_ctx_t wrapped) { notNull("wrapped", wrapped); this.wrapped = wrapped; } @Override public State getState() { isTrue("open", !closed); return State.fromIndex(mongocrypt_ctx_state(wrapped)); } @Override public RawBsonDocument getMongoOperation() { isTrue("open", !closed); mongocrypt_binary_t binary = mongocrypt_binary_new(); try { boolean success = mongocrypt_ctx_mongo_op(wrapped, binary); if (!success) { throwExceptionFromStatus(); } return toDocument(binary); } finally { mongocrypt_binary_destroy(binary); } } @Override public void addMongoOperationResult(final BsonDocument document) { isTrue("open", !closed); try (BinaryHolder binaryHolder = toBinary(document)) { boolean success = mongocrypt_ctx_mongo_feed(wrapped, binaryHolder.getBinary()); if (!success) { throwExceptionFromStatus(); } } } @Override public void completeMongoOperation() { isTrue("open", !closed); boolean success = mongocrypt_ctx_mongo_done(wrapped); if (!success) { throwExceptionFromStatus(); } } @Override public MongoKeyDecryptor nextKeyDecryptor() { isTrue("open", !closed); mongocrypt_kms_ctx_t kmsContext = mongocrypt_ctx_next_kms_ctx(wrapped); if (kmsContext == null) { return null; } return new MongoKeyDecryptorImpl(kmsContext); } @Override public void completeKeyDecryptors() { isTrue("open", !closed); boolean success = mongocrypt_ctx_kms_done(wrapped); if (!success) { throwExceptionFromStatus(); } } @Override public RawBsonDocument finish() { isTrue("open", !closed); mongocrypt_binary_t binary = mongocrypt_binary_new(); try { boolean success = mongocrypt_ctx_finalize(wrapped, binary); if (!success) { throwExceptionFromStatus(); } return toDocument(binary); } finally { mongocrypt_binary_destroy(binary); } } @Override public void close() { mongocrypt_ctx_destroy(wrapped); closed = true; } static void throwExceptionFromStatus(final mongocrypt_ctx_t wrapped) { mongocrypt_status_t status = mongocrypt_status_new(); mongocrypt_ctx_status(wrapped, status); MongoCryptException e = new MongoCryptException(status); mongocrypt_status_destroy(status); throw e; } private void throwExceptionFromStatus() { throwExceptionFromStatus(wrapped); } } MongoCryptException.java000066400000000000000000000035461414105245100350070ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import com.mongodb.crypt.capi.CAPI.mongocrypt_status_t; import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_code; import static org.bson.assertions.Assertions.isTrue; /** * Top level Exception for all Mongo Crypt CAPI exceptions */ public class MongoCryptException extends RuntimeException { private static final long serialVersionUID = -5524416583514807953L; private final int code; /** * @param msg the message */ public MongoCryptException(final String msg) { super(msg); this.code = -1; } /** * @param msg the message * @param cause the cause */ public MongoCryptException(final String msg, Throwable cause) { super(msg, cause); this.code = -1; } /** * Construct an instance from a {@code mongocrypt_status_t}. * * @param status the status */ MongoCryptException(final mongocrypt_status_t status) { super(CAPI.mongocrypt_status_message(status, null).toString()); isTrue("status not ok", !CAPI.mongocrypt_status_ok(status)); code = mongocrypt_status_code(status); } /** * @return the error code for the exception. */ public int getCode() { return code; } } MongoCryptImpl.java000066400000000000000000000361261414105245100337520ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import com.mongodb.crypt.capi.CAPI.cstring; import com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_t; import com.mongodb.crypt.capi.CAPI.mongocrypt_log_fn_t; import com.mongodb.crypt.capi.CAPI.mongocrypt_status_t; import com.mongodb.crypt.capi.CAPI.mongocrypt_t; import com.sun.jna.Pointer; import org.bson.BsonDocument; import org.bson.BsonString; import javax.crypto.Cipher; import java.nio.ByteBuffer; import java.security.SecureRandom; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import static com.mongodb.crypt.capi.CAPI.MONGOCRYPT_LOG_LEVEL_ERROR; import static com.mongodb.crypt.capi.CAPI.MONGOCRYPT_LOG_LEVEL_FATAL; import static com.mongodb.crypt.capi.CAPI.MONGOCRYPT_LOG_LEVEL_INFO; import static com.mongodb.crypt.capi.CAPI.MONGOCRYPT_LOG_LEVEL_TRACE; import static com.mongodb.crypt.capi.CAPI.MONGOCRYPT_LOG_LEVEL_WARNING; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_datakey_init; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_decrypt_init; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_encrypt_init; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_explicit_decrypt_init; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_explicit_encrypt_init; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_new; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_setopt_algorithm; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_setopt_key_alt_name; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_setopt_key_encryption_key; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_setopt_key_id; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_setopt_masterkey_aws; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_setopt_masterkey_aws_endpoint; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_setopt_masterkey_local; import static com.mongodb.crypt.capi.CAPI.mongocrypt_destroy; import static com.mongodb.crypt.capi.CAPI.mongocrypt_init; import static com.mongodb.crypt.capi.CAPI.mongocrypt_new; import static com.mongodb.crypt.capi.CAPI.mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5; import static com.mongodb.crypt.capi.CAPI.mongocrypt_setopt_crypto_hooks; import static com.mongodb.crypt.capi.CAPI.mongocrypt_setopt_kms_provider_aws; import static com.mongodb.crypt.capi.CAPI.mongocrypt_setopt_kms_provider_local; import static com.mongodb.crypt.capi.CAPI.mongocrypt_setopt_kms_providers; import static com.mongodb.crypt.capi.CAPI.mongocrypt_setopt_log_handler; import static com.mongodb.crypt.capi.CAPI.mongocrypt_setopt_schema_map; import static com.mongodb.crypt.capi.CAPI.mongocrypt_status; import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_destroy; import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_new; import static com.mongodb.crypt.capi.CAPIHelper.toBinary; import static org.bson.assertions.Assertions.isTrue; import static org.bson.assertions.Assertions.notNull; class MongoCryptImpl implements MongoCrypt { private static final Logger LOGGER = Loggers.getLogger(); private final mongocrypt_t wrapped; // Keep a strong reference to all the callbacks so that they don't get garbage collected @SuppressWarnings("FieldCanBeLocal") private final LogCallback logCallback; @SuppressWarnings("FieldCanBeLocal") private final CipherCallback aesCBC256EncryptCallback; @SuppressWarnings("FieldCanBeLocal") private final CipherCallback aesCBC256DecryptCallback; @SuppressWarnings("FieldCanBeLocal") private final MacCallback hmacSha512Callback; @SuppressWarnings("FieldCanBeLocal") private final MacCallback hmacSha256Callback; @SuppressWarnings("FieldCanBeLocal") private final MessageDigestCallback sha256Callback; @SuppressWarnings("FieldCanBeLocal") private final SecureRandomCallback secureRandomCallback; @SuppressWarnings("FieldCanBeLocal") private final SigningRSAESPKCSCallback signingRSAESPKCSCallback; private final AtomicBoolean closed; MongoCryptImpl(final MongoCryptOptions options) { closed = new AtomicBoolean(); wrapped = mongocrypt_new(); if (wrapped == null) { throw new MongoCryptException("Unable to create new mongocrypt object"); } boolean success; logCallback = new LogCallback(); success = mongocrypt_setopt_log_handler(wrapped, logCallback, null); if (!success) { throwExceptionFromStatus(); } // We specify NoPadding here because the underlying C library is responsible for padding prior // to executing the callback aesCBC256EncryptCallback = new CipherCallback("AES", "AES/CBC/NoPadding", Cipher.ENCRYPT_MODE); aesCBC256DecryptCallback = new CipherCallback("AES", "AES/CBC/NoPadding", Cipher.DECRYPT_MODE); hmacSha512Callback = new MacCallback("HmacSHA512"); hmacSha256Callback = new MacCallback("HmacSHA256"); sha256Callback = new MessageDigestCallback("SHA-256"); secureRandomCallback = new SecureRandomCallback(new SecureRandom()); success = mongocrypt_setopt_crypto_hooks(wrapped, aesCBC256EncryptCallback, aesCBC256DecryptCallback, secureRandomCallback, hmacSha512Callback, hmacSha256Callback, sha256Callback, null); if (!success) { throwExceptionFromStatus(); } signingRSAESPKCSCallback = new SigningRSAESPKCSCallback(); success = mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5(wrapped, signingRSAESPKCSCallback, null); if (!success) { throwExceptionFromStatus(); } if (options.getLocalKmsProviderOptions() != null) { try (BinaryHolder localMasterKeyBinaryHolder = toBinary(options.getLocalKmsProviderOptions().getLocalMasterKey())) { success = mongocrypt_setopt_kms_provider_local(wrapped, localMasterKeyBinaryHolder.getBinary()); if (!success) { throwExceptionFromStatus(); } } } if (options.getAwsKmsProviderOptions() != null) { success = mongocrypt_setopt_kms_provider_aws(wrapped, new cstring(options.getAwsKmsProviderOptions().getAccessKeyId()), -1, new cstring(options.getAwsKmsProviderOptions().getSecretAccessKey()), -1); if (!success) { throwExceptionFromStatus(); } } if (options.getKmsProviderOptions() != null) { try (BinaryHolder binaryHolder = toBinary(options.getKmsProviderOptions())) { success = mongocrypt_setopt_kms_providers(wrapped, binaryHolder.getBinary()); if (!success) { throwExceptionFromStatus(); } } } if (options.getLocalSchemaMap() != null) { BsonDocument localSchemaMapDocument = new BsonDocument(); for (Map.Entry cur: options.getLocalSchemaMap().entrySet()) { localSchemaMapDocument.put(cur.getKey(), cur.getValue()); } try (BinaryHolder localSchemaMapBinaryHolder = toBinary(localSchemaMapDocument)) { success = mongocrypt_setopt_schema_map(wrapped, localSchemaMapBinaryHolder.getBinary()); if (!success) { throwExceptionFromStatus(); } } } success = mongocrypt_init(wrapped); if (!success) { throwExceptionFromStatus(); } } @Override public MongoCryptContext createEncryptionContext(final String database, final BsonDocument commandDocument) { isTrue("open", !closed.get()); notNull("database", database); notNull("commandDocument", commandDocument); mongocrypt_ctx_t context = mongocrypt_ctx_new(wrapped); if (context == null) { throwExceptionFromStatus(); } try (BinaryHolder commandDocumentBinaryHolder = toBinary(commandDocument)) { boolean success = mongocrypt_ctx_encrypt_init(context, new cstring(database), -1, commandDocumentBinaryHolder.getBinary()); if (!success) { MongoCryptContextImpl.throwExceptionFromStatus(context); } return new MongoCryptContextImpl(context); } } @Override public MongoCryptContext createDecryptionContext(final BsonDocument document) { isTrue("open", !closed.get()); mongocrypt_ctx_t context = mongocrypt_ctx_new(wrapped); if (context == null) { throwExceptionFromStatus(); } try (BinaryHolder documentBinaryHolder = toBinary(document)){ boolean success = mongocrypt_ctx_decrypt_init(context, documentBinaryHolder.getBinary()); if (!success) { MongoCryptContextImpl.throwExceptionFromStatus(context); } } return new MongoCryptContextImpl(context); } @Override public MongoCryptContext createDataKeyContext(final String kmsProvider, final MongoDataKeyOptions options) { isTrue("open", !closed.get()); mongocrypt_ctx_t context = mongocrypt_ctx_new(wrapped); if (context == null) { throwExceptionFromStatus(); } boolean success; if (kmsProvider.equals("aws")) { success = mongocrypt_ctx_setopt_masterkey_aws(context, new cstring(options.getMasterKey().getString("region").getValue()), -1, new cstring(options.getMasterKey().getString("key").getValue()), -1); if (success && options.getMasterKey().containsKey("endpoint")) { success = mongocrypt_ctx_setopt_masterkey_aws_endpoint(context, new cstring(options.getMasterKey().getString("endpoint").getValue()), -1); } } else if (kmsProvider.equals("local")) { success = mongocrypt_ctx_setopt_masterkey_local(context); } else { BsonDocument masterKey = options.getMasterKey().clone(); masterKey.put("provider", new BsonString(kmsProvider)); success = mongocrypt_ctx_setopt_key_encryption_key(context, toBinary(masterKey).getBinary()); } if (!success) { MongoCryptContextImpl.throwExceptionFromStatus(context); } if (options.getKeyAltNames() != null) { for (String cur : options.getKeyAltNames()) { try (BinaryHolder keyAltNameBinaryHolder = toBinary(new BsonDocument("keyAltName", new BsonString(cur)))) { success = mongocrypt_ctx_setopt_key_alt_name(context, keyAltNameBinaryHolder.getBinary()); if (!success) { MongoCryptContextImpl.throwExceptionFromStatus(context); } } } } if (!mongocrypt_ctx_datakey_init(context)) { MongoCryptContextImpl.throwExceptionFromStatus(context); } return new MongoCryptContextImpl(context); } @Override public MongoCryptContext createExplicitEncryptionContext(final BsonDocument document, final MongoExplicitEncryptOptions options) { isTrue("open", !closed.get()); mongocrypt_ctx_t context = mongocrypt_ctx_new(wrapped); if (context == null) { throwExceptionFromStatus(); } boolean success; if (options.getKeyId() != null) { try (BinaryHolder keyIdBinaryHolder = toBinary(ByteBuffer.wrap(options.getKeyId().getData()))) { success = mongocrypt_ctx_setopt_key_id(context, keyIdBinaryHolder.getBinary()); if (!success) { MongoCryptContextImpl.throwExceptionFromStatus(context); } } } else if (options.getKeyAltName() != null) { try (BinaryHolder keyAltNameBinaryHolder = toBinary(new BsonDocument("keyAltName", new BsonString(options.getKeyAltName())))) { success = mongocrypt_ctx_setopt_key_alt_name(context, keyAltNameBinaryHolder.getBinary()); if (!success) { MongoCryptContextImpl.throwExceptionFromStatus(context); } } } success = mongocrypt_ctx_setopt_algorithm(context, new cstring(options.getAlgorithm()), -1); if (!success) { MongoCryptContextImpl.throwExceptionFromStatus(context); } try (BinaryHolder documentBinaryHolder = toBinary(document)) { success = mongocrypt_ctx_explicit_encrypt_init(context, documentBinaryHolder.getBinary()); if (!success) { MongoCryptContextImpl.throwExceptionFromStatus(context); } } return new MongoCryptContextImpl(context); } @Override public MongoCryptContext createExplicitDecryptionContext(final BsonDocument document) { isTrue("open", !closed.get()); mongocrypt_ctx_t context = mongocrypt_ctx_new(wrapped); if (context == null) { throwExceptionFromStatus(); } try (BinaryHolder binaryHolder = toBinary(document)) { boolean success = mongocrypt_ctx_explicit_decrypt_init(context, binaryHolder.getBinary()); if (!success) { MongoCryptContextImpl.throwExceptionFromStatus(context); } } return new MongoCryptContextImpl(context); } @Override public void close() { if (!closed.getAndSet(true)) { mongocrypt_destroy(wrapped); } } private void throwExceptionFromStatus() { mongocrypt_status_t status = mongocrypt_status_new(); mongocrypt_status(wrapped, status); MongoCryptException e = new MongoCryptException(status); mongocrypt_status_destroy(status); throw e; } static class LogCallback implements mongocrypt_log_fn_t { @Override public void log(final int level, final cstring message, final int messageLength, final Pointer ctx) { if (level == MONGOCRYPT_LOG_LEVEL_FATAL) { LOGGER.error(message.toString()); } if (level == MONGOCRYPT_LOG_LEVEL_ERROR) { LOGGER.error(message.toString()); } if (level == MONGOCRYPT_LOG_LEVEL_WARNING) { LOGGER.warn(message.toString()); } if (level == MONGOCRYPT_LOG_LEVEL_INFO) { LOGGER.info(message.toString()); } if (level == MONGOCRYPT_LOG_LEVEL_TRACE) { LOGGER.trace(message.toString()); } } } } MongoCryptOptions.java000066400000000000000000000112221414105245100344720ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import org.bson.BsonDocument; import java.util.Map; import static org.bson.assertions.Assertions.isTrue; /** * The options for configuring MongoCrypt. */ public class MongoCryptOptions { private final MongoAwsKmsProviderOptions awsKmsProviderOptions; private final MongoLocalKmsProviderOptions localKmsProviderOptions; private final BsonDocument kmsProviderOptions; private final Map localSchemaMap; /** * Construct a builder for the options * * @return the builder */ public static Builder builder() { return new Builder(); } /** * Gets the AWS KMS provider options. * * @return the AWS KMS provider options, which may be null */ public MongoAwsKmsProviderOptions getAwsKmsProviderOptions() { return awsKmsProviderOptions; } /** * Gets the local KMS provider options. * * @return the local KMS provider options, which may be null */ public MongoLocalKmsProviderOptions getLocalKmsProviderOptions() { return localKmsProviderOptions; } /** * Returns the KMS provider options. * * @return the KMS provider options, which may be null * @since 1.1 */ public BsonDocument getKmsProviderOptions() { return kmsProviderOptions; } /** * Gets the local schema map. * * @return the local schema map */ public Map getLocalSchemaMap() { return localSchemaMap; } /** * The builder for the options */ public static class Builder { private MongoAwsKmsProviderOptions awsKmsProviderOptions; private MongoLocalKmsProviderOptions localKmsProviderOptions; private BsonDocument kmsProviderOptions = null; private Map localSchemaMap = null; private Builder() { } /** * Sets the AWS KMS provider options. * * @param awsKmsProviderOptions the AWS KMS provider options * @return this */ public Builder awsKmsProviderOptions(final MongoAwsKmsProviderOptions awsKmsProviderOptions) { this.awsKmsProviderOptions = awsKmsProviderOptions; return this; } /** * Sets the local KMS provider options. * * @param localKmsProviderOptions the local KMS provider options * @return this */ public Builder localKmsProviderOptions(final MongoLocalKmsProviderOptions localKmsProviderOptions) { this.localKmsProviderOptions = localKmsProviderOptions; return this; } /** * Sets the KMS provider options. * * @param kmsProviderOptions the KMS provider options document * @return this * @since 1.1 */ public Builder kmsProviderOptions(final BsonDocument kmsProviderOptions) { this.kmsProviderOptions = kmsProviderOptions; return this; } /** * Sets the local schema map. * * @param localSchemaMap local schema map * @return this */ public Builder localSchemaMap(final Map localSchemaMap) { this.localSchemaMap = localSchemaMap; return this; } /** * Build the options. * * @return the options */ public MongoCryptOptions build() { return new MongoCryptOptions(this); } } private MongoCryptOptions(final Builder builder) { isTrue("at least one KMS provider is configured", builder.awsKmsProviderOptions != null || builder.localKmsProviderOptions != null || builder.kmsProviderOptions != null ); this.awsKmsProviderOptions = builder.awsKmsProviderOptions; this.localKmsProviderOptions = builder.localKmsProviderOptions; this.kmsProviderOptions = builder.kmsProviderOptions; this.localSchemaMap = builder.localSchemaMap; } } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCrypts.java000066400000000000000000000021411414105245100333600ustar00rootroot00000000000000/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; /** * The entry point to the MongoCrypt library. */ public class MongoCrypts { /** * Create a {@code MongoCrypt} instance. * *

* Make sure that JNA is able to find the shared library, most likely by setting the jna.library.path system property *

* * @param options the options * @return the instance */ public static MongoCrypt create(MongoCryptOptions options) { return new MongoCryptImpl(options); } } MongoDataKeyOptions.java000066400000000000000000000046461414105245100347270ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2008-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import org.bson.BsonDocument; import java.util.List; /** * The options for creation of a data key */ public class MongoDataKeyOptions { private final List keyAltNames; private final BsonDocument masterKey; /** * Options builder */ public static class Builder { private List keyAltNames; private BsonDocument masterKey; /** * Add alternate key names * @param keyAltNames the alternate key names * @return this */ public Builder keyAltNames(final List keyAltNames) { this.keyAltNames = keyAltNames; return this; } /** * Add the master key. * * @param masterKey the master key * @return this */ public Builder masterKey(final BsonDocument masterKey) { this.masterKey = masterKey; return this; } /** * Build the options. * * @return the options */ public MongoDataKeyOptions build() { return new MongoDataKeyOptions(this); } } /** * Create a builder for the options. * * @return the builder */ public static Builder builder() { return new Builder(); } /** * Gets the alternate key names for the data key. * * @return the alternate key names */ public List getKeyAltNames() { return keyAltNames; } /** * Gets the master key for the data key. * * @return the master key */ public BsonDocument getMasterKey() { return masterKey; } private MongoDataKeyOptions(final Builder builder) { keyAltNames = builder.keyAltNames; masterKey = builder.masterKey; } } MongoExplicitEncryptOptions.java000066400000000000000000000062261414105245100365270ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2008-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import org.bson.BsonBinary; /** * Options for explicit encryption. */ public class MongoExplicitEncryptOptions { private final BsonBinary keyId; private final String keyAltName; private final String algorithm; /** * The builder for the options */ public static class Builder { private BsonBinary keyId; private String keyAltName; private String algorithm; private Builder() { } /** * Add the key identifier. * * @param keyId the key idenfifier * @return this */ public Builder keyId(final BsonBinary keyId) { this.keyId = keyId; return this; } /** * Add the key alternative name. * * @param keyAltName the key alternative name * @return this */ public Builder keyAltName(final String keyAltName) { this.keyAltName = keyAltName; return this; } /** * Add the encryption algorithm. * * @param algorithm the encryption algorithm * @return this */ public Builder algorithm(final String algorithm) { this.algorithm = algorithm; return this; } /** * Build the options. * * @return the options */ public MongoExplicitEncryptOptions build() { return new MongoExplicitEncryptOptions(this); } } /** * Create a builder for the options. * * @return the builder */ public static Builder builder() { return new Builder(); } /** * Gets the key identifier * @return the key identifier */ public BsonBinary getKeyId() { return keyId; } /** * Gets the key alternative name * @return the key alternative name */ public String getKeyAltName() { return keyAltName; } /** * Gets the encryption algorithm * @return the encryption algorithm */ public String getAlgorithm() { return algorithm; } private MongoExplicitEncryptOptions(Builder builder) { this.keyId = builder.keyId; this.keyAltName = builder.keyAltName; this.algorithm = builder.algorithm; } @Override public String toString() { return "MongoExplicitEncryptOptions{" + "keyId=" + keyId + ", keyAltName=" + keyAltName + ", algorithm='" + algorithm + "'}"; } } MongoKeyDecryptor.java000066400000000000000000000044131414105245100344450ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import java.nio.ByteBuffer; /** * An interface representing a key decryption operation using a key management service. */ public interface MongoKeyDecryptor { /** * Gets the name of the KMS provider, e.g. "aws" or "kmip" * * @return the KMS provider name */ String getKmsProvider(); /** * Gets the host name of the key management service. * * @return the host name */ String getHostName(); /** * Gets the message to send to the key management service. * *

* Clients should call this method first, and send the message on a TLS connection to a configured KMS server. *

* * @return the message to send */ ByteBuffer getMessage(); /** * Gets the number of bytes that should be received from the KMS server. * *

* After sending the message to the KMS server, clients should call this method in a loop, receiving {@code bytesNeeded} from * the KMS server and feeding those bytes to this decryptor, until {@code bytesNeeded} is 0. *

* * @return the actual number of bytes that clients should be prepared receive */ int bytesNeeded(); /** * Feed the received bytes to the decryptor. * *

* After sending the message to the KMS server, clients should call this method in a loop, receiving the number of bytes indicated by * a call to {@link #bytesNeeded()} from the KMS server and feeding those bytes to this decryptor, until {@link #bytesNeeded()} * returns 0. *

* * @param bytes the received bytes */ void feed(ByteBuffer bytes); } MongoKeyDecryptorImpl.java000066400000000000000000000073051414105245100352720ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import com.mongodb.crypt.capi.CAPI.mongocrypt_binary_t; import com.mongodb.crypt.capi.CAPI.mongocrypt_kms_ctx_t; import com.mongodb.crypt.capi.CAPI.mongocrypt_status_t; import com.sun.jna.Pointer; import com.sun.jna.ptr.PointerByReference; import java.nio.ByteBuffer; import static com.mongodb.crypt.capi.CAPI.mongocrypt_binary_destroy; import static com.mongodb.crypt.capi.CAPI.mongocrypt_binary_new; import static com.mongodb.crypt.capi.CAPI.mongocrypt_kms_ctx_bytes_needed; import static com.mongodb.crypt.capi.CAPI.mongocrypt_kms_ctx_endpoint; import static com.mongodb.crypt.capi.CAPI.mongocrypt_kms_ctx_feed; import static com.mongodb.crypt.capi.CAPI.mongocrypt_kms_ctx_get_kms_provider; import static com.mongodb.crypt.capi.CAPI.mongocrypt_kms_ctx_message; import static com.mongodb.crypt.capi.CAPI.mongocrypt_kms_ctx_status; import static com.mongodb.crypt.capi.CAPI.mongocrypt_status; import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_destroy; import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_new; import static com.mongodb.crypt.capi.CAPIHelper.toBinary; import static com.mongodb.crypt.capi.CAPIHelper.toByteBuffer; import static org.bson.assertions.Assertions.notNull; class MongoKeyDecryptorImpl implements MongoKeyDecryptor { private final mongocrypt_kms_ctx_t wrapped; MongoKeyDecryptorImpl(final mongocrypt_kms_ctx_t wrapped) { notNull("wrapped", wrapped); this.wrapped = wrapped; } @Override public String getKmsProvider() { return mongocrypt_kms_ctx_get_kms_provider(wrapped, null).toString(); } @Override public String getHostName() { PointerByReference hostNamePointerByReference = new PointerByReference(); boolean success = mongocrypt_kms_ctx_endpoint(wrapped, hostNamePointerByReference); if (!success) { throwExceptionFromStatus(); } Pointer hostNamePointer = hostNamePointerByReference.getValue(); return hostNamePointer.getString(0); } @Override public ByteBuffer getMessage() { mongocrypt_binary_t binary = mongocrypt_binary_new(); try { boolean success = mongocrypt_kms_ctx_message(wrapped, binary); if (!success) { throwExceptionFromStatus(); } return toByteBuffer(binary); } finally { mongocrypt_binary_destroy(binary); } } @Override public int bytesNeeded() { return mongocrypt_kms_ctx_bytes_needed(wrapped); } @Override public void feed(final ByteBuffer bytes) { try (BinaryHolder binaryHolder = toBinary(bytes)) { boolean success = mongocrypt_kms_ctx_feed(wrapped, binaryHolder.getBinary()); if (!success) { throwExceptionFromStatus(); } } } private void throwExceptionFromStatus() { mongocrypt_status_t status = mongocrypt_status_new(); mongocrypt_kms_ctx_status(wrapped, status); MongoCryptException e = new MongoCryptException(status); mongocrypt_status_destroy(status); throw e; } } MongoLocalKmsProviderOptions.java000066400000000000000000000040611414105245100366140ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import java.nio.ByteBuffer; import static org.bson.assertions.Assertions.notNull; /** * The options for configuring a local KMS provider. */ public class MongoLocalKmsProviderOptions { private final ByteBuffer localMasterKey; /** * Construct a builder for the options * * @return the builder */ public static Builder builder() { return new Builder(); } /** * Gets the local master key * * @return the local master key */ public ByteBuffer getLocalMasterKey() { return localMasterKey; } /** * The builder for the options */ public static class Builder { private ByteBuffer localMasterKey; private Builder() { } /** * Sets the local master key. * * @param localMasterKey the local master key * @return this */ public Builder localMasterKey(final ByteBuffer localMasterKey) { this.localMasterKey = localMasterKey; return this; } /** * Build the options. * * @return the options */ public MongoLocalKmsProviderOptions build() { return new MongoLocalKmsProviderOptions(this); } } private MongoLocalKmsProviderOptions(final Builder builder) { this.localMasterKey = notNull("Local KMS provider localMasterKey", builder.localMasterKey); } } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/SLF4JLogger.java000066400000000000000000000046441414105245100330700ustar00rootroot00000000000000 /* * Copyright 2008-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import org.slf4j.LoggerFactory; class SLF4JLogger implements Logger { private final org.slf4j.Logger delegate; SLF4JLogger(final String name) { this.delegate = LoggerFactory.getLogger(name); } @Override public String getName() { return delegate.getName(); } @Override public boolean isTraceEnabled() { return delegate.isTraceEnabled(); } @Override public void trace(final String msg) { delegate.trace(msg); } @Override public void trace(final String msg, final Throwable t) { delegate.trace(msg, t); } @Override public boolean isDebugEnabled() { return delegate.isDebugEnabled(); } @Override public void debug(final String msg) { delegate.debug(msg); } @Override public void debug(final String msg, final Throwable t) { delegate.debug(msg, t); } @Override public boolean isInfoEnabled() { return delegate.isInfoEnabled(); } @Override public void info(final String msg) { delegate.info(msg); } @Override public void info(final String msg, final Throwable t) { delegate.info(msg, t); } @Override public boolean isWarnEnabled() { return delegate.isWarnEnabled(); } @Override public void warn(final String msg) { delegate.warn(msg); } @Override public void warn(final String msg, final Throwable t) { delegate.warn(msg, t); } @Override public boolean isErrorEnabled() { return delegate.isErrorEnabled(); } @Override public void error(final String msg) { delegate.error(msg); } @Override public void error(final String msg, final Throwable t) { delegate.error(msg, t); } } SecureRandomCallback.java000066400000000000000000000035121414105245100350240ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2008-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import com.mongodb.crypt.capi.CAPI.cstring; import com.mongodb.crypt.capi.CAPI.mongocrypt_binary_t; import com.mongodb.crypt.capi.CAPI.mongocrypt_random_fn; import com.mongodb.crypt.capi.CAPI.mongocrypt_status_t; import com.sun.jna.Pointer; import java.security.SecureRandom; import static com.mongodb.crypt.capi.CAPI.MONGOCRYPT_STATUS_ERROR_CLIENT; import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_set; import static com.mongodb.crypt.capi.CAPIHelper.writeByteArrayToBinary; class SecureRandomCallback implements mongocrypt_random_fn { private final SecureRandom secureRandom; SecureRandomCallback(final SecureRandom secureRandom) { this.secureRandom = secureRandom; } @Override public boolean random(final Pointer ctx, final mongocrypt_binary_t out, final int count, final mongocrypt_status_t status) { try { byte[] randomBytes = new byte[count]; secureRandom.nextBytes(randomBytes); writeByteArrayToBinary(out, randomBytes); return true; } catch (Exception e) { mongocrypt_status_set(status, MONGOCRYPT_STATUS_ERROR_CLIENT, 0, new cstring(e.toString()), -1); return false; } } } SigningRSAESPKCSCallback.java000066400000000000000000000056411414105245100353170ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/* * Copyright 2008-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import com.mongodb.crypt.capi.CAPI.cstring; import com.mongodb.crypt.capi.CAPI.mongocrypt_binary_t; import com.mongodb.crypt.capi.CAPI.mongocrypt_hmac_fn; import com.mongodb.crypt.capi.CAPI.mongocrypt_status_t; import com.sun.jna.Pointer; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.Signature; import java.security.SignatureException; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import static com.mongodb.crypt.capi.CAPI.MONGOCRYPT_STATUS_ERROR_CLIENT; import static com.mongodb.crypt.capi.CAPI.mongocrypt_status_set; import static com.mongodb.crypt.capi.CAPIHelper.toByteArray; import static com.mongodb.crypt.capi.CAPIHelper.writeByteArrayToBinary; class SigningRSAESPKCSCallback implements mongocrypt_hmac_fn { private static final String KEY_ALGORITHM = "RSA"; private static final String SIGN_ALGORITHM = "SHA256withRSA"; SigningRSAESPKCSCallback() { } @Override public boolean hmac(final Pointer ctx, final mongocrypt_binary_t key, final mongocrypt_binary_t in, final mongocrypt_binary_t out, final mongocrypt_status_t status) { try { byte[] result = getSignature(toByteArray(key), toByteArray(in)); writeByteArrayToBinary(out, result); return true; } catch (Exception e) { mongocrypt_status_set(status, MONGOCRYPT_STATUS_ERROR_CLIENT, 0, new cstring(e.toString()), -1); return false; } } static byte[] getSignature(final byte[] privateKeyBytes, final byte[] dataToSign) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException { KeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); Signature privateSignature = Signature.getInstance(SIGN_ALGORITHM); privateSignature.initSign(privateKey); privateSignature.update(dataToSign); return privateSignature.sign(); } } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/package-info.java000066400000000000000000000011771414105245100334300ustar00rootroot00000000000000/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/000077500000000000000000000000001414105245100230655ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/java/000077500000000000000000000000001414105245100240065ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/java/com/000077500000000000000000000000001414105245100245645ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/java/com/mongodb/000077500000000000000000000000001414105245100262115ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/java/com/mongodb/crypt/000077500000000000000000000000001414105245100273525ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/java/com/mongodb/crypt/capi/000077500000000000000000000000001414105245100302665ustar00rootroot00000000000000MongoCryptTest.java000066400000000000000000000257161414105245100340260ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/java/com/mongodb/crypt/capi/* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.mongodb.crypt.capi; import com.mongodb.crypt.capi.MongoCryptContext.State; import org.bson.BsonBinary; import org.bson.BsonBinarySubType; import org.bson.BsonDocument; import org.bson.BsonString; import org.bson.RawBsonDocument; import org.bson.codecs.BsonDocumentCodec; import org.bson.codecs.DecoderContext; import org.bson.json.JsonReader; import org.junit.Test; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.URISyntaxException; import java.net.URL; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.util.Arrays; import java.util.Base64; import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @SuppressWarnings("SameParameterValue") public class MongoCryptTest { @Test public void testEncrypt() throws URISyntaxException, IOException { MongoCrypt mongoCrypt = createMongoCrypt(); assertNotNull(mongoCrypt); MongoCryptContext encryptor = mongoCrypt.createEncryptionContext("test", getResourceAsDocument("command.json")); assertEquals(State.NEED_MONGO_COLLINFO, encryptor.getState()); BsonDocument listCollectionsFilter = encryptor.getMongoOperation(); assertEquals(getResourceAsDocument("list-collections-filter.json"), listCollectionsFilter); encryptor.addMongoOperationResult(getResourceAsDocument("collection-info.json")); encryptor.completeMongoOperation(); assertEquals(State.NEED_MONGO_MARKINGS, encryptor.getState()); BsonDocument jsonSchema = encryptor.getMongoOperation(); assertEquals(getResourceAsDocument("mongocryptd-command.json"), jsonSchema); encryptor.addMongoOperationResult(getResourceAsDocument("mongocryptd-reply.json")); encryptor.completeMongoOperation(); assertEquals(State.NEED_MONGO_KEYS, encryptor.getState()); testKeyDecryptor(encryptor); assertEquals(State.READY, encryptor.getState()); RawBsonDocument encryptedDocument = encryptor.finish(); assertEquals(State.DONE, encryptor.getState()); assertEquals(getResourceAsDocument("encrypted-command.json"), encryptedDocument); encryptor.close(); mongoCrypt.close(); } @Test public void testDecrypt() throws IOException, URISyntaxException { MongoCrypt mongoCrypt = createMongoCrypt(); assertNotNull(mongoCrypt); MongoCryptContext decryptor = mongoCrypt.createDecryptionContext(getResourceAsDocument("encrypted-command-reply.json")); assertEquals(State.NEED_MONGO_KEYS, decryptor.getState()); testKeyDecryptor(decryptor); assertEquals(State.READY, decryptor.getState()); RawBsonDocument decryptedDocument = decryptor.finish(); assertEquals(State.DONE, decryptor.getState()); assertEquals(getResourceAsDocument("command-reply.json"), decryptedDocument); decryptor.close(); mongoCrypt.close(); } @Test public void testMultipleCloseCalls() { MongoCrypt mongoCrypt = createMongoCrypt(); assertNotNull(mongoCrypt); mongoCrypt.close(); mongoCrypt.close(); } @Test public void testDataKeyCreation() { MongoCrypt mongoCrypt = createMongoCrypt(); assertNotNull(mongoCrypt); List keyAltNames = Arrays.asList("first", "second"); MongoCryptContext dataKeyContext = mongoCrypt.createDataKeyContext("local", MongoDataKeyOptions.builder().masterKey(new BsonDocument()) .keyAltNames(keyAltNames) .build()); assertEquals(State.READY, dataKeyContext.getState()); RawBsonDocument dataKeyDocument = dataKeyContext.finish(); assertEquals(State.DONE, dataKeyContext.getState()); assertNotNull(dataKeyDocument); dataKeyDocument.getArray("keyAltNames").containsAll(keyAltNames); dataKeyContext.close(); mongoCrypt.close(); } @Test public void testExplicitEncryptionDecryption() throws IOException, URISyntaxException { MongoCrypt mongoCrypt = createMongoCrypt(); assertNotNull(mongoCrypt); BsonDocument documentToEncrypt = new BsonDocument("v", new BsonString("hello")); MongoExplicitEncryptOptions options = MongoExplicitEncryptOptions.builder() .keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, Base64.getDecoder().decode("YWFhYWFhYWFhYWFhYWFhYQ=="))) .algorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic") .build(); MongoCryptContext encryptor = mongoCrypt.createExplicitEncryptionContext(documentToEncrypt, options); assertEquals(State.NEED_MONGO_KEYS, encryptor.getState()); testKeyDecryptor(encryptor); assertEquals(State.READY, encryptor.getState()); RawBsonDocument encryptedDocument = encryptor.finish(); assertEquals(State.DONE, encryptor.getState()); assertEquals(getResourceAsDocument("encrypted-value.json"), encryptedDocument); MongoCryptContext decryptor = mongoCrypt.createExplicitDecryptionContext(encryptedDocument); assertEquals(State.READY, decryptor.getState()); RawBsonDocument decryptedDocument = decryptor.finish(); assertEquals(State.DONE, decryptor.getState()); assertEquals(documentToEncrypt, decryptedDocument); encryptor.close(); mongoCrypt.close(); } @Test public void testExplicitEncryptionDecryptionKeyAltName() throws IOException, URISyntaxException { MongoCrypt mongoCrypt = createMongoCrypt(); assertNotNull(mongoCrypt); BsonDocument documentToEncrypt = new BsonDocument("v", new BsonString("hello")); MongoExplicitEncryptOptions options = MongoExplicitEncryptOptions.builder() .keyAltName("altKeyName") .algorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic") .build(); MongoCryptContext encryptor = mongoCrypt.createExplicitEncryptionContext(documentToEncrypt, options); assertEquals(State.NEED_MONGO_KEYS, encryptor.getState()); testKeyDecryptor(encryptor, true); assertEquals(State.READY, encryptor.getState()); RawBsonDocument encryptedDocument = encryptor.finish(); assertEquals(State.DONE, encryptor.getState()); assertEquals(getResourceAsDocument("encrypted-value.json"), encryptedDocument); MongoCryptContext decryptor = mongoCrypt.createExplicitDecryptionContext(encryptedDocument); assertEquals(State.READY, decryptor.getState()); RawBsonDocument decryptedDocument = decryptor.finish(); assertEquals(State.DONE, decryptor.getState()); assertEquals(documentToEncrypt, decryptedDocument); encryptor.close(); mongoCrypt.close(); } private void testKeyDecryptor(final MongoCryptContext context) throws URISyntaxException, IOException { testKeyDecryptor(context, false); } private void testKeyDecryptor(final MongoCryptContext context, final boolean keyAltName) throws URISyntaxException, IOException { BsonDocument keyFilter = context.getMongoOperation(); String keyFilterJson = keyAltName ? "key-filter-keyAltName.json" : "key-filter.json"; assertEquals(getResourceAsDocument(keyFilterJson), keyFilter); context.addMongoOperationResult(getResourceAsDocument("key-document.json")); context.completeMongoOperation(); assertEquals(State.NEED_KMS, context.getState()); MongoKeyDecryptor keyDecryptor = context.nextKeyDecryptor(); assertEquals("aws", keyDecryptor.getKmsProvider()); assertEquals("kms.us-east-1.amazonaws.com:443", keyDecryptor.getHostName()); ByteBuffer keyDecryptorMessage = keyDecryptor.getMessage(); assertEquals(781, keyDecryptorMessage.remaining()); int bytesNeeded = keyDecryptor.bytesNeeded(); assertEquals(1024, bytesNeeded); keyDecryptor.feed(getHttpResourceAsByteBuffer("kms-reply.txt")); bytesNeeded = keyDecryptor.bytesNeeded(); assertEquals(0, bytesNeeded); assertNull(context.nextKeyDecryptor()); context.completeKeyDecryptors(); } private MongoCrypt createMongoCrypt() { return MongoCrypts.create(MongoCryptOptions .builder() .awsKmsProviderOptions(MongoAwsKmsProviderOptions.builder() .accessKeyId("example") .secretAccessKey("example") .build()) .localKmsProviderOptions(MongoLocalKmsProviderOptions.builder() .localMasterKey(ByteBuffer.wrap(new byte[96])) .build()) .build()); } private static BsonDocument getResourceAsDocument(final String fileName) throws URISyntaxException, IOException { URL resource = MongoCryptTest.class.getResource("/" + fileName); if (resource == null) { throw new RuntimeException("Could not find file " + fileName); } File resourceFile = new File(resource.toURI()); return new BsonDocumentCodec().decode(new JsonReader(getFileAsString(resourceFile, System.getProperty("line.separator"))), DecoderContext.builder().build()); } private static ByteBuffer getHttpResourceAsByteBuffer(final String fileName) throws URISyntaxException, IOException { URL resource = MongoCryptTest.class.getResource("/" + fileName); File resourceFile = new File(resource.toURI()); return ByteBuffer.wrap(getFileAsString(resourceFile, "\r\n").getBytes(Charset.forName("UTF-8"))); } private static String getFileAsString(final File file, String lineSeparator) throws IOException { StringBuilder stringBuilder = new StringBuilder(); String line; try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), Charset.forName("UTF-8")))) { boolean first = true; while ((line = reader.readLine()) != null) { if (!first) { stringBuilder.append(lineSeparator); } first = false; stringBuilder.append(line); } } return stringBuilder.toString(); } } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/resources/000077500000000000000000000000001414105245100250775ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/resources/collection-info.json000066400000000000000000000017241414105245100310620ustar00rootroot00000000000000{ "type": "collection", "name": "test", "idIndex": { "ns": "test.test", "name": "_id_", "key": { "_id": { "$numberInt": "1" } }, "v": { "$numberInt": "2" } }, "options": { "validator": { "$jsonSchema": { "properties": { "ssn": { "encrypt": { "keyId": { "$binary": { "base64": "YWFhYWFhYWFhYWFhYWFhYQ==", "subType": "04" } }, "type": "string", "algorithm": "AEAD_AES_CBC_HMAC_SHA512-Deterministic" } } }, "bsonType": "object" } } } }libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/resources/command-reply.json000066400000000000000000000002361414105245100305420ustar00rootroot00000000000000{ "cursor": { "firstBatch": [ { "_id": 1, "ssn": "457-55-5462" } ], "id": 0, "ns": "test.test" }, "ok": 1 } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/resources/command.json000066400000000000000000000001121414105245100274020ustar00rootroot00000000000000{ "find": "test", "filter": { "ssn": "457-55-5462" } }libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/resources/encrypted-command-reply.json000066400000000000000000000005251414105245100325360ustar00rootroot00000000000000{ "cursor" : { "firstBatch" : [ { "_id": 1, "ssn": { "$binary": "AWFhYWFhYWFhYWFhYWFhYWECRTOW9yZzNDn5dGwuqsrJQNLtgMEKaujhs9aRWRp+7Yo3JK8N8jC8P0Xjll6C1CwLsE/iP5wjOMhVv1KMMyOCSCrHorXRsb2IKPtzl2lKTqQ=", "$type": "06" } } ], "id" : 0, "ns" : "test.test" }, "ok" : 1 }libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/resources/encrypted-command.json000066400000000000000000000004101414105245100313760ustar00rootroot00000000000000{ "filter": { "ssn": { "$binary": { "base64": "AWFhYWFhYWFhYWFhYWFhYWECRTOW9yZzNDn5dGwuqsrJQNLtgMEKaujhs9aRWRp+7Yo3JK8N8jC8P0Xjll6C1CwLsE/iP5wjOMhVv1KMMyOCSCrHorXRsb2IKPtzl2lKTqQ=", "subType": "06" } } }, "find": "test" } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/resources/encrypted-value.json000066400000000000000000000002461414105245100311030ustar00rootroot00000000000000{ "v": { "$binary": "AWFhYWFhYWFhYWFhYWFhYWECW+zDjR/69eS6VtuMD5+O2lZw6JyiWOw3avI7mnUkdpKzPfvy8F/nlZrgZa2cGmQsb0TmLZuk5trldosnGKD91w==", "$type": "06" } } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/resources/json-schema.json000066400000000000000000000004361414105245100302040ustar00rootroot00000000000000{ "properties": { "ssn": { "encrypt": { "keyId": { "$binary": "YWFhYWFhYWFhYWFhYWFhYQ==", "$type": "04" }, "type": "string", "algorithm": "AEAD_AES_CBC_HMAC_SHA512-Deterministic" } } }, "bsonType": "object" }libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/resources/key-document.json000066400000000000000000000020731414105245100304000ustar00rootroot00000000000000{ "status": { "$numberInt": "1" }, "_id": { "$binary": { "base64": "YWFhYWFhYWFhYWFhYWFhYQ==", "subType": "04" } }, "masterKey": { "region": "us-east-1", "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", "provider": "aws" }, "updateDate": { "$date": { "$numberLong": "1557827033449" } }, "keyMaterial": { "$binary": { "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", "subType": "00" } }, "creationDate": { "$date": { "$numberLong": "1557827033449" } }, "keyAltNames": [ "altKeyName", "another_altname" ] } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/resources/key-filter-keyAltName.json000066400000000000000000000002221414105245100320710ustar00rootroot00000000000000{ "$or": [ { "_id": { "$in": [] } }, { "keyAltNames": { "$in": ["altKeyName"] } } ] } libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/resources/key-filter.json000066400000000000000000000003631414105245100300470ustar00rootroot00000000000000{ "$or": [ { "_id": { "$in": [ { "$binary": "YWFhYWFhYWFhYWFhYWFhYQ==", "$type": "04" } ] } }, { "keyAltNames": { "$in": [] } } ] }libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/resources/kms-reply.txt000066400000000000000000000005561414105245100275710ustar00rootroot00000000000000HTTP/1.1 200 OK x-amzn-RequestId: deeb35e5-4ecb-4bf1-9af5-84a54ff0af0e Content-Type: application/x-amz-json-1.1 Content-Length: 233 {"KeyId": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", "Plaintext": "TqhXy3tKckECjy4/ZNykMWG8amBF46isVPzeOgeusKrwheBmYaU8TMG5AHR/NeUDKukqo8hBGgogiQOVpLPkqBQHD8YkLsNbDmHoGOill5QAHnniF/Lz405bGucB5TfR"}libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/resources/list-collections-filter.json000066400000000000000000000000241414105245100325400ustar00rootroot00000000000000{ "name": "test" }libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/resources/mongocryptd-command.json000066400000000000000000000006461414105245100317610ustar00rootroot00000000000000{ "find": "test", "filter": { "ssn": "457-55-5462" }, "jsonSchema": { "properties": { "ssn": { "encrypt": { "keyId": { "$binary": "YWFhYWFhYWFhYWFhYWFhYQ==", "$type": "04" }, "type": "string", "algorithm": "AEAD_AES_CBC_HMAC_SHA512-Deterministic" } } }, "bsonType": "object" }, "isRemoteSchema": true }libmongocrypt-1.3.0/bindings/java/mongocrypt/src/test/resources/mongocryptd-reply.json000066400000000000000000000006541414105245100314750ustar00rootroot00000000000000{ "schemaRequiresEncryption": true, "ok": { "$numberInt": "1" }, "result": { "filter": { "ssn": { "$binary": { "base64": "ADgAAAAQYQABAAAABWtpABAAAAAEYWFhYWFhYWFhYWFhYWFhYQJ2AAwAAAA0NTctNTUtNTQ2MgAA", "subType": "06" } } }, "find": "test" }, "hasEncryptedPlaceholders": true }libmongocrypt-1.3.0/bindings/node/000077500000000000000000000000001414105245100171225ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/node/.clang-format000066400000000000000000000006131414105245100214750ustar00rootroot00000000000000BasedOnStyle: Google AllowShortFunctionsOnASingleLine: Empty AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false BinPackArguments: false BinPackParameters: false ColumnLimit: 100 Cpp11BracedListStyle: true DerivePointerAlignment: false IndentWidth: 4 MaxEmptyLinesToKeep: 1 NamespaceIndentation: None SpaceBeforeAssignmentOperators: true Standard: Cpp11 UseTab: Never libmongocrypt-1.3.0/bindings/node/.eslintrc000066400000000000000000000007501414105245100207500ustar00rootroot00000000000000{ "extends": [ "eslint:recommended" ], "env": { "node": true, "mocha": true, "es6": true }, "globals": { "Promise": true }, "parserOptions": { "ecmaVersion": 2017 }, "plugins": [ "prettier" ], "rules": { "prettier/prettier": ["error", { "singleQuote": true, "tabWidth": 2, "printWidth": 100 }], "no-console": 0, "eqeqeq": ["error", "always", {"null": "ignore"}], "strict": ["error", "global"] } } libmongocrypt-1.3.0/bindings/node/.evergreen/000077500000000000000000000000001414105245100211625ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/node/.evergreen/find_cmake.sh000066400000000000000000000026631414105245100236050ustar00rootroot00000000000000#!/usr/bin/env bash -x # Copied from the mongo-c-driver find_cmake () { if [ ! -z "$CMAKE" ]; then return 0 elif [ -f "/Applications/cmake-3.2.2-Darwin-x86_64/CMake.app/Contents/bin/cmake" ]; then CMAKE="/Applications/cmake-3.2.2-Darwin-x86_64/CMake.app/Contents/bin/cmake" elif [ -f "/Applications/Cmake.app/Contents/bin/cmake" ]; then CMAKE="/Applications/Cmake.app/Contents/bin/cmake" elif [ -f "/opt/cmake/bin/cmake" ]; then CMAKE="/opt/cmake/bin/cmake" elif command -v cmake 2>/dev/null; then CMAKE=cmake elif uname -a | grep -iq 'x86_64 GNU/Linux'; then curl --retry 5 https://cmake.org/files/v3.11/cmake-3.11.0-Linux-x86_64.tar.gz -sS --max-time 120 --fail --output cmake.tar.gz mkdir cmake-3.11.0 tar xzf cmake.tar.gz -C cmake-3.11.0 --strip-components=1 CMAKE=$(pwd)/cmake-3.11.0/bin/cmake fi if [ -z "$CMAKE" -o -z "$( $CMAKE --version 2>/dev/null )" ]; then # Some images have no cmake yet, or a broken cmake (see: BUILD-8570) echo "-- MAKE CMAKE --" CMAKE_INSTALL_DIR=$(readlink -f cmake-install) curl --retry 5 https://cmake.org/files/v3.11/cmake-3.11.0.tar.gz -sS --max-time 120 --fail --output cmake.tar.gz tar xzf cmake.tar.gz cd cmake-3.11.0 ./bootstrap --prefix="${CMAKE_INSTALL_DIR}" make -j8 make install cd .. CMAKE="${CMAKE_INSTALL_DIR}/bin/cmake" echo "-- DONE MAKING CMAKE --" fi } find_cmake export CMAKE=$CMAKE libmongocrypt-1.3.0/bindings/node/.evergreen/prebuild.sh000077500000000000000000000046411414105245100233340ustar00rootroot00000000000000#!/usr/bin/env bash if [ -z ${DISTRO_ID+omitted} ]; then echo "DISTRO_ID is unset" && exit 1; fi set -o errexit set +o xtrace # FLE platform matrix (as of Oct 7th 2021) # macos x86_64 (compiled on 10.14) # windows x86_64 (compiled on vs2017) # linux x86_64 (releases on RHEL7) # linux s390x # linux arm64 # Determines the OS name through uname results # Returns 'windows' 'linux' 'macos' or 'unknown' os_name() { local WINDOWS_REGEX="cygwin|windows|mingw|msys" local UNAME UNAME=$(uname | tr '[:upper:]' '[:lower:]') local OS_NAME="unknown" if [[ $UNAME =~ $WINDOWS_REGEX ]]; then OS_NAME="windows" elif [[ $UNAME == "darwin" ]]; then OS_NAME="macos" elif [[ $UNAME == "linux" ]]; then OS_NAME="linux" fi echo $OS_NAME } OS=$(os_name) get_version_at_git_rev () { local REV=$1 local VERSION VERSION=$(node -r child_process -e "console.log(JSON.parse(child_process.execSync('git show $REV:./package.json', { encoding: 'utf8' })).version);") echo "$VERSION" } run_prebuild() { if [ -z ${NODE_GITHUB_TOKEN+omitted} ]; then echo "NODE_GITHUB_TOKEN is unset" && exit 1; fi echo "Github token detected. Running prebuild." npm run prebuild -- -u "$NODE_GITHUB_TOKEN" echo "Prebuild's successfully submitted" } VERSION_AT_HEAD=$(get_version_at_git_rev "HEAD") VERSION_AT_HEAD_1=$(get_version_at_git_rev "HEAD~1") if [[ -n $NODE_FORCE_PUBLISH ]]; then echo "\$NODE_FORCE_PUBLISH=${NODE_FORCE_PUBLISH} detected" echo "Beginning prebuild" run_prebuild elif [[ "$VERSION_AT_HEAD" != "$VERSION_AT_HEAD_1" ]]; then echo "Difference is package version ($VERSION_AT_HEAD_1 -> $VERSION_AT_HEAD)" echo "Beginning prebuild" if [[ "$OS" == "linux" ]]; then # Handle limiting which linux gets to publish prebuild ARCH=$(uname -m) if [[ $DISTRO_ID == "rhel70-small" ]]; then # only publish x86_64 linux prebuilds from RHEL 7 run_prebuild elif [[ "$ARCH" != "x86_64" ]]; then # Non-x86 linux variants should just publish run_prebuild else # Non RHEL 7 linux variants should just test the prebuild task echo "Will prebuild without submit ($OS - $ARCH - $DISTRO_ID)" npm run prebuild fi exit 0 fi # Windows and MacOS run_prebuild else echo "No difference is package version ($VERSION_AT_HEAD_1 -> $VERSION_AT_HEAD)" echo "Will prebuild without submit ($OS - $DISTRO_ID)" npm run prebuild echo "Local prebuild successful." fi libmongocrypt-1.3.0/bindings/node/.evergreen/setup_environment.sh000077500000000000000000000037321414105245100253120ustar00rootroot00000000000000#!/usr/bin/env bash set -o xtrace # Write all commands first to stderr set -o errexit # Exit the script with error if any of the commands fail NODE_VERSION=14 NODE_BINDINGS_PATH="${PROJECT_DIRECTORY}/bindings/node" NODE_ARTIFACTS_PATH="${NODE_BINDINGS_PATH}/node-artifacts" NPM_CACHE_DIR="${NODE_ARTIFACTS_PATH}/npm" NPM_TMP_DIR="${NODE_ARTIFACTS_PATH}/tmp" BIN_DIR="$(pwd)/bin" NVM_WINDOWS_URL="https://github.com/coreybutler/nvm-windows/releases/download/1.1.7/nvm-noinstall.zip" NVM_URL="https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh" # create node artifacts path if needed mkdir -p ${NODE_ARTIFACTS_PATH} mkdir -p ${NPM_CACHE_DIR} mkdir -p "${NPM_TMP_DIR}" mkdir -p ${BIN_DIR} # Add mongodb toolchain to path export PATH="$BIN_DIR:/opt/mongodbtoolchain/v2/bin:$PATH" # locate cmake if [ "$OS" == "Windows_NT" ]; then CMAKE=/cygdrive/c/cmake/bin/cmake ADDITIONAL_CMAKE_FLAGS="-Thost=x64 -A x64" else chmod u+x ./.evergreen/find_cmake.sh . ./.evergreen/find_cmake.sh fi # this needs to be explicitly exported for the nvm install below export NVM_DIR="${NODE_ARTIFACTS_PATH}/nvm" mkdir -p ${NVM_DIR} # install Node.js echo "Installing Node ${NODE_LTS_NAME}" if [ "$OS" == "Windows_NT" ]; then export NVM_HOME=`cygpath -w "$NVM_DIR"` export NVM_SYMLINK=`cygpath -w "$NODE_ARTIFACTS_PATH/bin"` export PATH=`cygpath $NVM_SYMLINK`:`cygpath $NVM_HOME`:$PATH # download and install nvm curl -L $NVM_WINDOWS_URL -o nvm.zip unzip -d $NVM_DIR nvm.zip rm nvm.zip chmod 777 $NVM_DIR chmod -R a+rx $NVM_DIR cat < $NVM_DIR/settings.txt root: $NVM_HOME path: $NVM_SYMLINK EOT nvm install $NODE_VERSION nvm use $NODE_VERSION else curl -o- $NVM_URL | bash [ -s "${NVM_DIR}/nvm.sh" ] && \. "${NVM_DIR}/nvm.sh" nvm install $NODE_VERSION nvm use $NODE_VERSION fi # setup npm cache in a local directory cat < .npmrc devdir=${NPM_CACHE_DIR}/.node-gyp init-module=${NPM_CACHE_DIR}/.npm-init.js cache=${NPM_CACHE_DIR} tmp=${NPM_TMP_DIR} EOT libmongocrypt-1.3.0/bindings/node/.evergreen/test.sh000077500000000000000000000010011414105245100224700ustar00rootroot00000000000000#!/usr/bin/env bash # set -o xtrace # Write all commands first to stderr set -o errexit # Exit the script with error if any of the commands fail echo "Setting up environment" . ./.evergreen/setup_environment.sh # install node dependencies echo "Installing package dependencies (includes a static build)" . ./etc/build-static.sh # npm install # Run tests echo "Running tests" MONGODB_NODE_SKIP_LIVE_TESTS=true npm test # Run prebuild and deploy echo "Running prebuild and deploy" . ./.evergreen/prebuild.sh libmongocrypt-1.3.0/bindings/node/.gitignore000066400000000000000000000002041414105245100211060ustar00rootroot00000000000000lib-cov *.seed *.log *.csv *.dat *.out *.pid *.gz .DS_Store pids logs results node_modules build npm-debug.log .vscode deps *.tgz libmongocrypt-1.3.0/bindings/node/CHANGELOG.md000066400000000000000000000035211414105245100207340ustar00rootroot00000000000000# Changelog All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. ## [2.0.0-beta.0](https://github.com/mongodb/libmongocrypt/compare/node-v1.2.7...node-v2.0.0-beta.0) (2021-10-07) ### [1.2.7](https://github.com/mongodb/libmongocrypt/compare/node-v1.2.6...node-v1.2.7) (2021-09-14) ### [1.2.6](https://github.com/mongodb/libmongocrypt/compare/node-v1.2.5...node-v1.2.6) (2021-07-01) ### [1.2.5](https://github.com/mongodb/libmongocrypt/compare/node-v1.2.4...node-v1.2.5) (2021-06-10) ### [1.2.4](https://github.com/mongodb/libmongocrypt/compare/node-v1.2.3...node-v1.2.4) (2021-06-01) ### [1.2.3](https://github.com/mongodb/libmongocrypt/compare/node-v1.2.2...node-v1.2.3) (2021-04-06) ### [1.2.2](https://github.com/mongodb/libmongocrypt/compare/node-v1.2.1...node-v1.2.2) (2021-03-16) ### [1.2.1](https://github.com/mongodb/libmongocrypt/compare/node-v1.2.0...node-v1.2.1) (2021-02-05) ## [1.2.0](https://github.com/mongodb/libmongocrypt/compare/node-v1.1.0...node-v1.2.0) (2021-02-02) ### [1.1.1-beta.0](https://github.com/mongodb/libmongocrypt/compare/node-v1.1.0...node-v1.1.1-beta.0) (2020-12-04) # [1.1.0](https://github.com/mongodb/libmongocrypt/compare/node-v1.0.1...node-v1.1.0) (2020-06-23) ## [1.0.1](https://github.com/mongodb/libmongocrypt/compare/node-v1.0.0...1.0.1) (2019-12-31) # [1.0.0](https://github.com/mongodb/libmongocrypt/compare/node-v1.0.0-rc3.0...1.0.0) (2019-12-10) # [1.0.0-rc3.0](https://github.com/mongodb/libmongocrypt/compare/node-v1.0.0-rc2.0...1.0.0-rc3.0) (2019-12-04) # [1.0.0-rc2.0](https://github.com/mongodb/libmongocrypt/compare/node-v1.0.0-rc1.0...1.0.0-rc2.0) (2019-12-04) # [1.0.0-rc1.0](https://github.com/mongodb/libmongocrypt/compare/node-v1.0.0-rc0...1.0.0-rc1.0) (2019-12-04) libmongocrypt-1.3.0/bindings/node/LICENSE000066400000000000000000000261351414105245100201360ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. libmongocrypt-1.3.0/bindings/node/README.md000066400000000000000000000435761414105245100204200ustar00rootroot00000000000000MongoDB Client Encryption ========================= The Node.js wrapper for [`libmongocrypt`](../../README.md) ### Requirements Follow the instructions for building `libmongocrypt` [here](../../README.md#building-libmongocrypt). ### Installation Now you can install `mongodb-client-encryption` with the following: ```bash npm install mongodb-client-encryption ``` ### Testing Run the test suite using: ```bash npm test ``` # Documentation ## Classes
AutoEncrypter

An internal class to be used by the driver for auto encryption NOTE: Not meant to be instantiated directly, this is for internal use only.

ClientEncryption

The public interface for explicit client side encryption

MongoCryptError

An error indicating that something went wrong specifically with MongoDB Client Encryption

## Typedefs
KMSProviders : object

Configuration options that are used by specific KMS providers during key generation, encryption, and decryption.

AWSEncryptionKeyOptions : object

Configuration options for making an AWS encryption key

GCPEncryptionKeyOptions : object

Configuration options for making a GCP encryption key

AzureEncryptionKeyOptions : object

Configuration options for making an Azure encryption key

## AutoEncrypter An internal class to be used by the driver for auto encryption **NOTE**: Not meant to be instantiated directly, this is for internal use only. * [AutoEncrypter](#AutoEncrypter) * [new AutoEncrypter(client, [options])](#new_AutoEncrypter_new) * [~logLevel](#AutoEncrypter..logLevel) * [~AutoEncryptionOptions](#AutoEncrypter..AutoEncryptionOptions) * [~AutoEncryptionExtraOptions](#AutoEncrypter..AutoEncryptionExtraOptions) * [~logger](#AutoEncrypter..logger) ### new AutoEncrypter(client, [options]) | Param | Type | Description | | --- | --- | --- | | client | MongoClient | The client autoEncryption is enabled on | | [options] | [AutoEncryptionOptions](#AutoEncrypter..AutoEncryptionOptions) | Optional settings | Create an AutoEncrypter **Note**: Do not instantiate this class directly. Rather, supply the relevant options to a MongoClient **Note**: Supplying `options.schemaMap` provides more security than relying on JSON Schemas obtained from the server. It protects against a malicious server advertising a false JSON Schema, which could trick the client into sending unencrypted data that should be encrypted. Schemas supplied in the schemaMap only apply to configuring automatic encryption for client side encryption. Other validation rules in the JSON schema will not be enforced by the driver and will result in an error. **Example** ```js // Enabling autoEncryption via a MongoClient const { MongoClient } = require('mongodb'); const client = new MongoClient(URL, { autoEncryption: { kmsProviders: { aws: { accessKeyId: AWS_ACCESS_KEY, secretAccessKey: AWS_SECRET_KEY } } } }); await client.connect(); // From here on, the client will be encrypting / decrypting automatically ``` ### *AutoEncrypter*~logLevel The level of severity of the log message | Value | Level | |-------|-------| | 0 | Fatal Error | | 1 | Error | | 2 | Warning | | 3 | Info | | 4 | Trace | ### *AutoEncrypter*~AutoEncryptionOptions **Properties** | Name | Type | Description | | --- | --- | --- | | [keyVaultClient] | MongoClient | A `MongoClient` used to fetch keys from a key vault | | [keyVaultNamespace] | string | The namespace where keys are stored in the key vault | | [kmsProviders] | [KMSProviders](#KMSProviders) | Configuration options that are used by specific KMS providers during key generation, encryption, and decryption. | | [schemaMap] | object | A map of namespaces to a local JSON schema for encryption | | [bypassAutoEncryption] | boolean | Allows the user to bypass auto encryption, maintaining implicit decryption | | [options.logger] | [logger](#AutoEncrypter..logger) | An optional hook to catch logging messages from the underlying encryption engine | | [extraOptions] | [AutoEncryptionExtraOptions](#AutoEncrypter..AutoEncryptionExtraOptions) | Extra options related to the mongocryptd process | Configuration options for a automatic client encryption. ### *AutoEncrypter*~AutoEncryptionExtraOptions **Properties** | Name | Type | Default | Description | | --- | --- | --- | --- | | [mongocryptdURI] | string | | A local process the driver communicates with to determine how to encrypt values in a command. Defaults to "mongodb://%2Fvar%2Fmongocryptd.sock" if domain sockets are available or "mongodb://localhost:27020" otherwise | | [mongocryptdBypassSpawn] | boolean | false | If true, autoEncryption will not attempt to spawn a mongocryptd before connecting | | [mongocryptdSpawnPath] | string | | The path to the mongocryptd executable on the system | | [mongocryptdSpawnArgs] | Array.<string> | | Command line arguments to use when auto-spawning a mongocryptd | Extra options related to the mongocryptd process ### *AutoEncrypter*~logger | Param | Type | Description | | --- | --- | --- | | level | [logLevel](#AutoEncrypter..logLevel) | The level of logging. | | message | string | The message to log | A callback that is invoked with logging information from the underlying C++ Bindings. ## ClientEncryption The public interface for explicit client side encryption * [ClientEncryption](#ClientEncryption) * [new ClientEncryption(client, options)](#new_ClientEncryption_new) * _instance_ * [.createDataKey(provider, [options], [callback])](#ClientEncryption+createDataKey) * [.encrypt(value, options, [callback])](#ClientEncryption+encrypt) * [.decrypt(value, callback)](#ClientEncryption+decrypt) * _inner_ * [~dataKeyId](#ClientEncryption..dataKeyId) * [~createDataKeyCallback](#ClientEncryption..createDataKeyCallback) * [~encryptCallback](#ClientEncryption..encryptCallback) * [~decryptCallback](#ClientEncryption..decryptCallback) ### new ClientEncryption(client, options) | Param | Type | Description | | --- | --- | --- | | client | MongoClient | The client used for encryption | | options | object | Additional settings | | options.keyVaultNamespace | string | The namespace of the key vault, used to store encryption keys | | [options.keyVaultClient] | MongoClient | A `MongoClient` used to fetch keys from a key vault. Defaults to `client` | | [options.kmsProviders] | [KMSProviders](#KMSProviders) | options for specific KMS providers to use | Create a new encryption instance **Example** ```js new ClientEncryption(mongoClient, { keyVaultNamespace: 'client.encryption', kmsProviders: { local: { key: masterKey // The master key used for encryption/decryption. A 96-byte long Buffer } } }); ``` **Example** ```js new ClientEncryption(mongoClient, { keyVaultNamespace: 'client.encryption', kmsProviders: { aws: { accessKeyId: AWS_ACCESS_KEY, secretAccessKey: AWS_SECRET_KEY } } }); ``` ### *clientEncryption*.createDataKey(provider, [options], [callback]) | Param | Type | Description | | --- | --- | --- | | provider | string | The KMS provider used for this data key. Must be `'aws'`, `'azure'`, `'gcp'`, or `'local'` | | [options] | object | Options for creating the data key | | [options.masterKey] | [AWSEncryptionKeyOptions](#AWSEncryptionKeyOptions) \| [AzureEncryptionKeyOptions](#AzureEncryptionKeyOptions) \| [GCPEncryptionKeyOptions](#GCPEncryptionKeyOptions) | Idenfities a new KMS-specific key used to encrypt the new data key | | [options.keyAltNames] | Array.<string> | An optional list of string alternate names used to reference a key. If a key is created with alternate names, then encryption may refer to the key by the unique alternate name instead of by _id. | | [callback] | [createDataKeyCallback](#ClientEncryption..createDataKeyCallback) | Optional callback to invoke when key is created | Creates a data key used for explicit encryption and inserts it into the key vault namespace **Returns**: Promise \| void - If no callback is provided, returns a Promise that either resolves with [the id of the created data key](#ClientEncryption..dataKeyId), or rejects with an error. If a callback is provided, returns nothing. **Example** ```js // Using callbacks to create a local key clientEncryption.createDataKey('local', (err, dataKey) => { if (err) { // This means creating the key failed. } else { // key creation succeeded } }); ``` **Example** ```js // Using async/await to create a local key const dataKeyId = await clientEncryption.createDataKey('local'); ``` **Example** ```js // Using async/await to create an aws key const dataKeyId = await clientEncryption.createDataKey('aws', { masterKey: { region: 'us-east-1', key: 'xxxxxxxxxxxxxx' // CMK ARN here } }); ``` **Example** ```js // Using async/await to create an aws key with a keyAltName const dataKeyId = await clientEncryption.createDataKey('aws', { masterKey: { region: 'us-east-1', key: 'xxxxxxxxxxxxxx' // CMK ARN here }, keyAltNames: [ 'mySpecialKey' ] }); ``` ### *clientEncryption*.encrypt(value, options, [callback]) | Param | Type | Description | | --- | --- | --- | | value | \* | The value that you wish to serialize. Must be of a type that can be serialized into BSON | | options | object | | | [options.keyId] | [dataKeyId](#ClientEncryption..dataKeyId) | The id of the Binary dataKey to use for encryption | | [options.keyAltName] | string | A unique string name corresponding to an already existing dataKey. | | options.algorithm | | The algorithm to use for encryption. Must be either `'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'` or `AEAD_AES_256_CBC_HMAC_SHA_512-Random'` | | [callback] | [encryptCallback](#ClientEncryption..encryptCallback) | Optional callback to invoke when value is encrypted | Explicitly encrypt a provided value. Note that either `options.keyId` or `options.keyAltName` must be specified. Specifying both `options.keyId` and `options.keyAltName` is considered an error. **Returns**: Promise \| void - If no callback is provided, returns a Promise that either resolves with the encrypted value, or rejects with an error. If a callback is provided, returns nothing. **Example** ```js // Encryption with callback API function encryptMyData(value, callback) { clientEncryption.createDataKey('local', (err, keyId) => { if (err) { return callback(err); } clientEncryption.encrypt(value, { keyId, algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' }, callback); }); } ``` **Example** ```js // Encryption with async/await api async function encryptMyData(value) { const keyId = await clientEncryption.createDataKey('local'); return clientEncryption.encrypt(value, { keyId, algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' }); } ``` **Example** ```js // Encryption using a keyAltName async function encryptMyData(value) { await clientEncryption.createDataKey('local', { keyAltNames: 'mySpecialKey' }); return clientEncryption.encrypt(value, { keyAltName: 'mySpecialKey', algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' }); } ``` ### *clientEncryption*.decrypt(value, callback) | Param | Type | Description | | --- | --- | --- | | value | Buffer | An encrypted value | | callback | [decryptCallback](#ClientEncryption..decryptCallback) | Optional callback to invoke when value is decrypted | Explicitly decrypt a provided encrypted value **Returns**: Promise \| void - If no callback is provided, returns a Promise that either resolves with the decryped value, or rejects with an error. If a callback is provided, returns nothing. **Example** ```js // Decrypting value with callback API function decryptMyValue(value, callback) { clientEncryption.decrypt(value, callback); } ``` **Example** ```js // Decrypting value with async/await API async function decryptMyValue(value) { return clientEncryption.decrypt(value); } ``` ### *ClientEncryption*~dataKeyId The id of an existing dataKey. Is a bson Binary value. Can be used for [ClientEncryption.encrypt](ClientEncryption.encrypt), and can be used to directly query for the data key itself against the key vault namespace. ### *ClientEncryption*~createDataKeyCallback | Param | Type | Description | | --- | --- | --- | | [error] | Error | If present, indicates an error that occurred in the creation of the data key | | [dataKeyId] | [dataKeyId](#ClientEncryption..dataKeyId) | If present, returns the id of the created data key | ### *ClientEncryption*~encryptCallback | Param | Type | Description | | --- | --- | --- | | [err] | Error | If present, indicates an error that occurred in the process of encryption | | [result] | Buffer | If present, is the encrypted result | ### *ClientEncryption*~decryptCallback | Param | Type | Description | | --- | --- | --- | | [err] | Error | If present, indicates an error that occurred in the process of decryption | | [result] | object | If present, is the decrypted result | ## MongoCryptError An error indicating that something went wrong specifically with MongoDB Client Encryption ## KMSProviders **Properties** | Name | Type | Description | | --- | --- | --- | | [aws] | object | Configuration options for using 'aws' as your KMS provider | | [aws.accessKeyId] | string | The access key used for the AWS KMS provider | | [aws.secretAccessKey] | string | The secret access key used for the AWS KMS provider | | [local] | object | Configuration options for using 'local' as your KMS provider | | [local.key] | Buffer | The master key used to encrypt/decrypt data keys. A 96-byte long Buffer. | | [azure] | object | Configuration options for using 'azure' as your KMS provider | | [azure.tenantId] | string | The tenant ID identifies the organization for the account | | [azure.clientId] | string | The client ID to authenticate a registered application | | [azure.clientSecret] | string | The client secret to authenticate a registered application | | [azure.identityPlatformEndpoint] | string | If present, a host with optional port. E.g. "example.com" or "example.com:443". This is optional, and only needed if customer is using a non-commercial Azure instance (e.g. a government or China account, which use different URLs). Defaults to "login.microsoftonline.com" | | [gcp] | object | Configuration options for using 'gcp' as your KMS provider | | [gcp.email] | string | The service account email to authenticate | | [gcp.privateKey] | string \| Binary | A PKCS#8 encrypted key. This can either be a base64 string or a binary representation | | [gcp.endpoint] | string | If present, a host with optional port. E.g. "example.com" or "example.com:443". Defaults to "oauth2.googleapis.com" | Configuration options that are used by specific KMS providers during key generation, encryption, and decryption. ## AWSEncryptionKeyOptions **Properties** | Name | Type | Description | | --- | --- | --- | | region | string | The AWS region of the KMS | | key | string | The Amazon Resource Name (ARN) to the AWS customer master key (CMK) | | [endpoint] | string | An alternate host to send KMS requests to. May include port number | Configuration options for making an AWS encryption key ## GCPEncryptionKeyOptions **Properties** | Name | Type | Description | | --- | --- | --- | | projectId | string | GCP project id | | location | string | Location name (e.g. "global") | | keyRing | string | Key ring name | | keyName | string | Key name | | [keyVersion] | string | Key version | | [endpoint] | string | KMS URL, defaults to `https://www.googleapis.com/auth/cloudkms` | Configuration options for making a GCP encryption key ## AzureEncryptionKeyOptions **Properties** | Name | Type | Description | | --- | --- | --- | | keyName | string | Key name | | keyVaultEndpoint | string | Key vault URL, typically `.vault.azure.net` | | [keyVersion] | string | Key version | Configuration options for making an Azure encryption key libmongocrypt-1.3.0/bindings/node/binding.gyp000066400000000000000000000042421414105245100212570ustar00rootroot00000000000000{ 'targets': [{ 'target_name': 'mongocrypt', 'include_dirs': [ "main}} libmongocrypt-1.3.0/bindings/node/etc/build-static.sh000077500000000000000000000040761414105245100226270ustar00rootroot00000000000000#!/usr/bin/env bash -x DEPS_PREFIX="$(pwd)/deps" BUILD_DIR=$DEPS_PREFIX/tmp LIBMONGOCRYPT_DIR="$(pwd)/../../" TOP_DIR="$(pwd)/../../../" if [[ -z $CMAKE ]]; then CMAKE=`which cmake` fi # create relevant folders mkdir -p $DEPS_PREFIX mkdir -p $BUILD_DIR mkdir -p $BUILD_DIR/libmongocrypt-build export BSON_INSTALL_PREFIX=$DEPS_PREFIX export MONGOCRYPT_INSTALL_PREFIX=$DEPS_PREFIX pushd $DEPS_PREFIX #./deps pushd $BUILD_DIR #./deps/tmp pushd $TOP_DIR # build and install bson # NOTE: we are setting -DCMAKE_INSTALL_LIBDIR=lib to ensure that the built # files are always installed to lib instead of alternate directories like # lib64. # NOTE: On OSX, -DCMAKE_OSX_DEPLOYMENT_TARGET can be set to an OSX version # to suppress build warnings. However, doing that tends to break some # of the versions that can be built export BSON_EXTRA_CMAKE_FLAGS="-DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_OSX_DEPLOYMENT_TARGET=\"10.12\"" if [ "$OS" == "Windows_NT" ]; then export BSON_EXTRA_CMAKE_FLAGS="${BSON_EXTRA_CMAKE_FLAGS} -DCMAKE_C_FLAGS_RELWITHDEBINFO=\"/MT\"" fi . ${TOP_DIR}/libmongocrypt/.evergreen/build_install_bson.sh popd #./deps/tmp # build and install libmongocrypt pushd libmongocrypt-build #./deps/tmp/libmongocrypt-build CMAKE_FLAGS="-DDISABLE_NATIVE_CRYPTO=1 -DCMAKE_C_FLAGS=\"-fPIC\" -DCMAKE_INSTALL_LIBDIR=lib " if [ "$OS" == "Windows_NT" ]; then WINDOWS_CMAKE_FLAGS="-Thost=x64 -A x64 -DCMAKE_C_FLAGS_RELWITHDEBINFO=\"/MT\"" $CMAKE $CMAKE_FLAGS $WINDOWS_CMAKE_FLAGS -DCMAKE_PREFIX_PATH="`cygpath -w $DEPS_PREFIX`" -DCMAKE_INSTALL_PREFIX="`cygpath -w $DEPS_PREFIX`" "`cygpath -w $LIBMONGOCRYPT_DIR`" else $CMAKE $CMAKE_FLAGS -DCMAKE_PREFIX_PATH=$DEPS_PREFIX -DCMAKE_INSTALL_PREFIX=$DEPS_PREFIX -DCMAKE_OSX_DEPLOYMENT_TARGET="10.12" $LIBMONGOCRYPT_DIR fi $CMAKE --build . --target install --config RelWithDebInfo popd #./deps/tmp popd #./deps popd #./ # build the `mongodb-client-encryption` addon # note the --unsafe-perm parameter to make the build work # when running as root. See https://github.com/npm/npm/issues/3497 BUILD_TYPE=static npm install --unsafe-perm --build-from-source libmongocrypt-1.3.0/bindings/node/index.d.ts000066400000000000000000000221521414105245100210250ustar00rootroot00000000000000import type { Binary } from 'bson'; import type { MongoClient } from 'mongodb'; export type ClientEncryptionDataKeyProvider = 'aws' | 'azure' | 'gcp' | 'local'; /** * An error indicating that something went wrong specifically with MongoDB Client Encryption */ export class MongoCryptError extends Error { } export interface ClientEncryptionCreateDataKeyCallback { /** * @param error If present, indicates an error that occurred in the creation of the data key * @param dataKeyId If present, returns the id of the created data key */ (error?: Error, dataKeyId?: Binary): void; } export interface ClientEncryptionEncryptCallback { /** * @param error If present, indicates an error that occurred in the process of encryption * @param result If present, is the encrypted result */ (error?: Error, result?: Binary): void; } export interface ClientEncryptionDecryptCallback { /** * @param error If present, indicates an error that occurred in the process of decryption * @param result If present, is the decrypted result */ (error?: Error, result?: any): void; } /** * Configuration options that are used by specific KMS providers during key generation, encryption, and decryption. */ export interface KMSProviders { /** * Configuration options for using 'aws' as your KMS provider */ aws?: { /** * The access key used for the AWS KMS provider */ accessKeyId: string; /** * The secret access key used for the AWS KMS provider */ secretAccessKey: string; /** * An optional AWS session token that will be used as the * X-Amz-Security-Token header for AWS requests. */ sessionToken?: string; }; /** * Configuration options for using 'local' as your KMS provider */ local?: { /** * The master key used to encrypt/decrypt data keys. * A 96-byte long Buffer or base64 encoded string. */ key: Buffer | string; }; /** * Configuration options for using 'azure' as your KMS provider */ azure?: { /** * The tenant ID identifies the organization for the account */ tenantId: string; /** * The client ID to authenticate a registered application */ clientId: string; /** * The client secret to authenticate a registered application */ clientSecret: string; /** * If present, a host with optional port. E.g. "example.com" or "example.com:443". * This is optional, and only needed if customer is using a non-commercial Azure instance * (e.g. a government or China account, which use different URLs). * Defaults to "login.microsoftonline.com" */ identityPlatformEndpoint?: string | undefined; }; /** * Configuration options for using 'gcp' as your KMS provider */ gcp?: { /** * The service account email to authenticate */ email: string; /** * A PKCS#8 encrypted key. This can either be a base64 string or a binary representation */ privateKey: string | Buffer; /** * If present, a host with optional port. E.g. "example.com" or "example.com:443". * Defaults to "oauth2.googleapis.com" */ endpoint?: string | undefined; } } /** * Additional settings to provide when creating a new `ClientEncryption` instance. */ export interface ClientEncryptionOptions { /** * The namespace of the key vault, used to store encryption keys */ keyVaultNamespace: string; /** * A MongoClient used to fetch keys from a key vault. Defaults to client. */ keyVaultClient?: MongoClient | undefined; /** * Options for specific KMS providers to use */ kmsProviders?: KMSProviders; } /** * Configuration options for making an AWS encryption key */ export interface AWSEncryptionKeyOptions { /** * The AWS region of the KMS */ region: string; /** * The Amazon Resource Name (ARN) to the AWS customer master key (CMK) */ key: string; /** * An alternate host to send KMS requests to. May include port number. */ endpoint?: string | undefined; } /** * Configuration options for making an AWS encryption key */ export interface GCPEncryptionKeyOptions { /** * GCP project ID */ projectId: string; /** * Location name (e.g. "global") */ location: string; /** * Key ring name */ keyRing: string; /** * Key name */ keyName: string; /** * Key version */ keyVersion?: string | undefined; /** * KMS URL, defaults to `https://www.googleapis.com/auth/cloudkms` */ endpoint?: string | undefined; } /** * Configuration options for making an Azure encryption key */ export interface AzureEncryptionKeyOptions { /** * Key name */ keyName: string; /** * Key vault URL, typically `.vault.azure.net` */ keyVaultEndpoint: string; /** * Key version */ keyVersion?: string | undefined; } /** * Options to provide when creating a new data key. */ export interface ClientEncryptionCreateDataKeyProviderOptions { /** * Idenfities a new KMS-specific key used to encrypt the new data key */ masterKey?: AWSEncryptionKeyOptions | AzureEncryptionKeyOptions | GCPEncryptionKeyOptions | undefined; /** * An optional list of string alternate names used to reference a key. * If a key is created with alternate names, then encryption may refer to the key by the unique alternate name instead of by _id. */ keyAltNames?: string[] | undefined; } /** * Options to provide when encrypting data. */ export interface ClientEncryptionEncryptOptions { /** * The algorithm to use for encryption. */ algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' | 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'; /** * The id of the Binary dataKey to use for encryption */ keyId?: Binary | undefined; /** * A unique string name corresponding to an already existing dataKey. */ keyAltName?: string | undefined; } /** * The public interface for explicit client side encrption. */ export class ClientEncryption { /** * Create a new encryption instance. * @param client The client used for encryption * @param options Additional settings */ constructor(client: MongoClient, options: ClientEncryptionOptions); /** * Creates a data key used for explicit encryption and inserts it into the key vault namespace * @param provider The KMS provider used for this data key. Must be `'aws'`, `'azure'`, `'gcp'`, or `'local'` */ createDataKey( provider: ClientEncryptionDataKeyProvider ): Promise; /** * Creates a data key used for explicit encryption and inserts it into the key vault namespace * @param provider The KMS provider used for this data key. Must be `'aws'`, `'azure'`, `'gcp'`, or `'local'` * @param options Options for creating the data key */ createDataKey( provider: ClientEncryptionDataKeyProvider, options: ClientEncryptionCreateDataKeyProviderOptions ): Promise; /** * Creates a data key used for explicit encryption and inserts it into the key vault namespace * @param provider The KMS provider used for this data key. Must be `'aws'`, `'azure'`, `'gcp'`, or `'local'` * @param callback Callback to invoke when key is created */ createDataKey( provider: ClientEncryptionDataKeyProvider, callback: ClientEncryptionCreateDataKeyCallback ): void; /** * Creates a data key used for explicit encryption and inserts it into the key vault namespace * @param provider The KMS provider used for this data key. Must be `'aws'`, `'azure'`, `'gcp'`, or `'local'` * @param options Options for creating the data key * @param callback Callback to invoke when key is created */ createDataKey( provider: ClientEncryptionDataKeyProvider, options: ClientEncryptionCreateDataKeyProviderOptions, callback: ClientEncryptionCreateDataKeyCallback ): void; /** * Explicitly encrypt a provided value. * Note that either options.keyId or options.keyAltName must be specified. * Specifying both options.keyId and options.keyAltName is considered an error. * @param value The value that you wish to serialize. Must be of a type that can be serialized into BSON * @param options */ encrypt( value: any, options: ClientEncryptionEncryptOptions ): Promise; /** * Explicitly encrypt a provided value. * Note that either options.keyId or options.keyAltName must be specified. * Specifying both options.keyId and options.keyAltName is considered an error. * @param value The value that you wish to serialize. Must be of a type that can be serialized into BSON * @param options * @param callback Callback to invoke when value is encrypted */ encrypt( value: any, options: ClientEncryptionEncryptOptions, callback: ClientEncryptionEncryptCallback ): void; /** * Explicitly decrypt a provided encrypted value * @param value An encrypted value */ decrypt( value: Binary ): Promise; /** * Explicitly decrypt a provided encrypted value * @param value An encrypted value * @param callback Callback to invoke when value is decrypted */ decrypt( value: Binary, callback: ClientEncryptionDecryptCallback ): void; } libmongocrypt-1.3.0/bindings/node/index.js000066400000000000000000000021171414105245100205700ustar00rootroot00000000000000'use strict'; let defaultModule; function loadDefaultModule() { if (!defaultModule) { defaultModule = extension(require('mongodb')); } return defaultModule; } const MongoCryptError = require('./lib/common').MongoCryptError; function extension(mongodb) { const modules = { mongodb }; modules.stateMachine = require('./lib/stateMachine')(modules); modules.autoEncrypter = require('./lib/autoEncrypter')(modules); modules.clientEncryption = require('./lib/clientEncryption')(modules); return { AutoEncrypter: modules.autoEncrypter.AutoEncrypter, ClientEncryption: modules.clientEncryption.ClientEncryption, MongoCryptError }; } module.exports = { extension, MongoCryptError, get AutoEncrypter() { const m = loadDefaultModule(); delete module.exports.AutoEncrypter; module.exports.AutoEncrypter = m.AutoEncrypter; return m.AutoEncrypter; }, get ClientEncryption() { const m = loadDefaultModule(); delete module.exports.ClientEncryption; module.exports.ClientEncryption = m.ClientEncryption; return m.ClientEncryption; } }; libmongocrypt-1.3.0/bindings/node/lib/000077500000000000000000000000001414105245100176705ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/node/lib/autoEncrypter.js000066400000000000000000000216531414105245100231010ustar00rootroot00000000000000'use strict'; module.exports = function(modules) { const mc = require('bindings')('mongocrypt'); const common = require('./common'); const databaseNamespace = common.databaseNamespace; const StateMachine = modules.stateMachine.StateMachine; const MongocryptdManager = require('./mongocryptdManager').MongocryptdManager; const MongoClient = modules.mongodb.MongoClient; const MongoError = modules.mongodb.MongoError; const cryptoCallbacks = require('./cryptoCallbacks'); /** * Configuration options for a automatic client encryption. * * @typedef {Object} AutoEncrypter~AutoEncryptionOptions * @property {MongoClient} [keyVaultClient] A `MongoClient` used to fetch keys from a key vault * @property {string} [keyVaultNamespace] The namespace where keys are stored in the key vault * @property {KMSProviders} [kmsProviders] Configuration options that are used by specific KMS providers during key generation, encryption, and decryption. * @property {object} [schemaMap] A map of namespaces to a local JSON schema for encryption * @property {boolean} [bypassAutoEncryption] Allows the user to bypass auto encryption, maintaining implicit decryption * @property {AutoEncrypter~logger} [options.logger] An optional hook to catch logging messages from the underlying encryption engine * @property {AutoEncrypter~AutoEncryptionExtraOptions} [extraOptions] Extra options related to the mongocryptd process */ /** * Extra options related to the mongocryptd process * @typedef {object} AutoEncrypter~AutoEncryptionExtraOptions * @property {string} [mongocryptdURI] A local process the driver communicates with to determine how to encrypt values in a command. Defaults to "mongodb://%2Fvar%2Fmongocryptd.sock" if domain sockets are available or "mongodb://localhost:27020" otherwise * @property {boolean} [mongocryptdBypassSpawn=false] If true, autoEncryption will not attempt to spawn a mongocryptd before connecting * @property {string} [mongocryptdSpawnPath] The path to the mongocryptd executable on the system * @property {string[]} [mongocryptdSpawnArgs] Command line arguments to use when auto-spawning a mongocryptd */ /** * @callback AutoEncrypter~logger * @description A callback that is invoked with logging information from * the underlying C++ Bindings. * @param {AutoEncrypter~logLevel} level The level of logging. * @param {string} message The message to log */ /** * @name AutoEncrypter~logLevel * @enum {number} * @description * The level of severity of the log message * * | Value | Level | * |-------|-------| * | 0 | Fatal Error | * | 1 | Error | * | 2 | Warning | * | 3 | Info | * | 4 | Trace | */ /** * @classdesc An internal class to be used by the driver for auto encryption * **NOTE**: Not meant to be instantiated directly, this is for internal use only. */ class AutoEncrypter { /** * Create an AutoEncrypter * * **Note**: Do not instantiate this class directly. Rather, supply the relevant options to a MongoClient * * **Note**: Supplying `options.schemaMap` provides more security than relying on JSON Schemas obtained from the server. * It protects against a malicious server advertising a false JSON Schema, which could trick the client into sending unencrypted data that should be encrypted. * Schemas supplied in the schemaMap only apply to configuring automatic encryption for client side encryption. * Other validation rules in the JSON schema will not be enforced by the driver and will result in an error. * @param {MongoClient} client The client autoEncryption is enabled on * @param {AutoEncrypter~AutoEncryptionOptions} [options] Optional settings * * @example * // Enabling autoEncryption via a MongoClient * const { MongoClient } = require('mongodb'); * const client = new MongoClient(URL, { * autoEncryption: { * kmsProviders: { * aws: { * accessKeyId: AWS_ACCESS_KEY, * secretAccessKey: AWS_SECRET_KEY * } * } * } * }); * * await client.connect(); * // From here on, the client will be encrypting / decrypting automatically */ constructor(client, options) { this._client = client; this._bson = options.bson || client.topology.bson; this._bypassEncryption = options.bypassAutoEncryption === true; if (!this._bypassAutoEncryption) { this._mongocryptdManager = new MongocryptdManager(options.extraOptions); this._mongocryptdClient = new MongoClient(this._mongocryptdManager.uri, { useNewUrlParser: true, useUnifiedTopology: true, serverSelectionTimeoutMS: 1000 }); } this._keyVaultNamespace = options.keyVaultNamespace || 'admin.datakeys'; this._keyVaultClient = options.keyVaultClient || client; this._metaDataClient = options.metadataClient || client; const mongoCryptOptions = {}; if (options.schemaMap) { mongoCryptOptions.schemaMap = Buffer.isBuffer(options.schemaMap) ? options.schemaMap : this._bson.serialize(options.schemaMap); } if (options.kmsProviders) { mongoCryptOptions.kmsProviders = !Buffer.isBuffer(options.kmsProviders) ? this._bson.serialize(options.kmsProviders) : options.kmsProviders; } if (options.logger) { mongoCryptOptions.logger = options.logger; } Object.assign(mongoCryptOptions, { cryptoCallbacks }); this._mongocrypt = new mc.MongoCrypt(mongoCryptOptions); this._contextCounter = 0; } /** * @ignore * @param {Function} callback Invoked when the mongocryptd client either successfully connects or errors */ init(callback) { if (this._bypassEncryption) { return callback(); } const _callback = (err, res) => { if ( err && err.message && (err.message.match(/timed out after/) || err.message.match(/ENOTFOUND/)) ) { callback( new MongoError( 'Unable to connect to `mongocryptd`, please make sure it is running or in your PATH for auto-spawn' ) ); return; } callback(err, res); }; if (this._mongocryptdManager.bypassSpawn) { return this._mongocryptdClient.connect(_callback); } this._mongocryptdManager.spawn(() => this._mongocryptdClient.connect(_callback)); } /** * @ignore * @param {Function} callback Invoked when the mongocryptd client either successfully disconnects or errors */ teardown(force, callback) { this._mongocryptdClient.close(force, callback); } /** * @ignore * Encrypt a command for a given namespace. * * @param {string} ns The namespace for this encryption context * @param {object} cmd The command to encrypt * @param {Function} callback */ encrypt(ns, cmd, options, callback) { if (typeof ns !== 'string') { throw new TypeError('Parameter `ns` must be a string'); } if (typeof cmd !== 'object') { throw new TypeError('Parameter `cmd` must be an object'); } if (typeof options === 'function' && callback == null) { callback = options; options = {}; } // If `bypassAutoEncryption` has been specified, don't encrypt if (this._bypassEncryption) { callback(undefined, cmd); return; } const bson = this._bson; const commandBuffer = Buffer.isBuffer(cmd) ? cmd : bson.serialize(cmd, options); let context; try { context = this._mongocrypt.makeEncryptionContext(databaseNamespace(ns), commandBuffer); } catch (err) { callback(err, null); return; } // TODO: should these be accessors from the addon? context.id = this._contextCounter++; context.ns = ns; context.document = cmd; const stateMachine = new StateMachine(Object.assign({ bson }, options)); stateMachine.execute(this, context, callback); } /** * @ignore * Decrypt a command response * * @param {Buffer} buffer * @param {Function} callback */ decrypt(response, options, callback) { if (typeof options === 'function' && callback == null) { callback = options; options = {}; } const bson = this._bson; const buffer = Buffer.isBuffer(response) ? response : bson.serialize(response, options); let context; try { context = this._mongocrypt.makeDecryptionContext(buffer); } catch (err) { callback(err, null); return; } // TODO: should this be an accessor from the addon? context.id = this._contextCounter++; const stateMachine = new StateMachine(Object.assign({ bson }, options)); stateMachine.execute(this, context, callback); } } return { AutoEncrypter }; }; libmongocrypt-1.3.0/bindings/node/lib/clientEncryption.js000066400000000000000000000355011414105245100235630ustar00rootroot00000000000000'use strict'; module.exports = function(modules) { const mc = require('bindings')('mongocrypt'); const common = require('./common'); const databaseNamespace = common.databaseNamespace; const collectionNamespace = common.collectionNamespace; const promiseOrCallback = common.promiseOrCallback; const StateMachine = modules.stateMachine.StateMachine; const cryptoCallbacks = require('./cryptoCallbacks'); /** * @typedef {object} KMSProviders * @description Configuration options that are used by specific KMS providers during key generation, encryption, and decryption. * @property {object} [aws] Configuration options for using 'aws' as your KMS provider * @property {string} [aws.accessKeyId] The access key used for the AWS KMS provider * @property {string} [aws.secretAccessKey] The secret access key used for the AWS KMS provider * @property {object} [local] Configuration options for using 'local' as your KMS provider * @property {Buffer} [local.key] The master key used to encrypt/decrypt data keys. A 96-byte long Buffer. * @property {object} [azure] Configuration options for using 'azure' as your KMS provider * @property {string} [azure.tenantId] The tenant ID identifies the organization for the account * @property {string} [azure.clientId] The client ID to authenticate a registered application * @property {string} [azure.clientSecret] The client secret to authenticate a registered application * @property {string} [azure.identityPlatformEndpoint] If present, a host with optional port. E.g. "example.com" or "example.com:443". This is optional, and only needed if customer is using a non-commercial Azure instance (e.g. a government or China account, which use different URLs). Defaults to "login.microsoftonline.com" * @property {object} [gcp] Configuration options for using 'gcp' as your KMS provider * @property {string} [gcp.email] The service account email to authenticate * @property {string|Binary} [gcp.privateKey] A PKCS#8 encrypted key. This can either be a base64 string or a binary representation * @property {string} [gcp.endpoint] If present, a host with optional port. E.g. "example.com" or "example.com:443". Defaults to "oauth2.googleapis.com" */ /** * The public interface for explicit client side encryption */ class ClientEncryption { /** * Create a new encryption instance * * @param {MongoClient} client The client used for encryption * @param {object} options Additional settings * @param {string} options.keyVaultNamespace The namespace of the key vault, used to store encryption keys * @param {MongoClient} [options.keyVaultClient] A `MongoClient` used to fetch keys from a key vault. Defaults to `client` * @param {KMSProviders} [options.kmsProviders] options for specific KMS providers to use * * @example * new ClientEncryption(mongoClient, { * keyVaultNamespace: 'client.encryption', * kmsProviders: { * local: { * key: masterKey // The master key used for encryption/decryption. A 96-byte long Buffer * } * } * }); * * @example * new ClientEncryption(mongoClient, { * keyVaultNamespace: 'client.encryption', * kmsProviders: { * aws: { * accessKeyId: AWS_ACCESS_KEY, * secretAccessKey: AWS_SECRET_KEY * } * } * }); */ constructor(client, options) { this._client = client; this._bson = options.bson || client.topology.bson; if (options.keyVaultNamespace == null) { throw new TypeError('Missing required option `keyVaultNamespace`'); } Object.assign(options, { cryptoCallbacks }); // kmsProviders will be parsed by libmongocrypt, must be provided as BSON binary data if (options.kmsProviders && !Buffer.isBuffer(options.kmsProviders)) { options.kmsProviders = this._bson.serialize(options.kmsProviders); } this._keyVaultNamespace = options.keyVaultNamespace; this._keyVaultClient = options.keyVaultClient || client; this._mongoCrypt = new mc.MongoCrypt(options); } /** * @typedef {Binary} ClientEncryption~dataKeyId * @description The id of an existing dataKey. Is a bson Binary value. * Can be used for {@link ClientEncryption.encrypt}, and can be used to directly * query for the data key itself against the key vault namespace. */ /** * @callback ClientEncryption~createDataKeyCallback * @param {Error} [error] If present, indicates an error that occurred in the creation of the data key * @param {ClientEncryption~dataKeyId} [dataKeyId] If present, returns the id of the created data key */ /** * @typedef {object} AWSEncryptionKeyOptions * @description Configuration options for making an AWS encryption key * @property {string} region The AWS region of the KMS * @property {string} key The Amazon Resource Name (ARN) to the AWS customer master key (CMK) * @property {string} [endpoint] An alternate host to send KMS requests to. May include port number */ /** * @typedef {object} GCPEncryptionKeyOptions * @description Configuration options for making a GCP encryption key * @property {string} projectId GCP project id * @property {string} location Location name (e.g. "global") * @property {string} keyRing Key ring name * @property {string} keyName Key name * @property {string} [keyVersion] Key version * @property {string} [endpoint] KMS URL, defaults to `https://www.googleapis.com/auth/cloudkms` */ /** * @typedef {object} AzureEncryptionKeyOptions * @description Configuration options for making an Azure encryption key * @property {string} keyName Key name * @property {string} keyVaultEndpoint Key vault URL, typically `.vault.azure.net` * @property {string} [keyVersion] Key version */ /** * Creates a data key used for explicit encryption and inserts it into the key vault namespace * * @param {string} provider The KMS provider used for this data key. Must be `'aws'`, `'azure'`, `'gcp'`, or `'local'` * @param {object} [options] Options for creating the data key * @param {AWSEncryptionKeyOptions|AzureEncryptionKeyOptions|GCPEncryptionKeyOptions} [options.masterKey] Idenfities a new KMS-specific key used to encrypt the new data key * @param {string[]} [options.keyAltNames] An optional list of string alternate names used to reference a key. If a key is created with alternate names, then encryption may refer to the key by the unique alternate name instead of by _id. * @param {ClientEncryption~createDataKeyCallback} [callback] Optional callback to invoke when key is created * @returns {Promise|void} If no callback is provided, returns a Promise that either resolves with {@link ClientEncryption~dataKeyId the id of the created data key}, or rejects with an error. If a callback is provided, returns nothing. * @example * // Using callbacks to create a local key * clientEncryption.createDataKey('local', (err, dataKey) => { * if (err) { * // This means creating the key failed. * } else { * // key creation succeeded * } * }); * * @example * // Using async/await to create a local key * const dataKeyId = await clientEncryption.createDataKey('local'); * * @example * // Using async/await to create an aws key * const dataKeyId = await clientEncryption.createDataKey('aws', { * masterKey: { * region: 'us-east-1', * key: 'xxxxxxxxxxxxxx' // CMK ARN here * } * }); * * @example * // Using async/await to create an aws key with a keyAltName * const dataKeyId = await clientEncryption.createDataKey('aws', { * masterKey: { * region: 'us-east-1', * key: 'xxxxxxxxxxxxxx' // CMK ARN here * }, * keyAltNames: [ 'mySpecialKey' ] * }); */ createDataKey(provider, options, callback) { if (typeof options === 'function') { callback = options; options = {}; } if (typeof options === 'undefined') { options = {}; } const bson = this._bson; const dataKey = Object.assign({ provider }, options.masterKey); if (options.keyAltNames && !Array.isArray(options.keyAltNames)) { throw new TypeError( `Option "keyAltNames" must be an array of strings, but was of type ${typeof options.keyAltNames}.` ); } let keyAltNames = undefined; if (options.keyAltNames && options.keyAltNames.length > 0) { keyAltNames = options.keyAltNames.map((keyAltName, i) => { if (typeof keyAltName !== 'string') { throw new TypeError( `Option "keyAltNames" must be an array of strings, but item at index ${i} was of type ${typeof keyAltName}` ); } return bson.serialize({ keyAltName }); }); } const dataKeyBson = bson.serialize(dataKey); const context = this._mongoCrypt.makeDataKeyContext(dataKeyBson, { keyAltNames }); const stateMachine = new StateMachine({ bson }); return promiseOrCallback(callback, cb => { stateMachine.execute(this, context, (err, dataKey) => { if (err) { cb(err, null); return; } const dbName = databaseNamespace(this._keyVaultNamespace); const collectionName = collectionNamespace(this._keyVaultNamespace); this._keyVaultClient .db(dbName) .collection(collectionName) .insertOne(dataKey, { writeConcern: { w: 'majority' } }, (err, result) => { if (err) { cb(err, null); return; } cb(null, result.insertedId); }); }); }); } /** * @callback ClientEncryption~encryptCallback * @param {Error} [err] If present, indicates an error that occurred in the process of encryption * @param {Buffer} [result] If present, is the encrypted result */ /** * Explicitly encrypt a provided value. Note that either `options.keyId` or `options.keyAltName` must * be specified. Specifying both `options.keyId` and `options.keyAltName` is considered an error. * * @param {*} value The value that you wish to serialize. Must be of a type that can be serialized into BSON * @param {object} options * @param {ClientEncryption~dataKeyId} [options.keyId] The id of the Binary dataKey to use for encryption * @param {string} [options.keyAltName] A unique string name corresponding to an already existing dataKey. * @param {} options.algorithm The algorithm to use for encryption. Must be either `'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'` or `AEAD_AES_256_CBC_HMAC_SHA_512-Random'` * @param {ClientEncryption~encryptCallback} [callback] Optional callback to invoke when value is encrypted * @returns {Promise|void} If no callback is provided, returns a Promise that either resolves with the encrypted value, or rejects with an error. If a callback is provided, returns nothing. * * @example * // Encryption with callback API * function encryptMyData(value, callback) { * clientEncryption.createDataKey('local', (err, keyId) => { * if (err) { * return callback(err); * } * clientEncryption.encrypt(value, { keyId, algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' }, callback); * }); * } * * @example * // Encryption with async/await api * async function encryptMyData(value) { * const keyId = await clientEncryption.createDataKey('local'); * return clientEncryption.encrypt(value, { keyId, algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' }); * } * * @example * // Encryption using a keyAltName * async function encryptMyData(value) { * await clientEncryption.createDataKey('local', { keyAltNames: 'mySpecialKey' }); * return clientEncryption.encrypt(value, { keyAltName: 'mySpecialKey', algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' }); * } */ encrypt(value, options, callback) { const bson = this._bson; const valueBuffer = bson.serialize({ v: value }); const contextOptions = Object.assign({}, options); if (options.keyId) { contextOptions.keyId = options.keyId.buffer; } if (options.keyAltName) { const keyAltName = options.keyAltName; if (options.keyId) { throw new TypeError(`"options" cannot contain both "keyId" and "keyAltName"`); } const keyAltNameType = typeof keyAltName; if (keyAltNameType !== 'string') { throw new TypeError( `"options.keyAltName" must be of type string, but was of type ${keyAltNameType}` ); } contextOptions.keyAltName = bson.serialize({ keyAltName }); } const stateMachine = new StateMachine({ bson }); const context = this._mongoCrypt.makeExplicitEncryptionContext(valueBuffer, contextOptions); return promiseOrCallback(callback, cb => { stateMachine.execute(this, context, (err, result) => { if (err) { cb(err, null); return; } cb(null, result.v); }); }); } /** * @callback ClientEncryption~decryptCallback * @param {Error} [err] If present, indicates an error that occurred in the process of decryption * @param {object} [result] If present, is the decrypted result */ /** * Explicitly decrypt a provided encrypted value * * @param {Buffer} value An encrypted value * @param {ClientEncryption~decryptCallback} callback Optional callback to invoke when value is decrypted * @returns {Promise|void} If no callback is provided, returns a Promise that either resolves with the decryped value, or rejects with an error. If a callback is provided, returns nothing. * * @example * // Decrypting value with callback API * function decryptMyValue(value, callback) { * clientEncryption.decrypt(value, callback); * } * * @example * // Decrypting value with async/await API * async function decryptMyValue(value) { * return clientEncryption.decrypt(value); * } */ decrypt(value, callback) { const bson = this._bson; const valueBuffer = bson.serialize({ v: value }); const context = this._mongoCrypt.makeExplicitDecryptionContext(valueBuffer); const stateMachine = new StateMachine({ bson }); return promiseOrCallback(callback, cb => { stateMachine.execute(this, context, (err, result) => { if (err) { cb(err, null); return; } cb(null, result.v); }); }); } } return { ClientEncryption }; }; libmongocrypt-1.3.0/bindings/node/lib/common.js000066400000000000000000000045131414105245100215210ustar00rootroot00000000000000'use strict'; /** * @ignore * Helper function for logging. Enabled by setting the environment flag MONGODB_CRYPT_DEBUG. * @param {*} msg Anything you want to be logged. */ function debug(msg) { if (process.env.MONGODB_CRYPT_DEBUG) { console.log(msg); } } /** * @ignore * Gets the database portion of a namespace string * @param {string} ns A string in the format of a namespace (database.collection) * @returns {string} The database portion of the namespace */ function databaseNamespace(ns) { return ns.split('.')[0]; } /** * @ignore * Gets the colleciton portion of a namespace string * @param {string} ns A string in the format of a namespace (database.collection) * @returns {string} The collection portion of the namespace */ function collectionNamespace(ns) { return ns .split('.') .slice(1) .join('.'); } /** * @class * An error indicating that something went wrong specifically with MongoDB Client Encryption */ class MongoCryptError extends Error { constructor(message) { super(message); this.name = 'MongoCryptError'; Error.captureStackTrace(this, this.constructor); } } /** * @ignore * A helper function. Invokes a function that takes a callback as the final * parameter. If a callback is supplied, then it is passed to the function. * If not, a Promise is returned that resolves/rejects with the result of the * callback * @param {Function} [callback] an optional callback. * @param {Function} fn A function that takes a callback * @returns {Promise|void} Returns nothing if a callback is supplied, else returns a Promise. */ function promiseOrCallback(callback, fn) { if (typeof callback === 'function') { fn(function(err) { if (err != null) { try { callback(err); } catch (error) { return process.nextTick(() => { throw error; }); } return; } callback.apply(this, arguments); }); return; } return new Promise((resolve, reject) => { fn(function(err, res) { if (err != null) { return reject(err); } if (arguments.length > 2) { return resolve(Array.prototype.slice.call(arguments, 1)); } resolve(res); }); }); } module.exports = { debug, databaseNamespace, collectionNamespace, MongoCryptError, promiseOrCallback }; libmongocrypt-1.3.0/bindings/node/lib/cryptoCallbacks.js000066400000000000000000000036371414105245100233570ustar00rootroot00000000000000'use strict'; const crypto = require('crypto'); function aes256CbcEncryptHook(key, iv, input, output) { let result; try { let cipher = crypto.createCipheriv('aes-256-cbc', key, iv); cipher.setAutoPadding(false); result = cipher.update(input); } catch (e) { return e; } result.copy(output); return result.length; } function aes256CbcDecryptHook(key, iv, input, output) { let result; try { let cipher = crypto.createDecipheriv('aes-256-cbc', key, iv); cipher.setAutoPadding(false); result = cipher.update(input); } catch (e) { return e; } result.copy(output); return result.length; } function randomHook(buffer, count) { try { crypto.randomFillSync(buffer, 0, count); } catch (e) { return e; } return count; } function sha256Hook(input, output) { let result; try { result = crypto .createHash('sha256') .update(input) .digest(); } catch (e) { return e; } result.copy(output); return result.length; } function makeHmacHook(algorithm) { return (key, input, output) => { let result; try { result = crypto .createHmac(algorithm, key) .update(input) .digest(); } catch (e) { return e; } result.copy(output); return result.length; }; } function signRsaSha256Hook(key, input, output) { let result; try { const signer = crypto.createSign('sha256WithRSAEncryption'); const privateKey = Buffer.from( `-----BEGIN PRIVATE KEY-----\n${key.toString('base64')}\n-----END PRIVATE KEY-----\n` ); result = signer .update(input) .end() .sign(privateKey); } catch (e) { return e; } result.copy(output); return result.length; } module.exports = { aes256CbcEncryptHook, aes256CbcDecryptHook, randomHook, hmacSha512Hook: makeHmacHook('sha512'), hmacSha256Hook: makeHmacHook('sha256'), sha256Hook, signRsaSha256Hook }; libmongocrypt-1.3.0/bindings/node/lib/mongocryptdManager.js000066400000000000000000000040611414105245100240670ustar00rootroot00000000000000'use strict'; const spawn = require('child_process').spawn; /** * @ignore * An internal class that handles spawning a mongocryptd. */ class MongocryptdManager { /** * @ignore * Creates a new Mongocryptd Manager * @param {AutoEncrypter~AutoEncryptionExtraOptions} [extraOptions] extra options that determine how/when to spawn a mongocryptd */ constructor(extraOptions) { extraOptions = extraOptions || {}; // TODO: this is not actually supported by the spec, so we should clarify // with the spec or get rid of this if (extraOptions.mongocryptdURI) { this.uri = extraOptions.mongocryptdURI; } else { // TODO: eventually support connecting on Linux Socket for non-windows, // blocked by SERVER-41029 this.uri = 'mongodb://localhost:27020/?serverSelectionTimeoutMS=1000'; } this.bypassSpawn = !!extraOptions.mongocryptdBypassSpawn; this.spawnPath = extraOptions.mongocryptdSpawnPath || ''; this.spawnArgs = []; if (Array.isArray(extraOptions.mongocryptdSpawnArgs)) { this.spawnArgs = this.spawnArgs.concat(extraOptions.mongocryptdSpawnArgs); } if ( this.spawnArgs .filter(arg => typeof arg === 'string') .every(arg => arg.indexOf('--idleShutdownTimeoutSecs') < 0) ) { this.spawnArgs.push('--idleShutdownTimeoutSecs', 60); } } /** * @ignore * Will check to see if a mongocryptd is up. If it is not up, it will attempt * to spawn a mongocryptd in a detached process, and then wait for it to be up. * @param {Function} callback Invoked when we think a mongocryptd is up */ spawn(callback) { const cmdName = this.spawnPath || 'mongocryptd'; // Spawned with stdio: ignore and detatched:true // to ensure child can outlive parent. this._child = spawn(cmdName, this.spawnArgs, { stdio: 'ignore', detached: true }); this._child.on('error', () => {}); // unref child to remove handle from event loop this._child.unref(); process.nextTick(callback); } } module.exports = { MongocryptdManager }; libmongocrypt-1.3.0/bindings/node/lib/stateMachine.js000066400000000000000000000304661414105245100226440ustar00rootroot00000000000000'use strict'; module.exports = function(modules) { const tls = require('tls'); // Try first to import 4.x name, fallback to 3.x name const MongoNetworkTimeoutError = modules.mongodb.MongoNetworkTimeoutError || modules.mongodb.MongoTimeoutError; const common = require('./common'); const debug = common.debug; const databaseNamespace = common.databaseNamespace; const collectionNamespace = common.collectionNamespace; const MongoCryptError = common.MongoCryptError; const BufferList = require('bl'); // libmongocrypt states const MONGOCRYPT_CTX_ERROR = 0; const MONGOCRYPT_CTX_NEED_MONGO_COLLINFO = 1; const MONGOCRYPT_CTX_NEED_MONGO_MARKINGS = 2; const MONGOCRYPT_CTX_NEED_MONGO_KEYS = 3; const MONGOCRYPT_CTX_NEED_KMS = 4; const MONGOCRYPT_CTX_READY = 5; const MONGOCRYPT_CTX_DONE = 6; const HTTPS_PORT = 443; const stateToString = new Map([ [MONGOCRYPT_CTX_ERROR, 'MONGOCRYPT_CTX_ERROR'], [MONGOCRYPT_CTX_NEED_MONGO_COLLINFO, 'MONGOCRYPT_CTX_NEED_MONGO_COLLINFO'], [MONGOCRYPT_CTX_NEED_MONGO_MARKINGS, 'MONGOCRYPT_CTX_NEED_MONGO_MARKINGS'], [MONGOCRYPT_CTX_NEED_MONGO_KEYS, 'MONGOCRYPT_CTX_NEED_MONGO_KEYS'], [MONGOCRYPT_CTX_NEED_KMS, 'MONGOCRYPT_CTX_NEED_KMS'], [MONGOCRYPT_CTX_READY, 'MONGOCRYPT_CTX_READY'], [MONGOCRYPT_CTX_DONE, 'MONGOCRYPT_CTX_DONE'] ]); /** * @ignore * @callback StateMachine~executeCallback * @param {Error} [err] If present, indicates that the execute call failed with the given error * @param {object} [result] If present, is the result of executing the state machine. * @returns {void} */ /** * @ignore * @callback StateMachine~fetchCollectionInfoCallback * @param {Error} [err] If present, indicates that fetching the collection info failed with the given error * @param {object} [result] If present, is the fetched collection info for the first collection to match the given filter * @returns {void} */ /** * @ignore * @callback StateMachine~markCommandCallback * @param {Error} [err] If present, indicates that marking the command failed with the given error * @param {Buffer} [result] If present, is the marked command serialized into bson * @returns {void} */ /** * @ignore * @callback StateMachine~fetchKeysCallback * @param {Error} [err] If present, indicates that fetching the keys failed with the given error * @param {object[]} [result] If present, is all the keys from the keyVault collection that matched the given filter */ /** * @ignore * An internal class that executes across a MongoCryptContext until either * a finishing state or an error is reached. Do not instantiate directly. * @class StateMachine */ class StateMachine { constructor(options) { this.options = options || {}; this.bson = options.bson; } /** * @ignore * Executes the state machine according to the specification * @param {AutoEncrypter|ClientEncryption} autoEncrypter The JS encryption object * @param {object} context The C++ context object returned from the bindings * @param {StateMachine~executeCallback} callback Invoked with the result/error of executing the state machine * @returns {void} */ execute(autoEncrypter, context, callback) { const bson = this.bson; const keyVaultNamespace = autoEncrypter._keyVaultNamespace; const keyVaultClient = autoEncrypter._keyVaultClient; const metaDataClient = autoEncrypter._metaDataClient; const mongocryptdClient = autoEncrypter._mongocryptdClient; const mongocryptdManager = autoEncrypter._mongocryptdManager; debug(`[context#${context.id}] ${stateToString.get(context.state) || context.state}`); switch (context.state) { case MONGOCRYPT_CTX_NEED_MONGO_COLLINFO: { const filter = bson.deserialize(context.nextMongoOperation()); this.fetchCollectionInfo(metaDataClient, context.ns, filter, (err, collInfo) => { if (err) { return callback(err, null); } if (collInfo) { context.addMongoOperationResponse(collInfo); } context.finishMongoOperation(); this.execute(autoEncrypter, context, callback); }); return; } case MONGOCRYPT_CTX_NEED_MONGO_MARKINGS: { const command = context.nextMongoOperation(); this.markCommand(mongocryptdClient, context.ns, command, (err, markedCommand) => { if (err) { // If we are not bypassing spawning, then we should retry once on a MongoTimeoutError (server selection error) if ( err instanceof MongoNetworkTimeoutError && mongocryptdManager && !mongocryptdManager.bypassSpawn ) { mongocryptdManager.spawn(() => { // TODO: should we be shadowing the variables here? this.markCommand(mongocryptdClient, context.ns, command, (err, markedCommand) => { if (err) return callback(err, null); context.addMongoOperationResponse(markedCommand); context.finishMongoOperation(); this.execute(autoEncrypter, context, callback); }); }); return; } return callback(err, null); } context.addMongoOperationResponse(markedCommand); context.finishMongoOperation(); this.execute(autoEncrypter, context, callback); }); return; } case MONGOCRYPT_CTX_NEED_MONGO_KEYS: { const filter = context.nextMongoOperation(); this.fetchKeys(keyVaultClient, keyVaultNamespace, filter, (err, keys) => { if (err) return callback(err, null); keys.forEach(key => { context.addMongoOperationResponse(bson.serialize(key)); }); context.finishMongoOperation(); this.execute(autoEncrypter, context, callback); }); return; } case MONGOCRYPT_CTX_NEED_KMS: { const promises = []; let request; while ((request = context.nextKMSRequest())) { promises.push(this.kmsRequest(request)); } Promise.all(promises) .then(() => { context.finishKMSRequests(); this.execute(autoEncrypter, context, callback); }) .catch(err => { callback(err, null); }); return; } // terminal states case MONGOCRYPT_CTX_READY: { const finalizedContext = context.finalize(); // TODO: Maybe rework the logic here so that instead of doing // the callback here, finalize stores the result, and then // we wait to MONGOCRYPT_CTX_DONE to do the callback if (context.state === MONGOCRYPT_CTX_ERROR) { const message = context.status.message || 'Finalization error'; callback(new MongoCryptError(message)); return; } callback(null, bson.deserialize(finalizedContext, this.options)); return; } case MONGOCRYPT_CTX_ERROR: { const message = context.status.message; callback(new MongoCryptError(message)); return; } case MONGOCRYPT_CTX_DONE: return; default: callback(new MongoCryptError(`Unknown state: ${context.state}`)); return; } } /** * @ignore * Handles the request to the KMS service. Exposed for testing purposes. Do not directly invoke. * @param {*} kmsContext A C++ KMS context returned from the bindings * @returns {Promise} A promise that resolves when the KMS reply has be fully parsed */ kmsRequest(request) { const parsedUrl = request.endpoint.split(':'); const port = parsedUrl[1] != null ? Number.parseInt(parsedUrl[1], 10) : HTTPS_PORT; const options = { host: parsedUrl[0], servername: parsedUrl[0], port }; const message = request.message; return new Promise((resolve, reject) => { const buffer = new BufferList(); const socket = tls.connect(options, () => { socket.write(message); }); socket.once('timeout', () => { socket.removeAllListeners(); socket.destroy(); reject(new MongoCryptError('KMS request timed out')); }); socket.once('error', err => { socket.removeAllListeners(); socket.destroy(); const mcError = new MongoCryptError('KMS request failed'); mcError.originalError = err; reject(mcError); }); socket.on('data', data => { buffer.append(data); while (request.bytesNeeded > 0 && buffer.length) { const bytesNeeded = Math.min(request.bytesNeeded, buffer.length); request.addResponse(buffer.slice(0, bytesNeeded)); buffer.consume(bytesNeeded); } if (request.bytesNeeded <= 0) { socket.end(resolve); } }); }); } /** * @ignore * Fetches collection info for a provided namespace, when libmongocrypt * enters the `MONGOCRYPT_CTX_NEED_MONGO_COLLINFO` state. The result is * used to inform libmongocrypt of the schema associated with this * namespace. Exposed for testing purposes. Do not directly invoke. * * @param {MongoClient} client A MongoClient connected to the topology * @param {string} ns The namespace to list collections from * @param {object} filter A filter for the listCollections command * @param {StateMachine~fetchCollectionInfoCallback} callback Invoked with the info of the requested collection, or with an error */ fetchCollectionInfo(client, ns, filter, callback) { const bson = this.bson; const dbName = databaseNamespace(ns); client .db(dbName) .listCollections(filter) .toArray((err, collections) => { if (err) { callback(err, null); return; } const info = collections.length > 0 ? bson.serialize(collections[0]) : null; callback(null, info); }); } /** * @ignore * Calls to the mongocryptd to provide markings for a command. * Exposed for testing purposes. Do not directly invoke. * @param {MongoClient} client A MongoClient connected to a mongocryptd * @param {string} ns The namespace (database.collection) the command is being executed on * @param {object} command The command to execute. * @param {StateMachine~markCommandCallback} callback Invoked with the serialized and marked bson command, or with an error * @returns {void} */ markCommand(client, ns, command, callback) { const bson = this.bson; const dbName = databaseNamespace(ns); const rawCommand = bson.deserialize(command, { promoteLongs: false, promoteValues: false }); client.db(dbName).command(rawCommand, (err, response) => { if (err) { callback(err, null); return; } callback(err, bson.serialize(response, this.options)); }); } /** * @ignore * Requests keys from the keyVault collection on the topology. * Exposed for testing purposes. Do not directly invoke. * @param {MongoClient} client A MongoClient connected to the topology * @param {string} keyVaultNamespace The namespace (database.collection) of the keyVault Collection * @param {object} filter The filter for the find query against the keyVault Collection * @param {StateMachine~fetchKeysCallback} callback Invoked with the found keys, or with an error * @returns {void} */ fetchKeys(client, keyVaultNamespace, filter, callback) { const bson = this.bson; const dbName = databaseNamespace(keyVaultNamespace); const collectionName = collectionNamespace(keyVaultNamespace); filter = bson.deserialize(filter); client .db(dbName) .collection(collectionName, { readConcern: { level: 'majority' } }) .find(filter) .toArray((err, keys) => { if (err) { callback(err, null); return; } callback(null, keys); }); } } return { StateMachine }; }; libmongocrypt-1.3.0/bindings/node/package-lock.json000066400000000000000000016453571414105245100223630ustar00rootroot00000000000000{ "name": "mongodb-client-encryption", "version": "2.0.0-beta.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "mongodb-client-encryption", "version": "1.2.7", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "bindings": "^1.5.0", "bl": "^2.2.1", "node-addon-api": "^4.1.0", "prebuild-install": "6.1.2" }, "devDependencies": { "bson": "^4.4.0", "chai": "^4.3.4", "chai-subset": "^1.6.0", "clang-format": "^1.5.0", "dmd-clear": "^0.1.2", "eslint": "^4.19.1", "eslint-plugin-prettier": "^2.7.0", "jsdoc-to-markdown": "^5.0.3", "mocha": "^4.1.0", "mongodb": "^3.6.9", "node-gyp": "^5.1.1", "prebuild": "^10.0.1", "prettier": "^1.19.1", "segfault-handler": "^1.3.0", "sinon": "^4.5.0", "sinon-chai": "^3.6.0", "standard-version": "^9.3.0", "tar": "^6.1.0" }, "engines": { "node": ">=12.9.0" }, "peerDependencies": { "mongodb": ">=3.4.0" } }, "node_modules/@babel/code-frame": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "dependencies": { "@babel/highlight": "^7.14.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight/node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, "node_modules/@babel/parser": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.5.tgz", "integrity": "sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==", "dev": true, "bin": { "parser": "bin/babel-parser.js" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "dev": true, "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/formatio": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", "dev": true, "dependencies": { "samsam": "1.3.0" } }, "node_modules/@sinonjs/samsam": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", "dev": true, "dependencies": { "@sinonjs/commons": "^1.3.0", "array-from": "^2.1.1", "lodash": "^4.17.15" } }, "node_modules/@sinonjs/text-encoding": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", "dev": true }, "node_modules/@types/minimist": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", "dev": true }, "node_modules/@types/normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "dev": true }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, "node_modules/acorn": { "version": "5.7.4", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", "dev": true, "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/acorn-jsx": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "dev": true, "dependencies": { "acorn": "^3.0.4" } }, "node_modules/acorn-jsx/node_modules/acorn": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", "dev": true, "bin": { "acorn": "bin/acorn" }, "engines": { "node": ">=0.4.0" } }, "node_modules/add-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=", "dev": true }, "node_modules/after": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", "dev": true }, "node_modules/ajv": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "dev": true, "dependencies": { "co": "^4.6.0", "fast-deep-equal": "^1.0.0", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.3.0" } }, "node_modules/ajv-keywords": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", "dev": true, "peerDependencies": { "ajv": "^5.0.0" } }, "node_modules/amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true, "engines": { "node": ">=0.4.2" } }, "node_modules/ansi": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=", "dev": true }, "node_modules/ansi-escape-sequences": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz", "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==", "dev": true, "dependencies": { "array-back": "^3.0.1" }, "engines": { "node": ">=8.0.0" } }, "node_modules/ansi-escape-sequences/node_modules/array-back": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "engines": { "node": ">=0.10.0" } }, "node_modules/ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" }, "node_modules/are-we-there-yet": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "dependencies": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" } }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/array-back": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/array-from": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", "dev": true }, "node_modules/array-ify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", "dev": true }, "node_modules/array-index": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-index/-/array-index-1.0.0.tgz", "integrity": "sha1-7FanSe4QPk4Ix5C5w1PfFgVbl/k=", "dev": true, "dependencies": { "debug": "^2.2.0", "es6-symbol": "^3.0.2" }, "engines": { "node": "*" } }, "node_modules/array-index/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { "ms": "2.0.0" } }, "node_modules/array-index/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "node_modules/arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "dev": true, "dependencies": { "safer-buffer": "~2.1.0" } }, "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true, "engines": { "node": ">=0.8" } }, "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true, "engines": { "node": "*" } }, "node_modules/async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true, "engines": { "node": "*" } }, "node_modules/aws4": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, "node_modules/babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "dependencies": { "chalk": "^1.1.3", "esutils": "^2.0.2", "js-tokens": "^3.0.2" } }, "node_modules/babel-code-frame/node_modules/chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, "dependencies": { "tweetnacl": "^0.14.3" } }, "node_modules/big-integer": { "version": "1.6.48", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==", "dev": true, "engines": { "node": ">=0.6" } }, "node_modules/binary": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", "dev": true, "dependencies": { "buffers": "~0.1.1", "chainsaw": "~0.1.0" }, "engines": { "node": "*" } }, "node_modules/bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "dependencies": { "file-uri-to-path": "1.0.0" } }, "node_modules/bl": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", "dependencies": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" } }, "node_modules/block-stream": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", "dev": true, "dependencies": { "inherits": "~2.0.0" }, "engines": { "node": "0.4 || >=0.5.8" } }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/browser-stdout": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", "dev": true }, "node_modules/bson": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/bson/-/bson-4.4.0.tgz", "integrity": "sha512-uX9Zqzv2DpFXJgQOWKD8nbf0dTQV57WM8eiXDXVWeJYgiu/zIRz61OGLJKwbfSEEjZJ+AgS+7TUT7Y8EloTaqQ==", "dev": true, "dependencies": { "buffer": "^5.6.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "node_modules/buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, "node_modules/buffer-indexof-polyfill": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", "dev": true, "engines": { "node": ">=0.10" } }, "node_modules/buffer-shims": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", "dev": true }, "node_modules/buffers": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", "dev": true, "engines": { "node": ">=0.2.0" } }, "node_modules/cache-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cache-point/-/cache-point-1.0.0.tgz", "integrity": "sha512-ZqrZp9Hi5Uq7vfSGmNP2bUT/9DzZC2Y/GXjHB8rUJN1a+KLmbV05+vxHipNsg8+CSVgjcVVzLV8VZms6w8ZeRw==", "dev": true, "dependencies": { "array-back": "^4.0.0", "fs-then-native": "^2.0.0", "mkdirp2": "^1.0.4" }, "engines": { "node": ">=8" } }, "node_modules/caller-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", "dev": true, "dependencies": { "callsites": "^0.2.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/callsites": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/camelcase-keys": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, "dependencies": { "camelcase": "^5.3.1", "map-obj": "^4.0.0", "quick-lru": "^4.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/camelcase-keys/node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, "node_modules/catharsis": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", "dev": true, "dependencies": { "lodash": "^4.17.15" }, "engines": { "node": ">= 10" } }, "node_modules/chai": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", "deep-eql": "^3.0.1", "get-func-name": "^2.0.0", "pathval": "^1.1.1", "type-detect": "^4.0.5" }, "engines": { "node": ">=4" } }, "node_modules/chai-subset": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/chai-subset/-/chai-subset-1.6.0.tgz", "integrity": "sha1-pdDKFOMpp5WW7XAFi2ZGvWmIz+k=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/chainsaw": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", "dev": true, "dependencies": { "traverse": ">=0.3.0 <0.4" }, "engines": { "node": "*" } }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" }, "engines": { "node": ">=4" } }, "node_modules/chalk/node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "dependencies": { "color-convert": "^1.9.0" }, "engines": { "node": ">=4" } }, "node_modules/chalk/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "dependencies": { "has-flag": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/chardet": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", "dev": true }, "node_modules/check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true, "engines": { "node": "*" } }, "node_modules/chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "node_modules/circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", "deprecated": "CircularJSON is in maintenance only, flatted is its successor.", "dev": true }, "node_modules/clang-format": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/clang-format/-/clang-format-1.5.0.tgz", "integrity": "sha512-C1LucFX7E+ABVYcPEbBHM4PYQ2+WInXsqsLpFlQ9cmRfSbk7A7b1I06h/nE4bQ3MsyEkb31jY2gC0Dtc76b4IA==", "dev": true, "dependencies": { "async": "^1.5.2", "glob": "^7.0.0", "resolve": "^1.1.6" }, "bin": { "check-clang-format": "bin/check-clang-format.js", "clang-format": "index.js", "git-clang-format": "bin/git-clang-format" } }, "node_modules/cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "dependencies": { "restore-cursor": "^2.0.0" }, "engines": { "node": ">=4" } }, "node_modules/cli-width": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", "dev": true }, "node_modules/cliui": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "dev": true, "dependencies": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1", "wrap-ansi": "^2.0.0" } }, "node_modules/cmake-js": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/cmake-js/-/cmake-js-5.2.0.tgz", "integrity": "sha512-/HLhzoBEOLKGdE1FLwH5ggzRt67AWTb4IErg4rm+bTC+R0DKUobojDyp17dSswDVPosdoPmHXjKxbJiyBZfQeg==", "dev": true, "dependencies": { "bluebird": "^3", "debug": "^4", "fs-extra": "^5.0.0", "is-iojs": "^1.0.1", "lodash": "^4", "memory-stream": "0", "npmlog": "^1.2.0", "rc": "^1.2.7", "request": "^2.54.0", "semver": "^5.0.3", "splitargs": "0", "tar": "^4", "traceur": "0.0.x", "unzipper": "^0.8.13", "url-join": "0", "which": "^1.0.9", "yargs": "^3.6.0" }, "bin": { "cmake-js": "bin/cmake-js" }, "engines": { "node": ">= 4.0.0" } }, "node_modules/cmake-js/node_modules/are-we-there-yet": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.0.6.tgz", "integrity": "sha1-otKMkxAqpsyWJFomy5VN4G7FPww=", "dev": true, "dependencies": { "delegates": "^1.0.0", "readable-stream": "^2.0.0 || ^1.1.13" } }, "node_modules/cmake-js/node_modules/debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/cmake-js/node_modules/gauge": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", "integrity": "sha1-6c7FSD09TuDvRLYKfZnkk14TbZM=", "dev": true, "dependencies": { "ansi": "^0.3.0", "has-unicode": "^2.0.0", "lodash.pad": "^4.1.0", "lodash.padend": "^4.1.0", "lodash.padstart": "^4.1.0" } }, "node_modules/cmake-js/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "node_modules/cmake-js/node_modules/npmlog": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-1.2.1.tgz", "integrity": "sha1-KOe+YZYJtT960d0wChDWTXFiaLY=", "dev": true, "dependencies": { "ansi": "~0.3.0", "are-we-there-yet": "~1.0.0", "gauge": "~1.2.0" } }, "node_modules/cmake-js/node_modules/tar": { "version": "4.4.13", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "dependencies": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", "minipass": "^2.8.6", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", "yallist": "^3.0.3" }, "engines": { "node": ">=4.5" } }, "node_modules/cmake-js/node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true, "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" } }, "node_modules/code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "engines": { "node": ">=0.10.0" } }, "node_modules/collect-all": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/collect-all/-/collect-all-1.0.4.tgz", "integrity": "sha512-RKZhRwJtJEP5FWul+gkSMEnaK6H3AGPTTWOiRimCcs+rc/OmQE3Yhy1Q7A7KsdkG3ZXVdZq68Y6ONSdvkeEcKA==", "dev": true, "dependencies": { "stream-connect": "^1.0.2", "stream-via": "^1.0.4" }, "engines": { "node": ">=0.10.0" } }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "dependencies": { "color-name": "1.1.3" } }, "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/command-line-args": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.1.tgz", "integrity": "sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==", "dev": true, "dependencies": { "array-back": "^3.0.1", "find-replace": "^3.0.0", "lodash.camelcase": "^4.3.0", "typical": "^4.0.0" }, "engines": { "node": ">=4.0.0" } }, "node_modules/command-line-args/node_modules/array-back": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/command-line-args/node_modules/typical": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/command-line-tool": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/command-line-tool/-/command-line-tool-0.8.0.tgz", "integrity": "sha512-Xw18HVx/QzQV3Sc5k1vy3kgtOeGmsKIqwtFFoyjI4bbcpSgnw2CWVULvtakyw4s6fhyAdI6soQQhXc2OzJy62g==", "dev": true, "dependencies": { "ansi-escape-sequences": "^4.0.0", "array-back": "^2.0.0", "command-line-args": "^5.0.0", "command-line-usage": "^4.1.0", "typical": "^2.6.1" }, "engines": { "node": ">=4.0.0" } }, "node_modules/command-line-tool/node_modules/array-back": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", "dev": true, "dependencies": { "typical": "^2.6.1" }, "engines": { "node": ">=4" } }, "node_modules/command-line-usage": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz", "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==", "dev": true, "dependencies": { "ansi-escape-sequences": "^4.0.0", "array-back": "^2.0.0", "table-layout": "^0.4.2", "typical": "^2.6.1" }, "engines": { "node": ">=4.0.0" } }, "node_modules/command-line-usage/node_modules/array-back": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", "dev": true, "dependencies": { "typical": "^2.6.1" }, "engines": { "node": ">=4" } }, "node_modules/commander": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", "dev": true }, "node_modules/common-sequence": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/common-sequence/-/common-sequence-2.0.2.tgz", "integrity": "sha512-jAg09gkdkrDO9EWTdXfv80WWH3yeZl5oT69fGfedBNS9pXUKYInVJ1bJ+/ht2+Moeei48TmSbQDYMc8EOx9G0g==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", "dev": true, "dependencies": { "array-ify": "^1.0.0", "dot-prop": "^5.1.0" } }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "node_modules/concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "engines": [ "node >= 0.8" ], "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, "node_modules/config-master": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/config-master/-/config-master-3.1.0.tgz", "integrity": "sha1-ZnZjWQUFooO/JqSE1oSJ10xUhdo=", "dev": true, "dependencies": { "walk-back": "^2.0.1" } }, "node_modules/config-master/node_modules/walk-back": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-2.0.1.tgz", "integrity": "sha1-VU4qnYdPrEeoywBr9EwvDEmYoKQ=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "node_modules/conventional-changelog": { "version": "3.1.24", "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.24.tgz", "integrity": "sha512-ed6k8PO00UVvhExYohroVPXcOJ/K1N0/drJHx/faTH37OIZthlecuLIRX/T6uOp682CAoVoFpu+sSEaeuH6Asg==", "dev": true, "dependencies": { "conventional-changelog-angular": "^5.0.12", "conventional-changelog-atom": "^2.0.8", "conventional-changelog-codemirror": "^2.0.8", "conventional-changelog-conventionalcommits": "^4.5.0", "conventional-changelog-core": "^4.2.1", "conventional-changelog-ember": "^2.0.9", "conventional-changelog-eslint": "^3.0.9", "conventional-changelog-express": "^2.0.6", "conventional-changelog-jquery": "^3.0.11", "conventional-changelog-jshint": "^2.0.9", "conventional-changelog-preset-loader": "^2.3.4" }, "engines": { "node": ">=10" } }, "node_modules/conventional-changelog-angular": { "version": "5.0.12", "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.12.tgz", "integrity": "sha512-5GLsbnkR/7A89RyHLvvoExbiGbd9xKdKqDTrArnPbOqBqG/2wIosu0fHwpeIRI8Tl94MhVNBXcLJZl92ZQ5USw==", "dev": true, "dependencies": { "compare-func": "^2.0.0", "q": "^1.5.1" }, "engines": { "node": ">=10" } }, "node_modules/conventional-changelog-atom": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz", "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==", "dev": true, "dependencies": { "q": "^1.5.1" }, "engines": { "node": ">=10" } }, "node_modules/conventional-changelog-codemirror": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz", "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==", "dev": true, "dependencies": { "q": "^1.5.1" }, "engines": { "node": ">=10" } }, "node_modules/conventional-changelog-config-spec": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", "dev": true }, "node_modules/conventional-changelog-conventionalcommits": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.5.0.tgz", "integrity": "sha512-buge9xDvjjOxJlyxUnar/+6i/aVEVGA7EEh4OafBCXPlLUQPGbRUBhBUveWRxzvR8TEjhKEP4BdepnpG2FSZXw==", "dev": true, "dependencies": { "compare-func": "^2.0.0", "lodash": "^4.17.15", "q": "^1.5.1" }, "engines": { "node": ">=10" } }, "node_modules/conventional-changelog-core": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.2.tgz", "integrity": "sha512-7pDpRUiobQDNkwHyJG7k9f6maPo9tfPzkSWbRq97GGiZqisElhnvUZSvyQH20ogfOjntB5aadvv6NNcKL1sReg==", "dev": true, "dependencies": { "add-stream": "^1.0.0", "conventional-changelog-writer": "^4.0.18", "conventional-commits-parser": "^3.2.0", "dateformat": "^3.0.0", "get-pkg-repo": "^1.0.0", "git-raw-commits": "^2.0.8", "git-remote-origin-url": "^2.0.0", "git-semver-tags": "^4.1.1", "lodash": "^4.17.15", "normalize-package-data": "^3.0.0", "q": "^1.5.1", "read-pkg": "^3.0.0", "read-pkg-up": "^3.0.0", "shelljs": "^0.8.3", "through2": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/conventional-changelog-core/node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/conventional-changelog-core/node_modules/through2": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", "dev": true, "dependencies": { "readable-stream": "3" } }, "node_modules/conventional-changelog-ember": { "version": "2.0.9", "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", "dev": true, "dependencies": { "q": "^1.5.1" }, "engines": { "node": ">=10" } }, "node_modules/conventional-changelog-eslint": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", "dev": true, "dependencies": { "q": "^1.5.1" }, "engines": { "node": ">=10" } }, "node_modules/conventional-changelog-express": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz", "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==", "dev": true, "dependencies": { "q": "^1.5.1" }, "engines": { "node": ">=10" } }, "node_modules/conventional-changelog-jquery": { "version": "3.0.11", "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", "dev": true, "dependencies": { "q": "^1.5.1" }, "engines": { "node": ">=10" } }, "node_modules/conventional-changelog-jshint": { "version": "2.0.9", "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", "dev": true, "dependencies": { "compare-func": "^2.0.0", "q": "^1.5.1" }, "engines": { "node": ">=10" } }, "node_modules/conventional-changelog-preset-loader": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", "dev": true, "engines": { "node": ">=10" } }, "node_modules/conventional-changelog-writer": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.1.0.tgz", "integrity": "sha512-WwKcUp7WyXYGQmkLsX4QmU42AZ1lqlvRW9mqoyiQzdD+rJWbTepdWoKJuwXTS+yq79XKnQNa93/roViPQrAQgw==", "dev": true, "dependencies": { "compare-func": "^2.0.0", "conventional-commits-filter": "^2.0.7", "dateformat": "^3.0.0", "handlebars": "^4.7.6", "json-stringify-safe": "^5.0.1", "lodash": "^4.17.15", "meow": "^8.0.0", "semver": "^6.0.0", "split": "^1.0.0", "through2": "^4.0.0" }, "bin": { "conventional-changelog-writer": "cli.js" }, "engines": { "node": ">=10" } }, "node_modules/conventional-changelog-writer/node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/conventional-changelog-writer/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/conventional-changelog-writer/node_modules/through2": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", "dev": true, "dependencies": { "readable-stream": "3" } }, "node_modules/conventional-commits-filter": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", "dev": true, "dependencies": { "lodash.ismatch": "^4.4.0", "modify-values": "^1.0.0" }, "engines": { "node": ">=10" } }, "node_modules/conventional-commits-parser": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.1.tgz", "integrity": "sha512-OG9kQtmMZBJD/32NEw5IhN5+HnBqVjy03eC+I71I0oQRFA5rOgA4OtPOYG7mz1GkCfCNxn3gKIX8EiHJYuf1cA==", "dev": true, "dependencies": { "is-text-path": "^1.0.1", "JSONStream": "^1.0.4", "lodash": "^4.17.15", "meow": "^8.0.0", "split2": "^3.0.0", "through2": "^4.0.0", "trim-off-newlines": "^1.0.0" }, "bin": { "conventional-commits-parser": "cli.js" }, "engines": { "node": ">=10" } }, "node_modules/conventional-commits-parser/node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/conventional-commits-parser/node_modules/through2": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", "dev": true, "dependencies": { "readable-stream": "3" } }, "node_modules/conventional-recommended-bump": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz", "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==", "dev": true, "dependencies": { "concat-stream": "^2.0.0", "conventional-changelog-preset-loader": "^2.3.4", "conventional-commits-filter": "^2.0.7", "conventional-commits-parser": "^3.2.0", "git-raw-commits": "^2.0.8", "git-semver-tags": "^4.1.1", "meow": "^8.0.0", "q": "^1.5.1" }, "bin": { "conventional-recommended-bump": "cli.js" }, "engines": { "node": ">=10" } }, "node_modules/conventional-recommended-bump/node_modules/concat-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "dev": true, "engines": [ "node >= 6.0" ], "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, "node_modules/conventional-recommended-bump/node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "node_modules/cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "dependencies": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", "which": "^1.2.9" } }, "node_modules/currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "dependencies": { "array-find-index": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", "dev": true, "dependencies": { "es5-ext": "^0.10.50", "type": "^1.0.1" } }, "node_modules/dargs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "dependencies": { "assert-plus": "^1.0.0" }, "engines": { "node": ">=0.10" } }, "node_modules/dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true, "engines": { "node": "*" } }, "node_modules/debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { "ms": "^2.1.1" } }, "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/decamelize-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", "dev": true, "dependencies": { "decamelize": "^1.1.0", "map-obj": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/decamelize-keys/node_modules/map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/decompress-response": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", "dependencies": { "mimic-response": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", "dev": true, "dependencies": { "type-detect": "^4.0.0" }, "engines": { "node": ">=0.12" } }, "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "engines": { "node": ">=4.0.0" } }, "node_modules/deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true, "engines": { "node": ">=0.4.0" } }, "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, "node_modules/denque": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==", "dev": true, "engines": { "node": ">=0.10" } }, "node_modules/detect-indent": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", "bin": { "detect-libc": "bin/detect-libc.js" }, "engines": { "node": ">=0.10" } }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/diff": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", "dev": true, "engines": { "node": ">=0.3.1" } }, "node_modules/dmd": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/dmd/-/dmd-4.0.6.tgz", "integrity": "sha512-7ZYAnFQ6jGm4SICArwqNPylJ83PaOdPTAkds3Z/s1ueFqSc5ilJ2F0b7uP+35W1PUbemH++gn5/VlC3KwEgiHQ==", "dev": true, "dependencies": { "array-back": "^4.0.1", "cache-point": "^1.0.0", "common-sequence": "^2.0.0", "file-set": "^3.0.0", "handlebars": "^4.5.3", "marked": "^0.7.0", "object-get": "^2.1.0", "reduce-flatten": "^3.0.0", "reduce-unique": "^2.0.1", "reduce-without": "^1.0.1", "test-value": "^3.0.0", "walk-back": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/dmd-clear": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/dmd-clear/-/dmd-clear-0.1.2.tgz", "integrity": "sha1-8GHFsHKya6IxZN1ajAvIZogzvhI=", "dev": true }, "node_modules/dmd/node_modules/reduce-flatten": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-3.0.1.tgz", "integrity": "sha512-bYo+97BmUUOzg09XwfkwALt4PQH1M5L0wzKerBt6WLm3Fhdd43mMS89HiT1B9pJIqko/6lWx3OnV4J9f2Kqp5Q==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "dependencies": { "esutils": "^2.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dev": true, "dependencies": { "is-obj": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/dotgitignore": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", "dev": true, "dependencies": { "find-up": "^3.0.0", "minimatch": "^3.0.4" }, "engines": { "node": ">=6" } }, "node_modules/dotgitignore/node_modules/find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "dependencies": { "locate-path": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/dotgitignore/node_modules/locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/dotgitignore/node_modules/p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "dependencies": { "p-limit": "^2.0.0" }, "engines": { "node": ">=6" } }, "node_modules/dotgitignore/node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "dependencies": { "readable-stream": "^2.0.2" } }, "node_modules/each-series-async": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/each-series-async/-/each-series-async-1.0.1.tgz", "integrity": "sha512-G4zip/Ewpwr6JQxW7+2RNgkPd09h/UNec5UlvA/xKwl4qf5blyBNK6a/zjQc3MojgsxaOb93B9v3T92QU6IMVg==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" } }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dependencies": { "once": "^1.4.0" } }, "node_modules/entities": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", "dev": true }, "node_modules/env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es5-ext": { "version": "0.10.53", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", "dev": true, "dependencies": { "es6-iterator": "~2.0.3", "es6-symbol": "~3.1.3", "next-tick": "~1.0.0" } }, "node_modules/es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", "dev": true, "dependencies": { "d": "1", "es5-ext": "^0.10.35", "es6-symbol": "^3.1.1" } }, "node_modules/es6-symbol": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", "dev": true, "dependencies": { "d": "^1.0.1", "ext": "^1.1.2" } }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true, "engines": { "node": ">=0.8.0" } }, "node_modules/eslint": { "version": "4.19.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", "dev": true, "dependencies": { "ajv": "^5.3.0", "babel-code-frame": "^6.22.0", "chalk": "^2.1.0", "concat-stream": "^1.6.0", "cross-spawn": "^5.1.0", "debug": "^3.1.0", "doctrine": "^2.1.0", "eslint-scope": "^3.7.1", "eslint-visitor-keys": "^1.0.0", "espree": "^3.5.4", "esquery": "^1.0.0", "esutils": "^2.0.2", "file-entry-cache": "^2.0.0", "functional-red-black-tree": "^1.0.1", "glob": "^7.1.2", "globals": "^11.0.1", "ignore": "^3.3.3", "imurmurhash": "^0.1.4", "inquirer": "^3.0.6", "is-resolvable": "^1.0.0", "js-yaml": "^3.9.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", "lodash": "^4.17.4", "minimatch": "^3.0.2", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", "path-is-inside": "^1.0.2", "pluralize": "^7.0.0", "progress": "^2.0.0", "regexpp": "^1.0.1", "require-uncached": "^1.0.3", "semver": "^5.3.0", "strip-ansi": "^4.0.0", "strip-json-comments": "~2.0.1", "table": "4.0.2", "text-table": "~0.2.0" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { "node": ">=4" } }, "node_modules/eslint-plugin-prettier": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz", "integrity": "sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA==", "dev": true, "dependencies": { "fast-diff": "^1.1.1", "jest-docblock": "^21.0.0" }, "engines": { "node": ">=4.0.0" }, "peerDependencies": { "prettier": ">= 0.11.0" } }, "node_modules/eslint-scope": { "version": "3.7.3", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", "dev": true, "dependencies": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" }, "engines": { "node": ">=4.0.0" } }, "node_modules/eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/eslint/node_modules/ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/eslint/node_modules/strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "dependencies": { "ansi-regex": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/espree": { "version": "3.5.4", "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "dev": true, "dependencies": { "acorn": "^5.5.0", "acorn-jsx": "^3.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" }, "engines": { "node": ">=4" } }, "node_modules/esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "dependencies": { "estraverse": "^5.1.0" }, "engines": { "node": ">=0.10" } }, "node_modules/esquery/node_modules/estraverse": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true, "engines": { "node": ">=4.0" } }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "dependencies": { "estraverse": "^5.2.0" }, "engines": { "node": ">=4.0" } }, "node_modules/esrecurse/node_modules/estraverse": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true, "engines": { "node": ">=4.0" } }, "node_modules/estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, "engines": { "node": ">=4.0" } }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/execspawn": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/execspawn/-/execspawn-1.0.1.tgz", "integrity": "sha1-gob53efOzeeQX73ATiTzaPI/jaY=", "dev": true, "dependencies": { "util-extend": "^1.0.1" } }, "node_modules/expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", "engines": { "node": ">=6" } }, "node_modules/ext": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", "dev": true, "dependencies": { "type": "^2.0.0" } }, "node_modules/ext/node_modules/type": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==", "dev": true }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, "node_modules/external-editor": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", "dev": true, "dependencies": { "chardet": "^0.4.0", "iconv-lite": "^0.4.17", "tmp": "^0.0.33" }, "engines": { "node": ">=0.12" } }, "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true, "engines": [ "node >=0.6.0" ] }, "node_modules/fast-deep-equal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, "node_modules/fast-diff": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", "dev": true }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, "node_modules/figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "dependencies": { "escape-string-regexp": "^1.0.5" }, "engines": { "node": ">=4" } }, "node_modules/file-entry-cache": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "dependencies": { "flat-cache": "^1.2.1", "object-assign": "^4.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/file-set": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/file-set/-/file-set-3.0.0.tgz", "integrity": "sha512-B/SdeSIeRv7VlOgIjtH3dkxMI+tEy5m+OeCXfAUsirBoVoY+bGtsmvmmTFPm/G23TBY4RiTtjpcgePCfwXRjqA==", "dev": true, "dependencies": { "array-back": "^4.0.0", "glob": "^7.1.5" }, "engines": { "node": ">=8" } }, "node_modules/file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, "node_modules/find-replace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", "dev": true, "dependencies": { "array-back": "^3.0.1" }, "engines": { "node": ">=4.0.0" } }, "node_modules/find-replace/node_modules/array-back": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/find-up/node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { "p-locate": "^5.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/find-up/node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "dependencies": { "yocto-queue": "^0.1.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/find-up/node_modules/p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { "p-limit": "^3.0.2" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat-cache": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", "dev": true, "dependencies": { "circular-json": "^0.3.1", "graceful-fs": "^4.1.2", "rimraf": "~2.6.2", "write": "^0.2.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "dev": true, "engines": { "node": "*" } }, "node_modules/form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", "mime-types": "^2.1.12" }, "engines": { "node": ">= 0.12" } }, "node_modules/fs-access": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", "dev": true, "dependencies": { "null-check": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "node_modules/fs-extra": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "node_modules/fs-minipass": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", "dev": true, "dependencies": { "minipass": "^2.6.0" } }, "node_modules/fs-then-native": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fs-then-native/-/fs-then-native-2.0.0.tgz", "integrity": "sha1-GaEk2U2QwiyOBF8ujdbr6jbUjGc=", "dev": true, "engines": { "node": ">=4.0.0" } }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "node_modules/fstream": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", "mkdirp": ">=0.5 0", "rimraf": "2" }, "engines": { "node": ">=0.6" } }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, "node_modules/functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, "node_modules/gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dependencies": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", "has-unicode": "^2.0.0", "object-assign": "^4.1.0", "signal-exit": "^3.0.0", "string-width": "^1.0.1", "strip-ansi": "^3.0.1", "wide-align": "^1.1.0" } }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true, "engines": { "node": "*" } }, "node_modules/get-pkg-repo": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz", "integrity": "sha1-xztInAbYDMVTbCyFP54FIyBWly0=", "dev": true, "dependencies": { "hosted-git-info": "^2.1.4", "meow": "^3.3.0", "normalize-package-data": "^2.3.0", "parse-github-repo-url": "^1.3.0", "through2": "^2.0.0" }, "bin": { "get-pkg-repo": "cli.js" } }, "node_modules/get-pkg-repo/node_modules/camelcase-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "dependencies": { "camelcase": "^2.0.0", "map-obj": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/get-pkg-repo/node_modules/find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "dependencies": { "path-exists": "^2.0.0", "pinkie-promise": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/get-pkg-repo/node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "node_modules/get-pkg-repo/node_modules/indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "dependencies": { "repeating": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/get-pkg-repo/node_modules/map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/get-pkg-repo/node_modules/meow": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "dependencies": { "camelcase-keys": "^2.0.0", "decamelize": "^1.1.2", "loud-rejection": "^1.0.0", "map-obj": "^1.0.1", "minimist": "^1.1.3", "normalize-package-data": "^2.3.4", "object-assign": "^4.0.1", "read-pkg-up": "^1.0.1", "redent": "^1.0.0", "trim-newlines": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/get-pkg-repo/node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, "node_modules/get-pkg-repo/node_modules/path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "dependencies": { "pinkie-promise": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/get-pkg-repo/node_modules/read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "dependencies": { "load-json-file": "^1.0.0", "normalize-package-data": "^2.3.2", "path-type": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/get-pkg-repo/node_modules/read-pkg-up": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "dependencies": { "find-up": "^1.0.0", "read-pkg": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/get-pkg-repo/node_modules/redent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", "dev": true, "dependencies": { "indent-string": "^2.1.0", "strip-indent": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/get-pkg-repo/node_modules/strip-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "dependencies": { "get-stdin": "^4.0.1" }, "bin": { "strip-indent": "cli.js" }, "engines": { "node": ">=0.10.0" } }, "node_modules/get-pkg-repo/node_modules/through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, "node_modules/get-pkg-repo/node_modules/trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "dependencies": { "assert-plus": "^1.0.0" } }, "node_modules/ghreleases": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/ghreleases/-/ghreleases-3.0.2.tgz", "integrity": "sha512-QiR9mIYvRG7hd8JuQYoxeBNOelVuTp2DpdiByRywbCDBSJufK9Vq7VuhD8B+5uviMxZx2AEkCzye61Us9gYgnw==", "dev": true, "dependencies": { "after": "~0.8.1", "ghrepos": "~2.1.0", "ghutils": "~3.2.0", "lodash.uniq": "^4.5.0", "simple-mime": "~0.1.0", "url-template": "~2.0.6" }, "engines": { "node": ">=6" } }, "node_modules/ghrepos": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ghrepos/-/ghrepos-2.1.0.tgz", "integrity": "sha512-6GM0ohSDTAv7xD6GsKfxJiV/CajoofRyUwu0E8l29d1o6lFAUxmmyMP/FH33afA20ZrXzxxcTtN6TsYvudMoAg==", "dev": true, "dependencies": { "ghutils": "~3.2.0" } }, "node_modules/ghutils": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/ghutils/-/ghutils-3.2.6.tgz", "integrity": "sha512-WpYHgLQkqU7Cv147wKUEThyj6qKHCdnAG2CL9RRsRQImVdLGdVqblJ3JUnj3ToQwgm1ALPS+FXgR0448AgGPUg==", "dev": true, "dependencies": { "jsonist": "~2.1.0", "xtend": "~4.0.1" } }, "node_modules/git-raw-commits": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.10.tgz", "integrity": "sha512-sHhX5lsbG9SOO6yXdlwgEMQ/ljIn7qMpAbJZCGfXX2fq5T8M5SrDnpYk9/4HswTildcIqatsWa91vty6VhWSaQ==", "dev": true, "dependencies": { "dargs": "^7.0.0", "lodash": "^4.17.15", "meow": "^8.0.0", "split2": "^3.0.0", "through2": "^4.0.0" }, "bin": { "git-raw-commits": "cli.js" }, "engines": { "node": ">=10" } }, "node_modules/git-raw-commits/node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/git-raw-commits/node_modules/through2": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", "dev": true, "dependencies": { "readable-stream": "3" } }, "node_modules/git-remote-origin-url": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", "dev": true, "dependencies": { "gitconfiglocal": "^1.0.0", "pify": "^2.3.0" }, "engines": { "node": ">=4" } }, "node_modules/git-semver-tags": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", "dev": true, "dependencies": { "meow": "^8.0.0", "semver": "^6.0.0" }, "bin": { "git-semver-tags": "cli.js" }, "engines": { "node": ">=10" } }, "node_modules/git-semver-tags/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, "bin": { "semver": "bin/semver.js" } }, "node_modules/gitconfiglocal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", "dev": true, "dependencies": { "ini": "^1.3.2" } }, "node_modules/github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" }, "node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, "node_modules/graceful-readlink": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", "dev": true }, "node_modules/growl": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", "dev": true, "engines": { "node": ">=4.x" } }, "node_modules/handlebars": { "version": "4.7.7", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", "dev": true, "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.0", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "bin": { "handlebars": "bin/handlebars" }, "engines": { "node": ">=0.4.7" }, "optionalDependencies": { "uglify-js": "^3.1.4" } }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/har-validator": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "deprecated": "this library is no longer supported", "dev": true, "dependencies": { "ajv": "^6.12.3", "har-schema": "^2.0.0" }, "engines": { "node": ">=6" } }, "node_modules/har-validator/node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/har-validator/node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "node_modules/har-validator/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "dependencies": { "function-bind": "^1.1.1" }, "engines": { "node": ">= 0.4.0" } }, "node_modules/has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "dependencies": { "ansi-regex": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, "node_modules/he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true, "bin": { "he": "bin/he" } }, "node_modules/hosted-git-info": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, "engines": { "node": ">=10" } }, "node_modules/hosted-git-info/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/hosted-git-info/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" }, "engines": { "node": ">=0.8", "npm": ">=1.3.7" } }, "node_modules/hyperquest": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/hyperquest/-/hyperquest-2.1.3.tgz", "integrity": "sha512-fUuDOrB47PqNK/BAMOS13v41UoaqIxqSLHX6CAbOD7OfT+/GCWO1/vPLfTNutOeXrv1ikuaZ3yux+33Z9vh+rw==", "dev": true, "dependencies": { "buffer-from": "^0.1.1", "duplexer2": "~0.0.2", "through2": "~0.6.3" } }, "node_modules/hyperquest/node_modules/buffer-from": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", "integrity": "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==", "dev": true }, "node_modules/hyperquest/node_modules/duplexer2": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", "dev": true, "dependencies": { "readable-stream": "~1.1.9" } }, "node_modules/hyperquest/node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "node_modules/hyperquest/node_modules/readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "node_modules/hyperquest/node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, "engines": { "node": ">=0.10.0" } }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/ignore": { "version": "3.3.10", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", "dev": true }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true, "engines": { "node": ">=0.8.19" } }, "node_modules/indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "node_modules/inquirer": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", "dev": true, "dependencies": { "ansi-escapes": "^3.0.0", "chalk": "^2.0.0", "cli-cursor": "^2.1.0", "cli-width": "^2.0.0", "external-editor": "^2.0.4", "figures": "^2.0.0", "lodash": "^4.3.0", "mute-stream": "0.0.7", "run-async": "^2.2.0", "rx-lite": "^4.0.8", "rx-lite-aggregates": "^4.0.8", "string-width": "^2.1.0", "strip-ansi": "^4.0.0", "through": "^2.3.6" } }, "node_modules/inquirer/node_modules/ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/inquirer/node_modules/is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/inquirer/node_modules/string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "dependencies": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" }, "engines": { "node": ">=4" } }, "node_modules/inquirer/node_modules/strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "dependencies": { "ansi-regex": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true, "engines": { "node": ">= 0.10" } }, "node_modules/invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, "node_modules/is-core-module": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", "dev": true, "dependencies": { "has": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-finite": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", "dev": true, "engines": { "node": ">=0.10.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dependencies": { "number-is-nan": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-iojs": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-iojs/-/is-iojs-1.1.0.tgz", "integrity": "sha1-TBEDO11dlNbqs3dd7cm+fQCDJfE=", "dev": true }, "node_modules/is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", "dev": true }, "node_modules/is-text-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", "dev": true, "dependencies": { "text-extensions": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, "node_modules/is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, "node_modules/jest-docblock": { "version": "21.2.0", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz", "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==", "dev": true }, "node_modules/js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, "node_modules/js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "node_modules/js2xmlparser": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz", "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==", "dev": true, "dependencies": { "xmlcreate": "^2.0.3" } }, "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, "node_modules/jsdoc": { "version": "3.6.7", "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.7.tgz", "integrity": "sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw==", "dev": true, "dependencies": { "@babel/parser": "^7.9.4", "bluebird": "^3.7.2", "catharsis": "^0.9.0", "escape-string-regexp": "^2.0.0", "js2xmlparser": "^4.0.1", "klaw": "^3.0.0", "markdown-it": "^10.0.0", "markdown-it-anchor": "^5.2.7", "marked": "^2.0.3", "mkdirp": "^1.0.4", "requizzle": "^0.2.3", "strip-json-comments": "^3.1.0", "taffydb": "2.6.2", "underscore": "~1.13.1" }, "bin": { "jsdoc": "jsdoc.js" }, "engines": { "node": ">=8.15.0" } }, "node_modules/jsdoc-api": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-5.0.4.tgz", "integrity": "sha512-1KMwLnfo0FyhF06TQKzqIm8BiY1yoMIGICxRdJHUjzskaHMzHMmpLlmNFgzoa4pAC8t1CDPK5jWuQTvv1pBsEQ==", "dev": true, "dependencies": { "array-back": "^4.0.0", "cache-point": "^1.0.0", "collect-all": "^1.0.3", "file-set": "^2.0.1", "fs-then-native": "^2.0.0", "jsdoc": "^3.6.3", "object-to-spawn-args": "^1.1.1", "temp-path": "^1.0.0", "walk-back": "^3.0.1" }, "engines": { "node": ">=8.0.0" } }, "node_modules/jsdoc-api/node_modules/file-set": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/file-set/-/file-set-2.0.1.tgz", "integrity": "sha512-XgOUUpgR6FbbfYcniLw0qm1Am7PnNYIAkd+eXxRt42LiYhjaso0WiuQ+VmrNdtwotyM+cLCfZ56AZrySP3QnKA==", "dev": true, "dependencies": { "array-back": "^2.0.0", "glob": "^7.1.3" } }, "node_modules/jsdoc-api/node_modules/file-set/node_modules/array-back": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", "dev": true, "dependencies": { "typical": "^2.6.1" }, "engines": { "node": ">=4" } }, "node_modules/jsdoc-api/node_modules/walk-back": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-3.0.1.tgz", "integrity": "sha512-umiNB2qLO731Sxbp6cfZ9pwURJzTnftxE4Gc7hq8n/ehkuXC//s9F65IEIJA2ZytQZ1ZOsm/Fju4IWx0bivkUQ==", "dev": true, "engines": { "node": ">=4.0.0" } }, "node_modules/jsdoc-parse": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-4.0.1.tgz", "integrity": "sha512-qIObw8yqYZjrP2qxWROB5eLQFLTUX2jRGLhW9hjo2CC2fQVlskidCIzjCoctwsDvauBp2a/lR31jkSleczSo8Q==", "dev": true, "dependencies": { "array-back": "^4.0.0", "lodash.omit": "^4.5.0", "lodash.pick": "^4.4.0", "reduce-extract": "^1.0.0", "sort-array": "^2.0.0", "test-value": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/jsdoc-to-markdown": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-5.0.3.tgz", "integrity": "sha512-tQv5tBV0fTYidRQtE60lJKxE98mmuLcYuITFDKQiDPE9hGccpeEGUNFcVkInq1vigyuPnZmt79bQ8wv2GKjY0Q==", "dev": true, "dependencies": { "array-back": "^4.0.1", "command-line-tool": "^0.8.0", "config-master": "^3.1.0", "dmd": "^4.0.5", "jsdoc-api": "^5.0.4", "jsdoc-parse": "^4.0.1", "walk-back": "^4.0.0" }, "bin": { "jsdoc2md": "bin/cli.js" }, "engines": { "node": ">=8.0.0" } }, "node_modules/jsdoc/node_modules/escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/jsdoc/node_modules/marked": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.7.tgz", "integrity": "sha512-BJXxkuIfJchcXOJWTT2DOL+yFWifFv2yGYOUzvXg8Qz610QKw+sHCvTMYwA+qWGhlA2uivBezChZ/pBy1tWdkQ==", "dev": true, "bin": { "marked": "bin/marked" }, "engines": { "node": ">= 8.16.2" } }, "node_modules/jsdoc/node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, "bin": { "mkdirp": "bin/cmd.js" }, "engines": { "node": ">=10" } }, "node_modules/jsdoc/node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, "node_modules/json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "dev": true }, "node_modules/json-schema-traverse": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, "node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/jsonist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/jsonist/-/jsonist-2.1.2.tgz", "integrity": "sha512-8yqmWJAC2VaYoSKQAbsfgCpGY5o/1etWzx6ZxaZrC4iGaHrHUZEo+a2MyF8w+2uTavTlHdLWaZUoR19UfBstxQ==", "dev": true, "dependencies": { "bl": "~3.0.0", "hyperquest": "~2.1.3", "json-stringify-safe": "~5.0.1", "xtend": "~4.0.1" } }, "node_modules/jsonist/node_modules/bl": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.1.tgz", "integrity": "sha512-jrCW5ZhfQ/Vt07WX1Ngs+yn9BDqPL/gw28S7s9H6QK/gupnizNzJAss5akW20ISgOrbLTlXOOCTJeNUQqruAWQ==", "dev": true, "dependencies": { "readable-stream": "^3.0.1" } }, "node_modules/jsonist/node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", "dev": true, "engines": [ "node >= 0.2.0" ] }, "node_modules/JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", "dev": true, "dependencies": { "jsonparse": "^1.2.0", "through": ">=2.2.7 <3" }, "bin": { "JSONStream": "bin.js" }, "engines": { "node": "*" } }, "node_modules/jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "dev": true, "engines": [ "node >=0.6.0" ], "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", "json-schema": "0.2.3", "verror": "1.10.0" } }, "node_modules/just-extend": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", "dev": true }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/klaw": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", "dev": true, "dependencies": { "graceful-fs": "^4.1.9" } }, "node_modules/lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "dev": true, "dependencies": { "invert-kv": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "dependencies": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, "node_modules/linkify-it": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", "dev": true, "dependencies": { "uc.micro": "^1.0.1" } }, "node_modules/listenercount": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", "dev": true }, "node_modules/load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", "pify": "^2.0.0", "pinkie-promise": "^2.0.0", "strip-bom": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/load-json-file/node_modules/parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "dependencies": { "error-ex": "^1.2.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { "p-locate": "^4.1.0" }, "engines": { "node": ">=8" } }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "node_modules/lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", "dev": true }, "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, "node_modules/lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", "dev": true }, "node_modules/lodash.omit": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=", "dev": true }, "node_modules/lodash.pad": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", "integrity": "sha1-QzCUmoM6fI2iLMIPaibE1Z3runA=", "dev": true }, "node_modules/lodash.padend": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=", "dev": true }, "node_modules/lodash.padstart": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=", "dev": true }, "node_modules/lodash.pick": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", "dev": true }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", "dev": true }, "node_modules/lolex": { "version": "2.7.5", "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", "dev": true }, "node_modules/loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "dev": true, "dependencies": { "currently-unhandled": "^0.4.1", "signal-exit": "^3.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, "dependencies": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "node_modules/map-obj": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==", "dev": true, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/markdown-it": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", "dev": true, "dependencies": { "argparse": "^1.0.7", "entities": "~2.0.0", "linkify-it": "^2.0.0", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" }, "bin": { "markdown-it": "bin/markdown-it.js" } }, "node_modules/markdown-it-anchor": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", "dev": true, "peerDependencies": { "markdown-it": "*" } }, "node_modules/marked": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", "dev": true, "bin": { "marked": "bin/marked" }, "engines": { "node": ">=0.10.0" } }, "node_modules/mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", "dev": true }, "node_modules/memory-pager": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", "dev": true, "optional": true }, "node_modules/memory-stream": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/memory-stream/-/memory-stream-0.0.3.tgz", "integrity": "sha1-6+jdHDuLw4wOeUHp3dWuvmtN6D8=", "dev": true, "dependencies": { "readable-stream": "~1.0.26-2" } }, "node_modules/memory-stream/node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "node_modules/memory-stream/node_modules/readable-stream": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "node_modules/memory-stream/node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "node_modules/meow": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", "dev": true, "dependencies": { "@types/minimist": "^1.2.0", "camelcase-keys": "^6.2.2", "decamelize-keys": "^1.1.0", "hard-rejection": "^2.1.0", "minimist-options": "4.1.0", "normalize-package-data": "^3.0.0", "read-pkg-up": "^7.0.1", "redent": "^3.0.0", "trim-newlines": "^3.0.0", "type-fest": "^0.18.0", "yargs-parser": "^20.2.3" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/meow/node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/meow/node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "node_modules/meow/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "dependencies": { "@types/normalize-package-data": "^2.4.0", "normalize-package-data": "^2.5.0", "parse-json": "^5.0.0", "type-fest": "^0.6.0" }, "engines": { "node": ">=8" } }, "node_modules/meow/node_modules/read-pkg-up": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "dependencies": { "find-up": "^4.1.0", "read-pkg": "^5.2.0", "type-fest": "^0.8.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, "node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/mime-db": { "version": "1.48.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.31", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", "dev": true, "dependencies": { "mime-db": "1.48.0" }, "engines": { "node": ">= 0.6" } }, "node_modules/mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/mimic-response": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, "engines": { "node": "*" } }, "node_modules/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "node_modules/minimist-options": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, "dependencies": { "arrify": "^1.0.1", "is-plain-obj": "^1.1.0", "kind-of": "^6.0.3" }, "engines": { "node": ">= 6" } }, "node_modules/minipass": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", "dev": true, "dependencies": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" } }, "node_modules/minipass/node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, "node_modules/minizlib": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", "dev": true, "dependencies": { "minipass": "^2.9.0" } }, "node_modules/mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "dependencies": { "minimist": "^1.2.5" }, "bin": { "mkdirp": "bin/cmd.js" } }, "node_modules/mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "node_modules/mkdirp2": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp2/-/mkdirp2-1.0.4.tgz", "integrity": "sha512-Q2PKB4ZR4UPtjLl76JfzlgSCUZhSV1AXQgAZa1qt5RiaALFjP/CDrGvFBrOz7Ck6McPcwMAxTsJvWOUjOU8XMw==", "dev": true }, "node_modules/mocha": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", "dev": true, "dependencies": { "browser-stdout": "1.3.0", "commander": "2.11.0", "debug": "3.1.0", "diff": "3.3.1", "escape-string-regexp": "1.0.5", "glob": "7.1.2", "growl": "1.10.3", "he": "1.1.1", "mkdirp": "0.5.1", "supports-color": "4.4.0" }, "bin": { "_mocha": "bin/_mocha", "mocha": "bin/mocha" }, "engines": { "node": ">= 4.0.0" } }, "node_modules/mocha/node_modules/debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "dependencies": { "ms": "2.0.0" } }, "node_modules/mocha/node_modules/glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" } }, "node_modules/mocha/node_modules/has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/mocha/node_modules/minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, "node_modules/mocha/node_modules/mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", "dev": true, "dependencies": { "minimist": "0.0.8" }, "bin": { "mkdirp": "bin/cmd.js" } }, "node_modules/mocha/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "node_modules/mocha/node_modules/supports-color": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "dependencies": { "has-flag": "^2.0.0" }, "engines": { "node": ">=4" } }, "node_modules/modify-values": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/mongodb": { "version": "3.6.9", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.9.tgz", "integrity": "sha512-1nSCKgSunzn/CXwgOWgbPHUWOO5OfERcuOWISmqd610jn0s8BU9K4879iJVabqgpPPbA6hO7rG48eq+fGED3Mg==", "dev": true, "dependencies": { "bl": "^2.2.1", "bson": "^1.1.4", "denque": "^1.4.1", "optional-require": "^1.0.3", "safe-buffer": "^5.1.2" }, "engines": { "node": ">=4" }, "optionalDependencies": { "saslprep": "^1.0.0" }, "peerDependenciesMeta": { "aws4": { "optional": true }, "bson-ext": { "optional": true }, "kerberos": { "optional": true }, "mongodb-client-encryption": { "optional": true }, "mongodb-extjson": { "optional": true }, "snappy": { "optional": true } } }, "node_modules/mongodb/node_modules/bson": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==", "dev": true, "engines": { "node": ">=0.6.19" } }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "node_modules/mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, "node_modules/nan": { "version": "2.14.2", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", "dev": true }, "node_modules/napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, "node_modules/next-tick": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, "node_modules/nise": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", "integrity": "sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==", "dev": true, "dependencies": { "@sinonjs/formatio": "^3.2.1", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", "lolex": "^5.0.1", "path-to-regexp": "^1.7.0" } }, "node_modules/nise/node_modules/@sinonjs/formatio": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", "dev": true, "dependencies": { "@sinonjs/commons": "^1", "@sinonjs/samsam": "^3.1.0" } }, "node_modules/nise/node_modules/lolex": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", "dev": true, "dependencies": { "@sinonjs/commons": "^1.7.0" } }, "node_modules/node-abi": { "version": "2.30.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.0.tgz", "integrity": "sha512-g6bZh3YCKQRdwuO/tSZZYJAw622SjsRfJ2X0Iy4sSOHZ34/sPPdVBn8fev2tj7njzLwuqPw9uMtGsGkO5kIQvg==", "dependencies": { "semver": "^5.4.1" } }, "node_modules/node-addon-api": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.1.0.tgz", "integrity": "sha512-Zz1o1BDX2VtduiAt6kgiUl8jX1Vm3NMboljFYKQJ6ee8AGfiTvM2mlZFI3xPbqjs80rCQgiVJI/DjQ/1QJ0HwA==" }, "node_modules/node-gyp": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.1.tgz", "integrity": "sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw==", "dev": true, "dependencies": { "env-paths": "^2.2.0", "glob": "^7.1.4", "graceful-fs": "^4.2.2", "mkdirp": "^0.5.1", "nopt": "^4.0.1", "npmlog": "^4.1.2", "request": "^2.88.0", "rimraf": "^2.6.3", "semver": "^5.7.1", "tar": "^4.4.12", "which": "^1.3.1" }, "bin": { "node-gyp": "bin/node-gyp.js" }, "engines": { "node": ">= 6.0.0" } }, "node_modules/node-gyp/node_modules/tar": { "version": "4.4.13", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "dependencies": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", "minipass": "^2.8.6", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", "yallist": "^3.0.3" }, "engines": { "node": ">=4.5" } }, "node_modules/node-gyp/node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, "node_modules/node-ninja": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/node-ninja/-/node-ninja-1.0.2.tgz", "integrity": "sha1-IKCeV7kuLfWRmT1L8JisPnJwYrY=", "dev": true, "dependencies": { "fstream": "^1.0.0", "glob": "3 || 4 || 5 || 6 || 7", "graceful-fs": "^4.1.2", "minimatch": "3", "mkdirp": "^0.5.0", "nopt": "2 || 3", "npmlog": "0 || 1 || 2", "osenv": "0", "path-array": "^1.0.0", "request": "2", "rimraf": "2", "semver": "2.x || 3.x || 4 || 5", "tar": "^2.0.0", "which": "1" }, "bin": { "node-ninja": "bin/node-ninja.js" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/node-ninja/node_modules/gauge": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", "integrity": "sha1-6c7FSD09TuDvRLYKfZnkk14TbZM=", "dev": true, "dependencies": { "ansi": "^0.3.0", "has-unicode": "^2.0.0", "lodash.pad": "^4.1.0", "lodash.padend": "^4.1.0", "lodash.padstart": "^4.1.0" } }, "node_modules/node-ninja/node_modules/nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "dependencies": { "abbrev": "1" }, "bin": { "nopt": "bin/nopt.js" } }, "node_modules/node-ninja/node_modules/npmlog": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", "integrity": "sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI=", "dev": true, "dependencies": { "ansi": "~0.3.1", "are-we-there-yet": "~1.1.2", "gauge": "~1.2.5" } }, "node_modules/node-ninja/node_modules/tar": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "deprecated": "This version of tar is no longer supported, and will not receive security updates. Please upgrade asap.", "dev": true, "dependencies": { "block-stream": "*", "fstream": "^1.0.12", "inherits": "2" } }, "node_modules/noop-logger": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" }, "node_modules/nopt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", "dev": true, "dependencies": { "abbrev": "1", "osenv": "^0.1.4" }, "bin": { "nopt": "bin/nopt.js" } }, "node_modules/normalize-package-data": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", "dev": true, "dependencies": { "hosted-git-info": "^4.0.1", "resolve": "^1.20.0", "semver": "^7.3.4", "validate-npm-package-license": "^3.0.1" }, "engines": { "node": ">=10" } }, "node_modules/normalize-package-data/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/normalize-package-data/node_modules/semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/normalize-package-data/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "node_modules/npm-path": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.4.tgz", "integrity": "sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw==", "dev": true, "dependencies": { "which": "^1.2.10" }, "bin": { "npm-path": "bin/npm-path" }, "engines": { "node": ">=0.8" } }, "node_modules/npm-which": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/npm-which/-/npm-which-3.0.1.tgz", "integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=", "dev": true, "dependencies": { "commander": "^2.9.0", "npm-path": "^2.0.2", "which": "^1.2.10" }, "bin": { "npm-which": "bin/npm-which.js" }, "engines": { "node": ">=4.2.0" } }, "node_modules/npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dependencies": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", "gauge": "~2.7.3", "set-blocking": "~2.0.0" } }, "node_modules/null-check": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "engines": { "node": ">=0.10.0" } }, "node_modules/nw-gyp": { "version": "3.6.5", "resolved": "https://registry.npmjs.org/nw-gyp/-/nw-gyp-3.6.5.tgz", "integrity": "sha512-vYrOIYJEKpq9CfaHuiqEjV1rBYgr6uaUrPhPRiznb91LujkAUqGhQ5QqDC1bLdd+zo9jf2H0Zkl2M5zQB7+CuQ==", "dev": true, "dependencies": { "fstream": "^1.0.0", "glob": "^7.0.3", "graceful-fs": "^4.1.2", "minimatch": "^3.0.2", "mkdirp": "^0.5.0", "nopt": "2 || 3", "npmlog": "0 || 1 || 2 || 3 || 4", "osenv": "0", "request": "2", "rimraf": "2", "semver": "~5.3.0", "tar": "^2.0.0", "which": "1" }, "bin": { "nw-gyp": "bin/nw-gyp.js" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/nw-gyp/node_modules/nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "dependencies": { "abbrev": "1" }, "bin": { "nopt": "bin/nopt.js" } }, "node_modules/nw-gyp/node_modules/semver": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "dev": true, "bin": { "semver": "bin/semver" } }, "node_modules/nw-gyp/node_modules/tar": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "deprecated": "This version of tar is no longer supported, and will not receive security updates. Please upgrade asap.", "dev": true, "dependencies": { "block-stream": "*", "fstream": "^1.0.12", "inherits": "2" } }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true, "engines": { "node": "*" } }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "engines": { "node": ">=0.10.0" } }, "node_modules/object-get": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/object-get/-/object-get-2.1.1.tgz", "integrity": "sha512-7n4IpLMzGGcLEMiQKsNR7vCe+N5E9LORFrtNUVy4sO3dj9a3HedZCxEL2T7QuLhcHN1NBuBsMOKaOsAYI9IIvg==", "dev": true }, "node_modules/object-to-spawn-args": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-to-spawn-args/-/object-to-spawn-args-1.1.1.tgz", "integrity": "sha1-d9qIJ/Bz0BHJ4bFz+JV4FHAkZ4U=", "dev": true }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "dependencies": { "mimic-fn": "^1.0.0" }, "engines": { "node": ">=4" } }, "node_modules/optional-require": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz", "integrity": "sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "dependencies": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.6", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", "word-wrap": "~1.2.3" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/os-locale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, "dependencies": { "lcid": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/osenv": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "dependencies": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" } }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { "p-try": "^2.0.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "dependencies": { "p-limit": "^2.2.0" }, "engines": { "node": ">=8" } }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/parse-github-repo-url": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz", "integrity": "sha1-nn2LslKmy2ukJZUGC3v23z28H1A=", "dev": true }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/path-array": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-array/-/path-array-1.0.1.tgz", "integrity": "sha1-fi8PNfB6IBUSK4aLfqwOssT+wnE=", "dev": true, "dependencies": { "array-index": "^1.0.0" } }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "node_modules/path-to-regexp": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", "dev": true, "dependencies": { "isarray": "0.0.1" } }, "node_modules/path-to-regexp/node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "node_modules/path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", "pify": "^2.0.0", "pinkie-promise": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true, "engines": { "node": "*" } }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, "node_modules/pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "dependencies": { "pinkie": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/prebuild": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/prebuild/-/prebuild-10.0.1.tgz", "integrity": "sha512-x0CkKDmHFwX49rTGEYJwB9jBQwJWxRzwUtP5PA9dP8khFGMm3oSFgYortxdlp0PkxB29EhWGp/KQE5g+adehYg==", "dev": true, "dependencies": { "cmake-js": "~5.2.0", "detect-libc": "^1.0.3", "each-series-async": "^1.0.1", "execspawn": "^1.0.1", "ghreleases": "^3.0.2", "github-from-package": "0.0.0", "glob": "^7.1.6", "minimist": "^1.1.2", "mkdirp": "^0.5.1", "napi-build-utils": "^1.0.1", "node-abi": "^2.2.0", "node-gyp": "^6.0.1", "node-ninja": "^1.0.1", "noop-logger": "^0.1.0", "npm-which": "^3.0.1", "npmlog": "^4.0.1", "nw-gyp": "^3.6.3", "rc": "^1.0.3", "run-waterfall": "^1.1.6", "tar-stream": "^2.1.0" }, "bin": { "prebuild": "bin.js" }, "engines": { "node": ">=6" } }, "node_modules/prebuild-install": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.2.tgz", "integrity": "sha512-PzYWIKZeP+967WuKYXlTOhYBgGOvTRSfaKI89XnfJ0ansRAH7hDU45X+K+FZeI1Wb/7p/NnuctPH3g0IqKUuSQ==", "dependencies": { "detect-libc": "^1.0.3", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", "node-abi": "^2.21.0", "noop-logger": "^0.1.1", "npmlog": "^4.0.1", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^3.0.3", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" }, "engines": { "node": ">=6" } }, "node_modules/prebuild/node_modules/node-gyp": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-6.1.0.tgz", "integrity": "sha512-h4A2zDlOujeeaaTx06r4Vy+8MZ1679lU+wbCKDS4ZtvY2A37DESo37oejIw0mtmR3+rvNwts5B6Kpt1KrNYdNw==", "dev": true, "dependencies": { "env-paths": "^2.2.0", "glob": "^7.1.4", "graceful-fs": "^4.2.2", "mkdirp": "^0.5.1", "nopt": "^4.0.1", "npmlog": "^4.1.2", "request": "^2.88.0", "rimraf": "^2.6.3", "semver": "^5.7.1", "tar": "^4.4.12", "which": "^1.3.1" }, "bin": { "node-gyp": "bin/node-gyp.js" }, "engines": { "node": ">= 6.0.0" } }, "node_modules/prebuild/node_modules/tar": { "version": "4.4.13", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "dependencies": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", "minipass": "^2.8.6", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", "yallist": "^3.0.3" }, "engines": { "node": ">=4.5" } }, "node_modules/prebuild/node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, "node_modules/prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true, "engines": { "node": ">= 0.8.0" } }, "node_modules/prettier": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "dev": true, "bin": { "prettier": "bin-prettier.js" }, "engines": { "node": ">=4" } }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, "engines": { "node": ">=0.4.0" } }, "node_modules/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "dev": true }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", "dev": true, "engines": { "node": ">=0.6.0", "teleport": ">=0.2.0" } }, "node_modules/qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true, "engines": { "node": ">=0.6" } }, "node_modules/quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "cli.js" } }, "node_modules/read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "dependencies": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", "path-type": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/read-pkg-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", "dev": true, "dependencies": { "find-up": "^2.0.0", "read-pkg": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/read-pkg-up/node_modules/find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "dependencies": { "locate-path": "^2.0.0" }, "engines": { "node": ">=4" } }, "node_modules/read-pkg-up/node_modules/locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "dependencies": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/read-pkg-up/node_modules/p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, "dependencies": { "p-try": "^1.0.0" }, "engines": { "node": ">=4" } }, "node_modules/read-pkg-up/node_modules/p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "dependencies": { "p-limit": "^1.1.0" }, "engines": { "node": ">=4" } }, "node_modules/read-pkg-up/node_modules/p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/read-pkg-up/node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/read-pkg/node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "node_modules/read-pkg/node_modules/load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/read-pkg/node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, "node_modules/read-pkg/node_modules/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" }, "engines": { "node": ">=4" } }, "node_modules/read-pkg/node_modules/path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "dependencies": { "pify": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/read-pkg/node_modules/pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/read-pkg/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "node_modules/readable-stream/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "dev": true, "dependencies": { "resolve": "^1.1.6" }, "engines": { "node": ">= 0.10" } }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "dependencies": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" }, "engines": { "node": ">=8" } }, "node_modules/reduce-extract": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz", "integrity": "sha1-Z/I4W+2mUGG19fQxJmLosIDKFSU=", "dev": true, "dependencies": { "test-value": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/reduce-extract/node_modules/array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", "dev": true, "dependencies": { "typical": "^2.6.0" }, "engines": { "node": ">=0.12.0" } }, "node_modules/reduce-extract/node_modules/test-value": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-1.1.0.tgz", "integrity": "sha1-oJE29y7AQ9J8iTcHwrFZv6196T8=", "dev": true, "dependencies": { "array-back": "^1.0.2", "typical": "^2.4.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/reduce-flatten": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz", "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/reduce-unique": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/reduce-unique/-/reduce-unique-2.0.1.tgz", "integrity": "sha512-x4jH/8L1eyZGR785WY+ePtyMNhycl1N2XOLxhCbzZFaqF4AXjLzqSxa2UHgJ2ZVR/HHyPOvl1L7xRnW8ye5MdA==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/reduce-without": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/reduce-without/-/reduce-without-1.0.1.tgz", "integrity": "sha1-aK0OrRGFXJo31OglbBW7+Hly/Iw=", "dev": true, "dependencies": { "test-value": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/reduce-without/node_modules/array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", "dev": true, "dependencies": { "typical": "^2.6.0" }, "engines": { "node": ">=0.12.0" } }, "node_modules/reduce-without/node_modules/test-value": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=", "dev": true, "dependencies": { "array-back": "^1.0.3", "typical": "^2.6.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/regexpp": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", "dev": true, "engines": { "node": ">=4.0.0" } }, "node_modules/repeating": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "dependencies": { "is-finite": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", "dev": true, "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", "caseless": "~0.12.0", "combined-stream": "~1.0.6", "extend": "~3.0.2", "forever-agent": "~0.6.1", "form-data": "~2.3.2", "har-validator": "~5.1.3", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", "json-stringify-safe": "~5.0.1", "mime-types": "~2.1.19", "oauth-sign": "~0.9.0", "performance-now": "^2.1.0", "qs": "~6.5.2", "safe-buffer": "^5.1.2", "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" }, "engines": { "node": ">= 6" } }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/require-uncached": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "dependencies": { "caller-path": "^0.1.0", "resolve-from": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/requizzle": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", "dev": true, "dependencies": { "lodash": "^4.17.14" } }, "node_modules/resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "dependencies": { "is-core-module": "^2.2.0", "path-parse": "^1.0.6" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-from": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "dependencies": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" }, "engines": { "node": ">=4" } }, "node_modules/rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "node_modules/rsvp": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz", "integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==", "dev": true, "engines": { "node": "0.12.* || 4.* || 6.* || >= 7.*" } }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true, "engines": { "node": ">=0.12.0" } }, "node_modules/run-waterfall": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/run-waterfall/-/run-waterfall-1.1.7.tgz", "integrity": "sha512-iFPgh7SatHXOG1ClcpdwHI63geV3Hc/iL6crGSyBlH2PY7Rm/za+zoKz6FfY/Qlw5K7JwSol8pseO8fN6CMhhQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/rx-lite": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", "dev": true }, "node_modules/rx-lite-aggregates": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", "dev": true, "dependencies": { "rx-lite": "*" } }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, "node_modules/samsam": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", "deprecated": "This package has been deprecated in favour of @sinonjs/samsam", "dev": true }, "node_modules/saslprep": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", "dev": true, "optional": true, "dependencies": { "sparse-bitfield": "^3.0.3" }, "engines": { "node": ">=6" } }, "node_modules/segfault-handler": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/segfault-handler/-/segfault-handler-1.3.0.tgz", "integrity": "sha512-p7kVHo+4uoYkr0jmIiTBthwV5L2qmWtben/KDunDZ834mbos+tY+iO0//HpAJpOFSQZZ+wxKWuRo4DxV02B7Lg==", "dev": true, "hasInstallScript": true, "dependencies": { "bindings": "^1.2.1", "nan": "^2.14.0" } }, "node_modules/semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "bin": { "semver": "bin/semver" } }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", "dev": true }, "node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "dependencies": { "shebang-regex": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/shelljs": { "version": "0.8.4", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", "dev": true, "dependencies": { "glob": "^7.0.0", "interpret": "^1.0.0", "rechoir": "^0.6.2" }, "bin": { "shjs": "bin/shjs" }, "engines": { "node": ">=4" } }, "node_modules/signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, "node_modules/simple-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/simple-get": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", "dependencies": { "decompress-response": "^4.2.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "node_modules/simple-mime": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/simple-mime/-/simple-mime-0.1.0.tgz", "integrity": "sha1-lfUXxPRm18/1YacfydqyWW6p7y4=", "dev": true, "engines": [ "node >= 0.2.0" ] }, "node_modules/sinon": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", "dev": true, "hasInstallScript": true, "dependencies": { "@sinonjs/formatio": "^2.0.0", "diff": "^3.1.0", "lodash.get": "^4.4.2", "lolex": "^2.2.0", "nise": "^1.2.0", "supports-color": "^5.1.0", "type-detect": "^4.0.5" } }, "node_modules/sinon-chai": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", "dev": true, "peerDependencies": { "chai": "^4.0.0", "sinon": ">=4.0.0" } }, "node_modules/sinon/node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "dependencies": { "has-flag": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/slice-ansi": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", "dev": true, "dependencies": { "is-fullwidth-code-point": "^2.0.0" }, "engines": { "node": ">=4" } }, "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/sort-array": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-2.0.0.tgz", "integrity": "sha1-OKnG2if9fRR7QuYFVPKBGHtN9HI=", "dev": true, "dependencies": { "array-back": "^1.0.4", "object-get": "^2.1.0", "typical": "^2.6.0" }, "engines": { "node": ">=4" } }, "node_modules/sort-array/node_modules/array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", "dev": true, "dependencies": { "typical": "^2.6.0" }, "engines": { "node": ">=0.12.0" } }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-support": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.2.10.tgz", "integrity": "sha1-6lo5AKHByyUJagrozFwrSxDe09w=", "dev": true, "dependencies": { "source-map": "0.1.32" } }, "node_modules/source-map-support/node_modules/source-map": { "version": "0.1.32", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz", "integrity": "sha1-yLbBZ3l7pHQKjqMyUhYv8IWRsmY=", "dev": true, "dependencies": { "amdefine": ">=0.0.4" }, "engines": { "node": ">=0.8.0" } }, "node_modules/sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", "dev": true, "optional": true, "dependencies": { "memory-pager": "^1.0.2" } }, "node_modules/spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-exceptions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, "node_modules/spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", "dev": true }, "node_modules/split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", "dev": true, "dependencies": { "through": "2" }, "engines": { "node": "*" } }, "node_modules/split2": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", "dev": true, "dependencies": { "readable-stream": "^3.0.0" } }, "node_modules/split2/node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/splitargs": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/splitargs/-/splitargs-0.0.7.tgz", "integrity": "sha1-/p965lc3GzOxDLgNoUPPgknPazs=", "dev": true }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, "node_modules/sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "dev": true, "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", "bcrypt-pbkdf": "^1.0.0", "dashdash": "^1.12.0", "ecc-jsbn": "~0.1.1", "getpass": "^0.1.1", "jsbn": "~0.1.0", "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, "bin": { "sshpk-conv": "bin/sshpk-conv", "sshpk-sign": "bin/sshpk-sign", "sshpk-verify": "bin/sshpk-verify" }, "engines": { "node": ">=0.10.0" } }, "node_modules/standard-version": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.3.0.tgz", "integrity": "sha512-cYxxKXhYfI3S9+CA84HmrJa9B88H56V5FQ302iFF2TNwJukJCNoU8FgWt+11YtwKFXRkQQFpepC2QOF7aDq2Ow==", "dev": true, "dependencies": { "chalk": "^2.4.2", "conventional-changelog": "3.1.24", "conventional-changelog-config-spec": "2.1.0", "conventional-changelog-conventionalcommits": "4.5.0", "conventional-recommended-bump": "6.1.0", "detect-indent": "^6.0.0", "detect-newline": "^3.1.0", "dotgitignore": "^2.1.0", "figures": "^3.1.0", "find-up": "^5.0.0", "fs-access": "^1.0.1", "git-semver-tags": "^4.0.0", "semver": "^7.1.1", "stringify-package": "^1.0.1", "yargs": "^16.0.0" }, "bin": { "standard-version": "bin/cli.js" }, "engines": { "node": ">=10" } }, "node_modules/standard-version/node_modules/ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/standard-version/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/standard-version/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "node_modules/standard-version/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/standard-version/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "node_modules/standard-version/node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "dependencies": { "escape-string-regexp": "^1.0.5" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/standard-version/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/standard-version/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=10" } }, "node_modules/standard-version/node_modules/semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" }, "engines": { "node": ">=10" } }, "node_modules/standard-version/node_modules/string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=8" } }, "node_modules/standard-version/node_modules/strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "dependencies": { "ansi-regex": "^5.0.0" }, "engines": { "node": ">=8" } }, "node_modules/standard-version/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, "node_modules/standard-version/node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, "engines": { "node": ">=10" } }, "node_modules/standard-version/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "node_modules/standard-version/node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" }, "engines": { "node": ">=10" } }, "node_modules/stream-connect": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-connect/-/stream-connect-1.0.2.tgz", "integrity": "sha1-GLyB8u2zW4tdmoAJIAqYUxRCipc=", "dev": true, "dependencies": { "array-back": "^1.0.2" }, "engines": { "node": ">=0.10.0" } }, "node_modules/stream-connect/node_modules/array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", "dev": true, "dependencies": { "typical": "^2.6.0" }, "engines": { "node": ">=0.12.0" } }, "node_modules/stream-via": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/stream-via/-/stream-via-1.0.4.tgz", "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "node_modules/string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dependencies": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", "strip-ansi": "^3.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/stringify-package": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz", "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==", "dev": true }, "node_modules/strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dependencies": { "ansi-regex": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/strip-bom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "dependencies": { "is-utf8": "^0.2.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, "dependencies": { "min-indent": "^1.0.0" }, "engines": { "node": ">=8" } }, "node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "engines": { "node": ">=0.10.0" } }, "node_modules/supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true, "engines": { "node": ">=0.8.0" } }, "node_modules/table": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "dependencies": { "ajv": "^5.2.3", "ajv-keywords": "^2.1.0", "chalk": "^2.1.0", "lodash": "^4.17.4", "slice-ansi": "1.0.0", "string-width": "^2.1.1" } }, "node_modules/table-layout": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz", "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==", "dev": true, "dependencies": { "array-back": "^2.0.0", "deep-extend": "~0.6.0", "lodash.padend": "^4.6.1", "typical": "^2.6.1", "wordwrapjs": "^3.0.0" }, "engines": { "node": ">=4.0.0" } }, "node_modules/table-layout/node_modules/array-back": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", "dev": true, "dependencies": { "typical": "^2.6.1" }, "engines": { "node": ">=4" } }, "node_modules/table/node_modules/ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/table/node_modules/is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true, "engines": { "node": ">=4" } }, "node_modules/table/node_modules/string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "dependencies": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" }, "engines": { "node": ">=4" } }, "node_modules/table/node_modules/strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "dependencies": { "ansi-regex": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/taffydb": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", "dev": true }, "node_modules/tar": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", "dev": true, "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^3.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" }, "engines": { "node": ">= 10" } }, "node_modules/tar-fs": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" }, "engines": { "node": ">=6" } }, "node_modules/tar-stream/node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "node_modules/tar-stream/node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/tar/node_modules/chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true, "engines": { "node": ">=10" } }, "node_modules/tar/node_modules/fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, "dependencies": { "minipass": "^3.0.0" }, "engines": { "node": ">= 8" } }, "node_modules/tar/node_modules/minipass": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", "dev": true, "dependencies": { "yallist": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/tar/node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "dev": true, "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" }, "engines": { "node": ">= 8" } }, "node_modules/tar/node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, "bin": { "mkdirp": "bin/cmd.js" }, "engines": { "node": ">=10" } }, "node_modules/tar/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "node_modules/temp-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/temp-path/-/temp-path-1.0.0.tgz", "integrity": "sha1-JLFUOXOrRCiW2a02fdnL2/r+kYs=", "dev": true }, "node_modules/test-value": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-3.0.0.tgz", "integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==", "dev": true, "dependencies": { "array-back": "^2.0.0", "typical": "^2.6.1" }, "engines": { "node": ">=4.0.0" } }, "node_modules/test-value/node_modules/array-back": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", "dev": true, "dependencies": { "typical": "^2.6.1" }, "engines": { "node": ">=4" } }, "node_modules/text-extensions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", "dev": true, "engines": { "node": ">=0.10" } }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, "node_modules/through2": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "dependencies": { "readable-stream": ">=1.0.33-1 <1.1.0-0", "xtend": ">=4.0.0 <4.1.0-0" } }, "node_modules/through2/node_modules/isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "node_modules/through2/node_modules/readable-stream": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "node_modules/through2/node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "dependencies": { "os-tmpdir": "~1.0.2" }, "engines": { "node": ">=0.6.0" } }, "node_modules/tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "dependencies": { "psl": "^1.1.28", "punycode": "^2.1.1" }, "engines": { "node": ">=0.8" } }, "node_modules/traceur": { "version": "0.0.111", "resolved": "https://registry.npmjs.org/traceur/-/traceur-0.0.111.tgz", "integrity": "sha1-wE3nTRRpbDNzQn3k/Ajsr5E/w6E=", "dev": true, "dependencies": { "commander": "2.9.x", "glob": "5.0.x", "rsvp": "^3.0.13", "semver": "^4.3.3", "source-map-support": "~0.2.8" }, "bin": { "traceur": "traceur" }, "engines": { "node": ">=0.10" } }, "node_modules/traceur/node_modules/commander": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", "dev": true, "dependencies": { "graceful-readlink": ">= 1.0.0" }, "engines": { "node": ">= 0.6.x" } }, "node_modules/traceur/node_modules/glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "dependencies": { "inflight": "^1.0.4", "inherits": "2", "minimatch": "2 || 3", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, "engines": { "node": "*" } }, "node_modules/traceur/node_modules/semver": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", "dev": true, "bin": { "semver": "bin/semver" } }, "node_modules/traverse": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", "dev": true, "engines": { "node": "*" } }, "node_modules/trim-newlines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true, "engines": { "node": ">=8" } }, "node_modules/trim-off-newlines": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dependencies": { "safe-buffer": "^5.0.1" }, "engines": { "node": "*" } }, "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, "node_modules/type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", "dev": true }, "node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "dependencies": { "prelude-ls": "~1.1.2" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, "engines": { "node": ">=4" } }, "node_modules/type-fest": { "version": "0.18.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, "node_modules/typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", "dev": true }, "node_modules/uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", "dev": true }, "node_modules/uglify-js": { "version": "3.13.9", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.9.tgz", "integrity": "sha512-wZbyTQ1w6Y7fHdt8sJnHfSIuWeDgk6B5rCb4E/AM6QNNPbOMIZph21PW5dRB3h7Df0GszN+t7RuUH6sWK5bF0g==", "dev": true, "optional": true, "bin": { "uglifyjs": "bin/uglifyjs" }, "engines": { "node": ">=0.8.0" } }, "node_modules/underscore": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==", "dev": true }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, "engines": { "node": ">= 4.0.0" } }, "node_modules/unzipper": { "version": "0.8.14", "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.8.14.tgz", "integrity": "sha512-8rFtE7EP5ssOwGpN2dt1Q4njl0N1hUXJ7sSPz0leU2hRdq6+pra57z4YPBlVqm40vcgv6ooKZEAx48fMTv9x4w==", "dev": true, "dependencies": { "big-integer": "^1.6.17", "binary": "~0.3.0", "bluebird": "~3.4.1", "buffer-indexof-polyfill": "~1.0.0", "duplexer2": "~0.1.4", "fstream": "~1.0.10", "listenercount": "~1.0.1", "readable-stream": "~2.1.5", "setimmediate": "~1.0.4" } }, "node_modules/unzipper/node_modules/bluebird": { "version": "3.4.7", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", "dev": true }, "node_modules/unzipper/node_modules/process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", "dev": true }, "node_modules/unzipper/node_modules/readable-stream": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=", "dev": true, "dependencies": { "buffer-shims": "^1.0.0", "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "~1.0.0", "process-nextick-args": "~1.0.6", "string_decoder": "~0.10.x", "util-deprecate": "~1.0.1" } }, "node_modules/unzipper/node_modules/string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "dependencies": { "punycode": "^2.1.0" } }, "node_modules/url-join": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz", "integrity": "sha1-HbSK1CLTQCRpqH99l73r/k+x48g=", "dev": true }, "node_modules/url-template": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=", "dev": true }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "node_modules/util-extend": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz", "integrity": "sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=", "dev": true }, "node_modules/uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, "bin": { "uuid": "bin/uuid" } }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, "engines": [ "node >=0.6.0" ], "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, "node_modules/walk-back": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-4.0.0.tgz", "integrity": "sha512-kudCA8PXVQfrqv2mFTG72vDBRi8BKWxGgFLwPpzHcpZnSwZk93WMwUDVcLHWNsnm+Y0AC4Vb6MUNRgaHfyV2DQ==", "dev": true, "engines": { "node": ">=8.0.0" } }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "dependencies": { "isexe": "^2.0.0" }, "bin": { "which": "bin/which" } }, "node_modules/wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dependencies": { "string-width": "^1.0.2 || 2" } }, "node_modules/window-size": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", "dev": true, "bin": { "window-size": "cli.js" }, "engines": { "node": ">= 0.10.0" } }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", "dev": true }, "node_modules/wordwrapjs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz", "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==", "dev": true, "dependencies": { "reduce-flatten": "^1.0.1", "typical": "^2.6.1" }, "engines": { "node": ">=4.0.0" } }, "node_modules/wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "dependencies": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "node_modules/write": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "dev": true, "dependencies": { "mkdirp": "^0.5.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/xmlcreate": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz", "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==", "dev": true }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true, "engines": { "node": ">=0.4" } }, "node_modules/y18n": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", "dev": true }, "node_modules/yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, "node_modules/yargs": { "version": "3.32.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", "dev": true, "dependencies": { "camelcase": "^2.0.1", "cliui": "^3.0.3", "decamelize": "^1.1.1", "os-locale": "^1.4.0", "string-width": "^1.0.1", "window-size": "^0.1.4", "y18n": "^3.2.0" } }, "node_modules/yargs-parser": { "version": "20.2.7", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", "dev": true, "engines": { "node": ">=10" } }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } } }, "dependencies": { "@babel/code-frame": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "requires": { "@babel/highlight": "^7.14.5" } }, "@babel/helper-validator-identifier": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", "dev": true }, "@babel/highlight": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, "dependencies": { "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true } } }, "@babel/parser": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.5.tgz", "integrity": "sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg==", "dev": true }, "@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "dev": true, "requires": { "type-detect": "4.0.8" } }, "@sinonjs/formatio": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", "dev": true, "requires": { "samsam": "1.3.0" } }, "@sinonjs/samsam": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", "dev": true, "requires": { "@sinonjs/commons": "^1.3.0", "array-from": "^2.1.1", "lodash": "^4.17.15" } }, "@sinonjs/text-encoding": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", "dev": true }, "@types/minimist": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", "dev": true }, "@types/normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "dev": true }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, "acorn": { "version": "5.7.4", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", "dev": true }, "acorn-jsx": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "dev": true, "requires": { "acorn": "^3.0.4" }, "dependencies": { "acorn": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", "dev": true } } }, "add-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=", "dev": true }, "after": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", "dev": true }, "ajv": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "dev": true, "requires": { "co": "^4.6.0", "fast-deep-equal": "^1.0.0", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.3.0" } }, "ajv-keywords": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", "dev": true, "requires": {} }, "amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "dev": true }, "ansi": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=", "dev": true }, "ansi-escape-sequences": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz", "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==", "dev": true, "requires": { "array-back": "^3.0.1" }, "dependencies": { "array-back": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", "dev": true } } }, "ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "dev": true }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" }, "are-we-there-yet": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" } }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { "sprintf-js": "~1.0.2" } }, "array-back": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", "dev": true }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true }, "array-from": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", "dev": true }, "array-ify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", "dev": true }, "array-index": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-index/-/array-index-1.0.0.tgz", "integrity": "sha1-7FanSe4QPk4Ix5C5w1PfFgVbl/k=", "dev": true, "requires": { "debug": "^2.2.0", "es6-symbol": "^3.0.2" }, "dependencies": { "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "dev": true, "requires": { "safer-buffer": "~2.1.0" } }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true }, "aws4": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { "chalk": "^1.1.3", "esutils": "^2.0.2", "js-tokens": "^3.0.2" }, "dependencies": { "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" } } } }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, "requires": { "tweetnacl": "^0.14.3" } }, "big-integer": { "version": "1.6.48", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==", "dev": true }, "binary": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", "dev": true, "requires": { "buffers": "~0.1.1", "chainsaw": "~0.1.0" } }, "bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", "requires": { "file-uri-to-path": "1.0.0" } }, "bl": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", "requires": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" } }, "block-stream": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", "dev": true, "requires": { "inherits": "~2.0.0" } }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "browser-stdout": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", "dev": true }, "bson": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/bson/-/bson-4.4.0.tgz", "integrity": "sha512-uX9Zqzv2DpFXJgQOWKD8nbf0dTQV57WM8eiXDXVWeJYgiu/zIRz61OGLJKwbfSEEjZJ+AgS+7TUT7Y8EloTaqQ==", "dev": true, "requires": { "buffer": "^5.6.0" } }, "buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, "buffer-indexof-polyfill": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", "dev": true }, "buffer-shims": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", "dev": true }, "buffers": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", "dev": true }, "cache-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cache-point/-/cache-point-1.0.0.tgz", "integrity": "sha512-ZqrZp9Hi5Uq7vfSGmNP2bUT/9DzZC2Y/GXjHB8rUJN1a+KLmbV05+vxHipNsg8+CSVgjcVVzLV8VZms6w8ZeRw==", "dev": true, "requires": { "array-back": "^4.0.0", "fs-then-native": "^2.0.0", "mkdirp2": "^1.0.4" } }, "caller-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", "dev": true, "requires": { "callsites": "^0.2.0" } }, "callsites": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", "dev": true }, "camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", "dev": true }, "camelcase-keys": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, "requires": { "camelcase": "^5.3.1", "map-obj": "^4.0.0", "quick-lru": "^4.0.1" }, "dependencies": { "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true } } }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, "catharsis": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", "dev": true, "requires": { "lodash": "^4.17.15" } }, "chai": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", "dev": true, "requires": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", "deep-eql": "^3.0.1", "get-func-name": "^2.0.0", "pathval": "^1.1.1", "type-detect": "^4.0.5" } }, "chai-subset": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/chai-subset/-/chai-subset-1.6.0.tgz", "integrity": "sha1-pdDKFOMpp5WW7XAFi2ZGvWmIz+k=", "dev": true }, "chainsaw": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", "dev": true, "requires": { "traverse": ">=0.3.0 <0.4" } }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" }, "dependencies": { "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "^1.9.0" } }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" } } } }, "chardet": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", "dev": true }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", "dev": true }, "clang-format": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/clang-format/-/clang-format-1.5.0.tgz", "integrity": "sha512-C1LucFX7E+ABVYcPEbBHM4PYQ2+WInXsqsLpFlQ9cmRfSbk7A7b1I06h/nE4bQ3MsyEkb31jY2gC0Dtc76b4IA==", "dev": true, "requires": { "async": "^1.5.2", "glob": "^7.0.0", "resolve": "^1.1.6" } }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "requires": { "restore-cursor": "^2.0.0" } }, "cli-width": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", "dev": true }, "cliui": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1", "wrap-ansi": "^2.0.0" } }, "cmake-js": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/cmake-js/-/cmake-js-5.2.0.tgz", "integrity": "sha512-/HLhzoBEOLKGdE1FLwH5ggzRt67AWTb4IErg4rm+bTC+R0DKUobojDyp17dSswDVPosdoPmHXjKxbJiyBZfQeg==", "dev": true, "requires": { "bluebird": "^3", "debug": "^4", "fs-extra": "^5.0.0", "is-iojs": "^1.0.1", "lodash": "^4", "memory-stream": "0", "npmlog": "^1.2.0", "rc": "^1.2.7", "request": "^2.54.0", "semver": "^5.0.3", "splitargs": "0", "tar": "^4", "traceur": "0.0.x", "unzipper": "^0.8.13", "url-join": "0", "which": "^1.0.9", "yargs": "^3.6.0" }, "dependencies": { "are-we-there-yet": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.0.6.tgz", "integrity": "sha1-otKMkxAqpsyWJFomy5VN4G7FPww=", "dev": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.0 || ^1.1.13" } }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" } }, "gauge": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", "integrity": "sha1-6c7FSD09TuDvRLYKfZnkk14TbZM=", "dev": true, "requires": { "ansi": "^0.3.0", "has-unicode": "^2.0.0", "lodash.pad": "^4.1.0", "lodash.padend": "^4.1.0", "lodash.padstart": "^4.1.0" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "npmlog": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-1.2.1.tgz", "integrity": "sha1-KOe+YZYJtT960d0wChDWTXFiaLY=", "dev": true, "requires": { "ansi": "~0.3.0", "are-we-there-yet": "~1.0.0", "gauge": "~1.2.0" } }, "tar": { "version": "4.4.13", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", "minipass": "^2.8.6", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", "yallist": "^3.0.3" } }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "collect-all": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/collect-all/-/collect-all-1.0.4.tgz", "integrity": "sha512-RKZhRwJtJEP5FWul+gkSMEnaK6H3AGPTTWOiRimCcs+rc/OmQE3Yhy1Q7A7KsdkG3ZXVdZq68Y6ONSdvkeEcKA==", "dev": true, "requires": { "stream-connect": "^1.0.2", "stream-via": "^1.0.4" } }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { "color-name": "1.1.3" } }, "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "requires": { "delayed-stream": "~1.0.0" } }, "command-line-args": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.1.tgz", "integrity": "sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==", "dev": true, "requires": { "array-back": "^3.0.1", "find-replace": "^3.0.0", "lodash.camelcase": "^4.3.0", "typical": "^4.0.0" }, "dependencies": { "array-back": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", "dev": true }, "typical": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", "dev": true } } }, "command-line-tool": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/command-line-tool/-/command-line-tool-0.8.0.tgz", "integrity": "sha512-Xw18HVx/QzQV3Sc5k1vy3kgtOeGmsKIqwtFFoyjI4bbcpSgnw2CWVULvtakyw4s6fhyAdI6soQQhXc2OzJy62g==", "dev": true, "requires": { "ansi-escape-sequences": "^4.0.0", "array-back": "^2.0.0", "command-line-args": "^5.0.0", "command-line-usage": "^4.1.0", "typical": "^2.6.1" }, "dependencies": { "array-back": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", "dev": true, "requires": { "typical": "^2.6.1" } } } }, "command-line-usage": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz", "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==", "dev": true, "requires": { "ansi-escape-sequences": "^4.0.0", "array-back": "^2.0.0", "table-layout": "^0.4.2", "typical": "^2.6.1" }, "dependencies": { "array-back": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", "dev": true, "requires": { "typical": "^2.6.1" } } } }, "commander": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", "dev": true }, "common-sequence": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/common-sequence/-/common-sequence-2.0.2.tgz", "integrity": "sha512-jAg09gkdkrDO9EWTdXfv80WWH3yeZl5oT69fGfedBNS9pXUKYInVJ1bJ+/ht2+Moeei48TmSbQDYMc8EOx9G0g==", "dev": true }, "compare-func": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", "dev": true, "requires": { "array-ify": "^1.0.0", "dot-prop": "^5.1.0" } }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, "config-master": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/config-master/-/config-master-3.1.0.tgz", "integrity": "sha1-ZnZjWQUFooO/JqSE1oSJ10xUhdo=", "dev": true, "requires": { "walk-back": "^2.0.1" }, "dependencies": { "walk-back": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-2.0.1.tgz", "integrity": "sha1-VU4qnYdPrEeoywBr9EwvDEmYoKQ=", "dev": true } } }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "conventional-changelog": { "version": "3.1.24", "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.24.tgz", "integrity": "sha512-ed6k8PO00UVvhExYohroVPXcOJ/K1N0/drJHx/faTH37OIZthlecuLIRX/T6uOp682CAoVoFpu+sSEaeuH6Asg==", "dev": true, "requires": { "conventional-changelog-angular": "^5.0.12", "conventional-changelog-atom": "^2.0.8", "conventional-changelog-codemirror": "^2.0.8", "conventional-changelog-conventionalcommits": "^4.5.0", "conventional-changelog-core": "^4.2.1", "conventional-changelog-ember": "^2.0.9", "conventional-changelog-eslint": "^3.0.9", "conventional-changelog-express": "^2.0.6", "conventional-changelog-jquery": "^3.0.11", "conventional-changelog-jshint": "^2.0.9", "conventional-changelog-preset-loader": "^2.3.4" } }, "conventional-changelog-angular": { "version": "5.0.12", "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.12.tgz", "integrity": "sha512-5GLsbnkR/7A89RyHLvvoExbiGbd9xKdKqDTrArnPbOqBqG/2wIosu0fHwpeIRI8Tl94MhVNBXcLJZl92ZQ5USw==", "dev": true, "requires": { "compare-func": "^2.0.0", "q": "^1.5.1" } }, "conventional-changelog-atom": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz", "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-codemirror": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz", "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-config-spec": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", "dev": true }, "conventional-changelog-conventionalcommits": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.5.0.tgz", "integrity": "sha512-buge9xDvjjOxJlyxUnar/+6i/aVEVGA7EEh4OafBCXPlLUQPGbRUBhBUveWRxzvR8TEjhKEP4BdepnpG2FSZXw==", "dev": true, "requires": { "compare-func": "^2.0.0", "lodash": "^4.17.15", "q": "^1.5.1" } }, "conventional-changelog-core": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.2.tgz", "integrity": "sha512-7pDpRUiobQDNkwHyJG7k9f6maPo9tfPzkSWbRq97GGiZqisElhnvUZSvyQH20ogfOjntB5aadvv6NNcKL1sReg==", "dev": true, "requires": { "add-stream": "^1.0.0", "conventional-changelog-writer": "^4.0.18", "conventional-commits-parser": "^3.2.0", "dateformat": "^3.0.0", "get-pkg-repo": "^1.0.0", "git-raw-commits": "^2.0.8", "git-remote-origin-url": "^2.0.0", "git-semver-tags": "^4.1.1", "lodash": "^4.17.15", "normalize-package-data": "^3.0.0", "q": "^1.5.1", "read-pkg": "^3.0.0", "read-pkg-up": "^3.0.0", "shelljs": "^0.8.3", "through2": "^4.0.0" }, "dependencies": { "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "through2": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", "dev": true, "requires": { "readable-stream": "3" } } } }, "conventional-changelog-ember": { "version": "2.0.9", "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-eslint": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-express": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz", "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-jquery": { "version": "3.0.11", "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-jshint": { "version": "2.0.9", "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", "dev": true, "requires": { "compare-func": "^2.0.0", "q": "^1.5.1" } }, "conventional-changelog-preset-loader": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", "dev": true }, "conventional-changelog-writer": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.1.0.tgz", "integrity": "sha512-WwKcUp7WyXYGQmkLsX4QmU42AZ1lqlvRW9mqoyiQzdD+rJWbTepdWoKJuwXTS+yq79XKnQNa93/roViPQrAQgw==", "dev": true, "requires": { "compare-func": "^2.0.0", "conventional-commits-filter": "^2.0.7", "dateformat": "^3.0.0", "handlebars": "^4.7.6", "json-stringify-safe": "^5.0.1", "lodash": "^4.17.15", "meow": "^8.0.0", "semver": "^6.0.0", "split": "^1.0.0", "through2": "^4.0.0" }, "dependencies": { "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, "through2": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", "dev": true, "requires": { "readable-stream": "3" } } } }, "conventional-commits-filter": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", "dev": true, "requires": { "lodash.ismatch": "^4.4.0", "modify-values": "^1.0.0" } }, "conventional-commits-parser": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.1.tgz", "integrity": "sha512-OG9kQtmMZBJD/32NEw5IhN5+HnBqVjy03eC+I71I0oQRFA5rOgA4OtPOYG7mz1GkCfCNxn3gKIX8EiHJYuf1cA==", "dev": true, "requires": { "is-text-path": "^1.0.1", "JSONStream": "^1.0.4", "lodash": "^4.17.15", "meow": "^8.0.0", "split2": "^3.0.0", "through2": "^4.0.0", "trim-off-newlines": "^1.0.0" }, "dependencies": { "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "through2": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", "dev": true, "requires": { "readable-stream": "3" } } } }, "conventional-recommended-bump": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz", "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==", "dev": true, "requires": { "concat-stream": "^2.0.0", "conventional-changelog-preset-loader": "^2.3.4", "conventional-commits-filter": "^2.0.7", "conventional-commits-parser": "^3.2.0", "git-raw-commits": "^2.0.8", "git-semver-tags": "^4.1.1", "meow": "^8.0.0", "q": "^1.5.1" }, "dependencies": { "concat-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "dev": true, "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } } } }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", "which": "^1.2.9" } }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "requires": { "array-find-index": "^1.0.1" } }, "d": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", "dev": true, "requires": { "es5-ext": "^0.10.50", "type": "^1.0.1" } }, "dargs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", "dev": true }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "requires": { "assert-plus": "^1.0.0" } }, "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true }, "debug": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { "ms": "^2.1.1" } }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, "decamelize-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", "dev": true, "requires": { "decamelize": "^1.1.0", "map-obj": "^1.0.0" }, "dependencies": { "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "dev": true } } }, "decompress-response": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", "requires": { "mimic-response": "^2.0.0" } }, "deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", "dev": true, "requires": { "type-detect": "^4.0.0" } }, "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, "denque": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", "integrity": "sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ==", "dev": true }, "detect-indent": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", "dev": true }, "detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true }, "diff": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", "dev": true }, "dmd": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/dmd/-/dmd-4.0.6.tgz", "integrity": "sha512-7ZYAnFQ6jGm4SICArwqNPylJ83PaOdPTAkds3Z/s1ueFqSc5ilJ2F0b7uP+35W1PUbemH++gn5/VlC3KwEgiHQ==", "dev": true, "requires": { "array-back": "^4.0.1", "cache-point": "^1.0.0", "common-sequence": "^2.0.0", "file-set": "^3.0.0", "handlebars": "^4.5.3", "marked": "^0.7.0", "object-get": "^2.1.0", "reduce-flatten": "^3.0.0", "reduce-unique": "^2.0.1", "reduce-without": "^1.0.1", "test-value": "^3.0.0", "walk-back": "^4.0.0" }, "dependencies": { "reduce-flatten": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-3.0.1.tgz", "integrity": "sha512-bYo+97BmUUOzg09XwfkwALt4PQH1M5L0wzKerBt6WLm3Fhdd43mMS89HiT1B9pJIqko/6lWx3OnV4J9f2Kqp5Q==", "dev": true } } }, "dmd-clear": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/dmd-clear/-/dmd-clear-0.1.2.tgz", "integrity": "sha1-8GHFsHKya6IxZN1ajAvIZogzvhI=", "dev": true }, "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { "esutils": "^2.0.2" } }, "dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dev": true, "requires": { "is-obj": "^2.0.0" } }, "dotgitignore": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", "dev": true, "requires": { "find-up": "^3.0.0", "minimatch": "^3.0.4" }, "dependencies": { "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { "locate-path": "^3.0.0" } }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { "p-limit": "^2.0.0" } }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true } } }, "duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "requires": { "readable-stream": "^2.0.2" } }, "each-series-async": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/each-series-async/-/each-series-async-1.0.1.tgz", "integrity": "sha512-G4zip/Ewpwr6JQxW7+2RNgkPd09h/UNec5UlvA/xKwl4qf5blyBNK6a/zjQc3MojgsxaOb93B9v3T92QU6IMVg==", "dev": true }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" } }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "requires": { "once": "^1.4.0" } }, "entities": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", "dev": true }, "env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "requires": { "is-arrayish": "^0.2.1" } }, "es5-ext": { "version": "0.10.53", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", "dev": true, "requires": { "es6-iterator": "~2.0.3", "es6-symbol": "~3.1.3", "next-tick": "~1.0.0" } }, "es6-iterator": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", "dev": true, "requires": { "d": "1", "es5-ext": "^0.10.35", "es6-symbol": "^3.1.1" } }, "es6-symbol": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", "dev": true, "requires": { "d": "^1.0.1", "ext": "^1.1.2" } }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, "eslint": { "version": "4.19.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", "dev": true, "requires": { "ajv": "^5.3.0", "babel-code-frame": "^6.22.0", "chalk": "^2.1.0", "concat-stream": "^1.6.0", "cross-spawn": "^5.1.0", "debug": "^3.1.0", "doctrine": "^2.1.0", "eslint-scope": "^3.7.1", "eslint-visitor-keys": "^1.0.0", "espree": "^3.5.4", "esquery": "^1.0.0", "esutils": "^2.0.2", "file-entry-cache": "^2.0.0", "functional-red-black-tree": "^1.0.1", "glob": "^7.1.2", "globals": "^11.0.1", "ignore": "^3.3.3", "imurmurhash": "^0.1.4", "inquirer": "^3.0.6", "is-resolvable": "^1.0.0", "js-yaml": "^3.9.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", "lodash": "^4.17.4", "minimatch": "^3.0.2", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", "path-is-inside": "^1.0.2", "pluralize": "^7.0.0", "progress": "^2.0.0", "regexpp": "^1.0.1", "require-uncached": "^1.0.3", "semver": "^5.3.0", "strip-ansi": "^4.0.0", "strip-json-comments": "~2.0.1", "table": "4.0.2", "text-table": "~0.2.0" }, "dependencies": { "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" } } } }, "eslint-plugin-prettier": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz", "integrity": "sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA==", "dev": true, "requires": { "fast-diff": "^1.1.1", "jest-docblock": "^21.0.0" } }, "eslint-scope": { "version": "3.7.3", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } }, "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true }, "espree": { "version": "3.5.4", "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "dev": true, "requires": { "acorn": "^5.5.0", "acorn-jsx": "^3.0.0" } }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "esquery": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { "estraverse": "^5.1.0" }, "dependencies": { "estraverse": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true } } }, "esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { "estraverse": "^5.2.0" }, "dependencies": { "estraverse": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true } } }, "estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "execspawn": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/execspawn/-/execspawn-1.0.1.tgz", "integrity": "sha1-gob53efOzeeQX73ATiTzaPI/jaY=", "dev": true, "requires": { "util-extend": "^1.0.1" } }, "expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" }, "ext": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", "dev": true, "requires": { "type": "^2.0.0" }, "dependencies": { "type": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==", "dev": true } } }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, "external-editor": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", "dev": true, "requires": { "chardet": "^0.4.0", "iconv-lite": "^0.4.17", "tmp": "^0.0.33" } }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, "fast-deep-equal": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", "dev": true }, "fast-diff": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", "dev": true }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" } }, "file-entry-cache": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { "flat-cache": "^1.2.1", "object-assign": "^4.0.1" } }, "file-set": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/file-set/-/file-set-3.0.0.tgz", "integrity": "sha512-B/SdeSIeRv7VlOgIjtH3dkxMI+tEy5m+OeCXfAUsirBoVoY+bGtsmvmmTFPm/G23TBY4RiTtjpcgePCfwXRjqA==", "dev": true, "requires": { "array-back": "^4.0.0", "glob": "^7.1.5" } }, "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, "find-replace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", "dev": true, "requires": { "array-back": "^3.0.1" }, "dependencies": { "array-back": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", "dev": true } } }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" }, "dependencies": { "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { "p-locate": "^5.0.0" } }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { "yocto-queue": "^0.1.0" } }, "p-locate": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { "p-limit": "^3.0.2" } } } }, "flat-cache": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", "dev": true, "requires": { "circular-json": "^0.3.1", "graceful-fs": "^4.1.2", "rimraf": "~2.6.2", "write": "^0.2.1" } }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "dev": true }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } }, "fs-access": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", "dev": true, "requires": { "null-check": "^1.0.0" } }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "fs-extra": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", "dev": true, "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "fs-minipass": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", "dev": true, "requires": { "minipass": "^2.6.0" } }, "fs-then-native": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fs-then-native/-/fs-then-native-2.0.0.tgz", "integrity": "sha1-GaEk2U2QwiyOBF8ujdbr6jbUjGc=", "dev": true }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "fstream": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", "dev": true, "requires": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", "mkdirp": ">=0.5 0", "rimraf": "2" } }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", "has-unicode": "^2.0.0", "object-assign": "^4.1.0", "signal-exit": "^3.0.0", "string-width": "^1.0.1", "strip-ansi": "^3.0.1", "wide-align": "^1.1.0" } }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", "dev": true }, "get-pkg-repo": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz", "integrity": "sha1-xztInAbYDMVTbCyFP54FIyBWly0=", "dev": true, "requires": { "hosted-git-info": "^2.1.4", "meow": "^3.3.0", "normalize-package-data": "^2.3.0", "parse-github-repo-url": "^1.3.0", "through2": "^2.0.0" }, "dependencies": { "camelcase-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { "camelcase": "^2.0.0", "map-obj": "^1.0.0" } }, "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { "path-exists": "^2.0.0", "pinkie-promise": "^2.0.0" } }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { "repeating": "^2.0.0" } }, "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "dev": true }, "meow": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { "camelcase-keys": "^2.0.0", "decamelize": "^1.1.2", "loud-rejection": "^1.0.0", "map-obj": "^1.0.1", "minimist": "^1.1.3", "normalize-package-data": "^2.3.4", "object-assign": "^4.0.1", "read-pkg-up": "^1.0.1", "redent": "^1.0.0", "trim-newlines": "^1.0.0" } }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { "pinkie-promise": "^2.0.0" } }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { "load-json-file": "^1.0.0", "normalize-package-data": "^2.3.2", "path-type": "^1.0.0" } }, "read-pkg-up": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { "find-up": "^1.0.0", "read-pkg": "^1.0.0" } }, "redent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", "dev": true, "requires": { "indent-string": "^2.1.0", "strip-indent": "^1.0.1" } }, "strip-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "requires": { "get-stdin": "^4.0.1" } }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", "dev": true } } }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", "dev": true }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "requires": { "assert-plus": "^1.0.0" } }, "ghreleases": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/ghreleases/-/ghreleases-3.0.2.tgz", "integrity": "sha512-QiR9mIYvRG7hd8JuQYoxeBNOelVuTp2DpdiByRywbCDBSJufK9Vq7VuhD8B+5uviMxZx2AEkCzye61Us9gYgnw==", "dev": true, "requires": { "after": "~0.8.1", "ghrepos": "~2.1.0", "ghutils": "~3.2.0", "lodash.uniq": "^4.5.0", "simple-mime": "~0.1.0", "url-template": "~2.0.6" } }, "ghrepos": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ghrepos/-/ghrepos-2.1.0.tgz", "integrity": "sha512-6GM0ohSDTAv7xD6GsKfxJiV/CajoofRyUwu0E8l29d1o6lFAUxmmyMP/FH33afA20ZrXzxxcTtN6TsYvudMoAg==", "dev": true, "requires": { "ghutils": "~3.2.0" } }, "ghutils": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/ghutils/-/ghutils-3.2.6.tgz", "integrity": "sha512-WpYHgLQkqU7Cv147wKUEThyj6qKHCdnAG2CL9RRsRQImVdLGdVqblJ3JUnj3ToQwgm1ALPS+FXgR0448AgGPUg==", "dev": true, "requires": { "jsonist": "~2.1.0", "xtend": "~4.0.1" } }, "git-raw-commits": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.10.tgz", "integrity": "sha512-sHhX5lsbG9SOO6yXdlwgEMQ/ljIn7qMpAbJZCGfXX2fq5T8M5SrDnpYk9/4HswTildcIqatsWa91vty6VhWSaQ==", "dev": true, "requires": { "dargs": "^7.0.0", "lodash": "^4.17.15", "meow": "^8.0.0", "split2": "^3.0.0", "through2": "^4.0.0" }, "dependencies": { "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "through2": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", "dev": true, "requires": { "readable-stream": "3" } } } }, "git-remote-origin-url": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", "dev": true, "requires": { "gitconfiglocal": "^1.0.0", "pify": "^2.3.0" } }, "git-semver-tags": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", "dev": true, "requires": { "meow": "^8.0.0", "semver": "^6.0.0" }, "dependencies": { "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "gitconfiglocal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", "dev": true, "requires": { "ini": "^1.3.2" } }, "github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, "graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, "graceful-readlink": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", "dev": true }, "growl": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", "dev": true }, "handlebars": { "version": "4.7.7", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", "dev": true, "requires": { "minimist": "^1.2.5", "neo-async": "^2.6.0", "source-map": "^0.6.1", "uglify-js": "^3.1.4", "wordwrap": "^1.0.0" } }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true }, "har-validator": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "dev": true, "requires": { "ajv": "^6.12.3", "har-schema": "^2.0.0" }, "dependencies": { "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true } } }, "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", "dev": true }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "requires": { "function-bind": "^1.1.1" } }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, "hosted-git-info": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", "dev": true, "requires": { "lru-cache": "^6.0.0" }, "dependencies": { "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { "yallist": "^4.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" } }, "hyperquest": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/hyperquest/-/hyperquest-2.1.3.tgz", "integrity": "sha512-fUuDOrB47PqNK/BAMOS13v41UoaqIxqSLHX6CAbOD7OfT+/GCWO1/vPLfTNutOeXrv1ikuaZ3yux+33Z9vh+rw==", "dev": true, "requires": { "buffer-from": "^0.1.1", "duplexer2": "~0.0.2", "through2": "~0.6.3" }, "dependencies": { "buffer-from": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", "integrity": "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==", "dev": true }, "duplexer2": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", "dev": true, "requires": { "readable-stream": "~1.1.9" } }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { "version": "3.3.10", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", "dev": true }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, "indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" } }, "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "inquirer": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", "dev": true, "requires": { "ansi-escapes": "^3.0.0", "chalk": "^2.0.0", "cli-cursor": "^2.1.0", "cli-width": "^2.0.0", "external-editor": "^2.0.4", "figures": "^2.0.0", "lodash": "^4.3.0", "mute-stream": "0.0.7", "run-async": "^2.2.0", "rx-lite": "^4.0.8", "rx-lite-aggregates": "^4.0.8", "string-width": "^2.1.0", "strip-ansi": "^4.0.0", "through": "^2.3.6" }, "dependencies": { "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" } }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" } } } }, "interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, "is-core-module": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", "dev": true, "requires": { "has": "^1.0.3" } }, "is-finite": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { "number-is-nan": "^1.0.0" } }, "is-iojs": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-iojs/-/is-iojs-1.1.0.tgz", "integrity": "sha1-TBEDO11dlNbqs3dd7cm+fQCDJfE=", "dev": true }, "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true }, "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", "dev": true }, "is-text-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", "dev": true, "requires": { "text-extensions": "^1.0.0" } }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, "jest-docblock": { "version": "21.2.0", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz", "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==", "dev": true }, "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, "js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" } }, "js2xmlparser": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz", "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==", "dev": true, "requires": { "xmlcreate": "^2.0.3" } }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, "jsdoc": { "version": "3.6.7", "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.7.tgz", "integrity": "sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw==", "dev": true, "requires": { "@babel/parser": "^7.9.4", "bluebird": "^3.7.2", "catharsis": "^0.9.0", "escape-string-regexp": "^2.0.0", "js2xmlparser": "^4.0.1", "klaw": "^3.0.0", "markdown-it": "^10.0.0", "markdown-it-anchor": "^5.2.7", "marked": "^2.0.3", "mkdirp": "^1.0.4", "requizzle": "^0.2.3", "strip-json-comments": "^3.1.0", "taffydb": "2.6.2", "underscore": "~1.13.1" }, "dependencies": { "escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, "marked": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.7.tgz", "integrity": "sha512-BJXxkuIfJchcXOJWTT2DOL+yFWifFv2yGYOUzvXg8Qz610QKw+sHCvTMYwA+qWGhlA2uivBezChZ/pBy1tWdkQ==", "dev": true }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true } } }, "jsdoc-api": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-5.0.4.tgz", "integrity": "sha512-1KMwLnfo0FyhF06TQKzqIm8BiY1yoMIGICxRdJHUjzskaHMzHMmpLlmNFgzoa4pAC8t1CDPK5jWuQTvv1pBsEQ==", "dev": true, "requires": { "array-back": "^4.0.0", "cache-point": "^1.0.0", "collect-all": "^1.0.3", "file-set": "^2.0.1", "fs-then-native": "^2.0.0", "jsdoc": "^3.6.3", "object-to-spawn-args": "^1.1.1", "temp-path": "^1.0.0", "walk-back": "^3.0.1" }, "dependencies": { "file-set": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/file-set/-/file-set-2.0.1.tgz", "integrity": "sha512-XgOUUpgR6FbbfYcniLw0qm1Am7PnNYIAkd+eXxRt42LiYhjaso0WiuQ+VmrNdtwotyM+cLCfZ56AZrySP3QnKA==", "dev": true, "requires": { "array-back": "^2.0.0", "glob": "^7.1.3" }, "dependencies": { "array-back": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", "dev": true, "requires": { "typical": "^2.6.1" } } } }, "walk-back": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-3.0.1.tgz", "integrity": "sha512-umiNB2qLO731Sxbp6cfZ9pwURJzTnftxE4Gc7hq8n/ehkuXC//s9F65IEIJA2ZytQZ1ZOsm/Fju4IWx0bivkUQ==", "dev": true } } }, "jsdoc-parse": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-4.0.1.tgz", "integrity": "sha512-qIObw8yqYZjrP2qxWROB5eLQFLTUX2jRGLhW9hjo2CC2fQVlskidCIzjCoctwsDvauBp2a/lR31jkSleczSo8Q==", "dev": true, "requires": { "array-back": "^4.0.0", "lodash.omit": "^4.5.0", "lodash.pick": "^4.4.0", "reduce-extract": "^1.0.0", "sort-array": "^2.0.0", "test-value": "^3.0.0" } }, "jsdoc-to-markdown": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-5.0.3.tgz", "integrity": "sha512-tQv5tBV0fTYidRQtE60lJKxE98mmuLcYuITFDKQiDPE9hGccpeEGUNFcVkInq1vigyuPnZmt79bQ8wv2GKjY0Q==", "dev": true, "requires": { "array-back": "^4.0.1", "command-line-tool": "^0.8.0", "config-master": "^3.1.0", "dmd": "^4.0.5", "jsdoc-api": "^5.0.4", "jsdoc-parse": "^4.0.1", "walk-back": "^4.0.0" } }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "dev": true }, "json-schema-traverse": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, "requires": { "graceful-fs": "^4.1.6" } }, "jsonist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/jsonist/-/jsonist-2.1.2.tgz", "integrity": "sha512-8yqmWJAC2VaYoSKQAbsfgCpGY5o/1etWzx6ZxaZrC4iGaHrHUZEo+a2MyF8w+2uTavTlHdLWaZUoR19UfBstxQ==", "dev": true, "requires": { "bl": "~3.0.0", "hyperquest": "~2.1.3", "json-stringify-safe": "~5.0.1", "xtend": "~4.0.1" }, "dependencies": { "bl": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.1.tgz", "integrity": "sha512-jrCW5ZhfQ/Vt07WX1Ngs+yn9BDqPL/gw28S7s9H6QK/gupnizNzJAss5akW20ISgOrbLTlXOOCTJeNUQqruAWQ==", "dev": true, "requires": { "readable-stream": "^3.0.1" } }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } } } }, "jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", "dev": true }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", "dev": true, "requires": { "jsonparse": "^1.2.0", "through": ">=2.2.7 <3" } }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", "json-schema": "0.2.3", "verror": "1.10.0" } }, "just-extend": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", "dev": true }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, "klaw": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", "dev": true, "requires": { "graceful-fs": "^4.1.9" } }, "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "dev": true, "requires": { "invert-kv": "^1.0.0" } }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" } }, "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, "linkify-it": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", "dev": true, "requires": { "uc.micro": "^1.0.1" } }, "listenercount": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", "dev": true }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", "pify": "^2.0.0", "pinkie-promise": "^2.0.0", "strip-bom": "^2.0.0" }, "dependencies": { "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { "error-ex": "^1.2.0" } } } }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { "p-locate": "^4.1.0" } }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", "dev": true }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, "lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", "dev": true }, "lodash.omit": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=", "dev": true }, "lodash.pad": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", "integrity": "sha1-QzCUmoM6fI2iLMIPaibE1Z3runA=", "dev": true }, "lodash.padend": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=", "dev": true }, "lodash.padstart": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=", "dev": true }, "lodash.pick": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=", "dev": true }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", "dev": true }, "lolex": { "version": "2.7.5", "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", "dev": true }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "dev": true, "requires": { "currently-unhandled": "^0.4.1", "signal-exit": "^3.0.0" } }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "map-obj": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==", "dev": true }, "markdown-it": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", "dev": true, "requires": { "argparse": "^1.0.7", "entities": "~2.0.0", "linkify-it": "^2.0.0", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" } }, "markdown-it-anchor": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz", "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==", "dev": true, "requires": {} }, "marked": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", "dev": true }, "mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", "dev": true }, "memory-pager": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", "dev": true, "optional": true }, "memory-stream": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/memory-stream/-/memory-stream-0.0.3.tgz", "integrity": "sha1-6+jdHDuLw4wOeUHp3dWuvmtN6D8=", "dev": true, "requires": { "readable-stream": "~1.0.26-2" }, "dependencies": { "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "readable-stream": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "meow": { "version": "8.1.2", "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", "dev": true, "requires": { "@types/minimist": "^1.2.0", "camelcase-keys": "^6.2.2", "decamelize-keys": "^1.1.0", "hard-rejection": "^2.1.0", "minimist-options": "4.1.0", "normalize-package-data": "^3.0.0", "read-pkg-up": "^7.0.1", "redent": "^3.0.0", "trim-newlines": "^3.0.0", "type-fest": "^0.18.0", "yargs-parser": "^20.2.3" }, "dependencies": { "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { "@types/normalize-package-data": "^2.4.0", "normalize-package-data": "^2.5.0", "parse-json": "^5.0.0", "type-fest": "^0.6.0" }, "dependencies": { "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, "type-fest": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true } } }, "read-pkg-up": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "requires": { "find-up": "^4.1.0", "read-pkg": "^5.2.0", "type-fest": "^0.8.1" }, "dependencies": { "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true } } } } }, "mime-db": { "version": "1.48.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", "dev": true }, "mime-types": { "version": "2.1.31", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", "dev": true, "requires": { "mime-db": "1.48.0" } }, "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, "mimic-response": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==" }, "min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minimist-options": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, "requires": { "arrify": "^1.0.1", "is-plain-obj": "^1.1.0", "kind-of": "^6.0.3" } }, "minipass": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", "dev": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" }, "dependencies": { "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } }, "minizlib": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", "dev": true, "requires": { "minipass": "^2.9.0" } }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { "minimist": "^1.2.5" } }, "mkdirp-classic": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, "mkdirp2": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp2/-/mkdirp2-1.0.4.tgz", "integrity": "sha512-Q2PKB4ZR4UPtjLl76JfzlgSCUZhSV1AXQgAZa1qt5RiaALFjP/CDrGvFBrOz7Ck6McPcwMAxTsJvWOUjOU8XMw==", "dev": true }, "mocha": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", "dev": true, "requires": { "browser-stdout": "1.3.0", "commander": "2.11.0", "debug": "3.1.0", "diff": "3.3.1", "escape-string-regexp": "1.0.5", "glob": "7.1.2", "growl": "1.10.3", "he": "1.1.1", "mkdirp": "0.5.1", "supports-color": "4.4.0" }, "dependencies": { "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { "ms": "2.0.0" } }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { "minimist": "0.0.8" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "supports-color": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", "dev": true, "requires": { "has-flag": "^2.0.0" } } } }, "modify-values": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", "dev": true }, "mongodb": { "version": "3.6.9", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.9.tgz", "integrity": "sha512-1nSCKgSunzn/CXwgOWgbPHUWOO5OfERcuOWISmqd610jn0s8BU9K4879iJVabqgpPPbA6hO7rG48eq+fGED3Mg==", "dev": true, "requires": { "bl": "^2.2.1", "bson": "^1.1.4", "denque": "^1.4.1", "optional-require": "^1.0.3", "safe-buffer": "^5.1.2", "saslprep": "^1.0.0" }, "dependencies": { "bson": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==", "dev": true } } }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, "nan": { "version": "2.14.2", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", "dev": true }, "napi-build-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, "next-tick": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, "nise": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", "integrity": "sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==", "dev": true, "requires": { "@sinonjs/formatio": "^3.2.1", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", "lolex": "^5.0.1", "path-to-regexp": "^1.7.0" }, "dependencies": { "@sinonjs/formatio": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", "dev": true, "requires": { "@sinonjs/commons": "^1", "@sinonjs/samsam": "^3.1.0" } }, "lolex": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0" } } } }, "node-abi": { "version": "2.30.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.0.tgz", "integrity": "sha512-g6bZh3YCKQRdwuO/tSZZYJAw622SjsRfJ2X0Iy4sSOHZ34/sPPdVBn8fev2tj7njzLwuqPw9uMtGsGkO5kIQvg==", "requires": { "semver": "^5.4.1" } }, "node-addon-api": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.1.0.tgz", "integrity": "sha512-Zz1o1BDX2VtduiAt6kgiUl8jX1Vm3NMboljFYKQJ6ee8AGfiTvM2mlZFI3xPbqjs80rCQgiVJI/DjQ/1QJ0HwA==" }, "node-gyp": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.1.tgz", "integrity": "sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw==", "dev": true, "requires": { "env-paths": "^2.2.0", "glob": "^7.1.4", "graceful-fs": "^4.2.2", "mkdirp": "^0.5.1", "nopt": "^4.0.1", "npmlog": "^4.1.2", "request": "^2.88.0", "rimraf": "^2.6.3", "semver": "^5.7.1", "tar": "^4.4.12", "which": "^1.3.1" }, "dependencies": { "tar": { "version": "4.4.13", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", "minipass": "^2.8.6", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", "yallist": "^3.0.3" } }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } }, "node-ninja": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/node-ninja/-/node-ninja-1.0.2.tgz", "integrity": "sha1-IKCeV7kuLfWRmT1L8JisPnJwYrY=", "dev": true, "requires": { "fstream": "^1.0.0", "glob": "3 || 4 || 5 || 6 || 7", "graceful-fs": "^4.1.2", "minimatch": "3", "mkdirp": "^0.5.0", "nopt": "2 || 3", "npmlog": "0 || 1 || 2", "osenv": "0", "path-array": "^1.0.0", "request": "2", "rimraf": "2", "semver": "2.x || 3.x || 4 || 5", "tar": "^2.0.0", "which": "1" }, "dependencies": { "gauge": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", "integrity": "sha1-6c7FSD09TuDvRLYKfZnkk14TbZM=", "dev": true, "requires": { "ansi": "^0.3.0", "has-unicode": "^2.0.0", "lodash.pad": "^4.1.0", "lodash.padend": "^4.1.0", "lodash.padstart": "^4.1.0" } }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { "abbrev": "1" } }, "npmlog": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", "integrity": "sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI=", "dev": true, "requires": { "ansi": "~0.3.1", "are-we-there-yet": "~1.1.2", "gauge": "~1.2.5" } }, "tar": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", "fstream": "^1.0.12", "inherits": "2" } } } }, "noop-logger": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" }, "nopt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", "dev": true, "requires": { "abbrev": "1", "osenv": "^0.1.4" } }, "normalize-package-data": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.2.tgz", "integrity": "sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg==", "dev": true, "requires": { "hosted-git-info": "^4.0.1", "resolve": "^1.20.0", "semver": "^7.3.4", "validate-npm-package-license": "^3.0.1" }, "dependencies": { "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { "yallist": "^4.0.0" } }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" } }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } }, "npm-path": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.4.tgz", "integrity": "sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw==", "dev": true, "requires": { "which": "^1.2.10" } }, "npm-which": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/npm-which/-/npm-which-3.0.1.tgz", "integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=", "dev": true, "requires": { "commander": "^2.9.0", "npm-path": "^2.0.2", "which": "^1.2.10" } }, "npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", "gauge": "~2.7.3", "set-blocking": "~2.0.0" } }, "null-check": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", "dev": true }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "nw-gyp": { "version": "3.6.5", "resolved": "https://registry.npmjs.org/nw-gyp/-/nw-gyp-3.6.5.tgz", "integrity": "sha512-vYrOIYJEKpq9CfaHuiqEjV1rBYgr6uaUrPhPRiznb91LujkAUqGhQ5QqDC1bLdd+zo9jf2H0Zkl2M5zQB7+CuQ==", "dev": true, "requires": { "fstream": "^1.0.0", "glob": "^7.0.3", "graceful-fs": "^4.1.2", "minimatch": "^3.0.2", "mkdirp": "^0.5.0", "nopt": "2 || 3", "npmlog": "0 || 1 || 2 || 3 || 4", "osenv": "0", "request": "2", "rimraf": "2", "semver": "~5.3.0", "tar": "^2.0.0", "which": "1" }, "dependencies": { "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { "abbrev": "1" } }, "semver": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "dev": true }, "tar": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { "block-stream": "*", "fstream": "^1.0.12", "inherits": "2" } } } }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-get": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/object-get/-/object-get-2.1.1.tgz", "integrity": "sha512-7n4IpLMzGGcLEMiQKsNR7vCe+N5E9LORFrtNUVy4sO3dj9a3HedZCxEL2T7QuLhcHN1NBuBsMOKaOsAYI9IIvg==", "dev": true }, "object-to-spawn-args": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-to-spawn-args/-/object-to-spawn-args-1.1.1.tgz", "integrity": "sha1-d9qIJ/Bz0BHJ4bFz+JV4FHAkZ4U=", "dev": true }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { "wrappy": "1" } }, "onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { "mimic-fn": "^1.0.0" } }, "optional-require": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz", "integrity": "sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==", "dev": true }, "optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.6", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", "word-wrap": "~1.2.3" } }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, "os-locale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, "requires": { "lcid": "^1.0.0" } }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, "osenv": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "requires": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" } }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" } }, "p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { "p-limit": "^2.2.0" } }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "parse-github-repo-url": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz", "integrity": "sha1-nn2LslKmy2ukJZUGC3v23z28H1A=", "dev": true }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "path-array": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-array/-/path-array-1.0.1.tgz", "integrity": "sha1-fi8PNfB6IBUSK4aLfqwOssT+wnE=", "dev": true, "requires": { "array-index": "^1.0.0" } }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "path-to-regexp": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", "dev": true, "requires": { "isarray": "0.0.1" }, "dependencies": { "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true } } }, "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "pify": "^2.0.0", "pinkie-promise": "^2.0.0" } }, "pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", "dev": true }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { "pinkie": "^2.0.0" } }, "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", "dev": true }, "prebuild": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/prebuild/-/prebuild-10.0.1.tgz", "integrity": "sha512-x0CkKDmHFwX49rTGEYJwB9jBQwJWxRzwUtP5PA9dP8khFGMm3oSFgYortxdlp0PkxB29EhWGp/KQE5g+adehYg==", "dev": true, "requires": { "cmake-js": "~5.2.0", "detect-libc": "^1.0.3", "each-series-async": "^1.0.1", "execspawn": "^1.0.1", "ghreleases": "^3.0.2", "github-from-package": "0.0.0", "glob": "^7.1.6", "minimist": "^1.1.2", "mkdirp": "^0.5.1", "napi-build-utils": "^1.0.1", "node-abi": "^2.2.0", "node-gyp": "^6.0.1", "node-ninja": "^1.0.1", "noop-logger": "^0.1.0", "npm-which": "^3.0.1", "npmlog": "^4.0.1", "nw-gyp": "^3.6.3", "rc": "^1.0.3", "run-waterfall": "^1.1.6", "tar-stream": "^2.1.0" }, "dependencies": { "node-gyp": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-6.1.0.tgz", "integrity": "sha512-h4A2zDlOujeeaaTx06r4Vy+8MZ1679lU+wbCKDS4ZtvY2A37DESo37oejIw0mtmR3+rvNwts5B6Kpt1KrNYdNw==", "dev": true, "requires": { "env-paths": "^2.2.0", "glob": "^7.1.4", "graceful-fs": "^4.2.2", "mkdirp": "^0.5.1", "nopt": "^4.0.1", "npmlog": "^4.1.2", "request": "^2.88.0", "rimraf": "^2.6.3", "semver": "^5.7.1", "tar": "^4.4.12", "which": "^1.3.1" } }, "tar": { "version": "4.4.13", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", "minipass": "^2.8.6", "minizlib": "^1.2.1", "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", "yallist": "^3.0.3" } }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } }, "prebuild-install": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.1.2.tgz", "integrity": "sha512-PzYWIKZeP+967WuKYXlTOhYBgGOvTRSfaKI89XnfJ0ansRAH7hDU45X+K+FZeI1Wb/7p/NnuctPH3g0IqKUuSQ==", "requires": { "detect-libc": "^1.0.3", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", "node-abi": "^2.21.0", "noop-logger": "^0.1.1", "npmlog": "^4.0.1", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^3.0.3", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" } }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, "prettier": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "dev": true }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "dev": true }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", "dev": true }, "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, "quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" } }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "requires": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", "path-type": "^3.0.0" }, "dependencies": { "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" } }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" } }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { "pify": "^3.0.0" } }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true } } }, "read-pkg-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", "dev": true, "requires": { "find-up": "^2.0.0", "read-pkg": "^3.0.0" }, "dependencies": { "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { "locate-path": "^2.0.0" } }, "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" } }, "p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, "requires": { "p-try": "^1.0.0" } }, "p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { "p-limit": "^1.1.0" } }, "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true } } }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" }, "dependencies": { "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, "rechoir": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "dev": true, "requires": { "resolve": "^1.1.6" } }, "redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "requires": { "indent-string": "^4.0.0", "strip-indent": "^3.0.0" } }, "reduce-extract": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz", "integrity": "sha1-Z/I4W+2mUGG19fQxJmLosIDKFSU=", "dev": true, "requires": { "test-value": "^1.0.1" }, "dependencies": { "array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", "dev": true, "requires": { "typical": "^2.6.0" } }, "test-value": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-1.1.0.tgz", "integrity": "sha1-oJE29y7AQ9J8iTcHwrFZv6196T8=", "dev": true, "requires": { "array-back": "^1.0.2", "typical": "^2.4.2" } } } }, "reduce-flatten": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz", "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=", "dev": true }, "reduce-unique": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/reduce-unique/-/reduce-unique-2.0.1.tgz", "integrity": "sha512-x4jH/8L1eyZGR785WY+ePtyMNhycl1N2XOLxhCbzZFaqF4AXjLzqSxa2UHgJ2ZVR/HHyPOvl1L7xRnW8ye5MdA==", "dev": true }, "reduce-without": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/reduce-without/-/reduce-without-1.0.1.tgz", "integrity": "sha1-aK0OrRGFXJo31OglbBW7+Hly/Iw=", "dev": true, "requires": { "test-value": "^2.0.0" }, "dependencies": { "array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", "dev": true, "requires": { "typical": "^2.6.0" } }, "test-value": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=", "dev": true, "requires": { "array-back": "^1.0.3", "typical": "^2.6.0" } } } }, "regexpp": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", "dev": true }, "repeating": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { "is-finite": "^1.0.0" } }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", "caseless": "~0.12.0", "combined-stream": "~1.0.6", "extend": "~3.0.2", "forever-agent": "~0.6.1", "form-data": "~2.3.2", "har-validator": "~5.1.3", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", "json-stringify-safe": "~5.0.1", "mime-types": "~2.1.19", "oauth-sign": "~0.9.0", "performance-now": "^2.1.0", "qs": "~6.5.2", "safe-buffer": "^5.1.2", "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" } }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, "require-uncached": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { "caller-path": "^0.1.0", "resolve-from": "^1.0.0" } }, "requizzle": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz", "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==", "dev": true, "requires": { "lodash": "^4.17.14" } }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "requires": { "is-core-module": "^2.2.0", "path-parse": "^1.0.6" } }, "resolve-from": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", "dev": true }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "requires": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" } }, "rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "requires": { "glob": "^7.1.3" } }, "rsvp": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz", "integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==", "dev": true }, "run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true }, "run-waterfall": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/run-waterfall/-/run-waterfall-1.1.7.tgz", "integrity": "sha512-iFPgh7SatHXOG1ClcpdwHI63geV3Hc/iL6crGSyBlH2PY7Rm/za+zoKz6FfY/Qlw5K7JwSol8pseO8fN6CMhhQ==", "dev": true }, "rx-lite": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", "dev": true }, "rx-lite-aggregates": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", "dev": true, "requires": { "rx-lite": "*" } }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, "samsam": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", "dev": true }, "saslprep": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", "dev": true, "optional": true, "requires": { "sparse-bitfield": "^3.0.3" } }, "segfault-handler": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/segfault-handler/-/segfault-handler-1.3.0.tgz", "integrity": "sha512-p7kVHo+4uoYkr0jmIiTBthwV5L2qmWtben/KDunDZ834mbos+tY+iO0//HpAJpOFSQZZ+wxKWuRo4DxV02B7Lg==", "dev": true, "requires": { "bindings": "^1.2.1", "nan": "^2.14.0" } }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", "dev": true }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { "shebang-regex": "^1.0.0" } }, "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, "shelljs": { "version": "0.8.4", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", "dev": true, "requires": { "glob": "^7.0.0", "interpret": "^1.0.0", "rechoir": "^0.6.2" } }, "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, "simple-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" }, "simple-get": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", "requires": { "decompress-response": "^4.2.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "simple-mime": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/simple-mime/-/simple-mime-0.1.0.tgz", "integrity": "sha1-lfUXxPRm18/1YacfydqyWW6p7y4=", "dev": true }, "sinon": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", "dev": true, "requires": { "@sinonjs/formatio": "^2.0.0", "diff": "^3.1.0", "lodash.get": "^4.4.2", "lolex": "^2.2.0", "nise": "^1.2.0", "supports-color": "^5.1.0", "type-detect": "^4.0.5" }, "dependencies": { "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" } } } }, "sinon-chai": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", "dev": true, "requires": {} }, "slice-ansi": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0" }, "dependencies": { "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true } } }, "sort-array": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-2.0.0.tgz", "integrity": "sha1-OKnG2if9fRR7QuYFVPKBGHtN9HI=", "dev": true, "requires": { "array-back": "^1.0.4", "object-get": "^2.1.0", "typical": "^2.6.0" }, "dependencies": { "array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", "dev": true, "requires": { "typical": "^2.6.0" } } } }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "source-map-support": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.2.10.tgz", "integrity": "sha1-6lo5AKHByyUJagrozFwrSxDe09w=", "dev": true, "requires": { "source-map": "0.1.32" }, "dependencies": { "source-map": { "version": "0.1.32", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz", "integrity": "sha1-yLbBZ3l7pHQKjqMyUhYv8IWRsmY=", "dev": true, "requires": { "amdefine": ">=0.0.4" } } } }, "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", "dev": true, "optional": true, "requires": { "memory-pager": "^1.0.2" } }, "spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "spdx-exceptions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, "spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "spdx-license-ids": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", "dev": true }, "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", "dev": true, "requires": { "through": "2" } }, "split2": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", "dev": true, "requires": { "readable-stream": "^3.0.0" }, "dependencies": { "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } } } }, "splitargs": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/splitargs/-/splitargs-0.0.7.tgz", "integrity": "sha1-/p965lc3GzOxDLgNoUPPgknPazs=", "dev": true }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", "bcrypt-pbkdf": "^1.0.0", "dashdash": "^1.12.0", "ecc-jsbn": "~0.1.1", "getpass": "^0.1.1", "jsbn": "~0.1.0", "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" } }, "standard-version": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.3.0.tgz", "integrity": "sha512-cYxxKXhYfI3S9+CA84HmrJa9B88H56V5FQ302iFF2TNwJukJCNoU8FgWt+11YtwKFXRkQQFpepC2QOF7aDq2Ow==", "dev": true, "requires": { "chalk": "^2.4.2", "conventional-changelog": "3.1.24", "conventional-changelog-config-spec": "2.1.0", "conventional-changelog-conventionalcommits": "4.5.0", "conventional-recommended-bump": "6.1.0", "detect-indent": "^6.0.0", "detect-newline": "^3.1.0", "dotgitignore": "^2.1.0", "figures": "^3.1.0", "find-up": "^5.0.0", "fs-access": "^1.0.1", "git-semver-tags": "^4.0.0", "semver": "^7.1.1", "stringify-package": "^1.0.1", "yargs": "^16.0.0" }, "dependencies": { "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { "color-convert": "^2.0.1" } }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" } }, "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" } }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { "yallist": "^4.0.0" } }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" } }, "string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.0" } }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { "ansi-regex": "^5.0.0" } }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } } } }, "stream-connect": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-connect/-/stream-connect-1.0.2.tgz", "integrity": "sha1-GLyB8u2zW4tdmoAJIAqYUxRCipc=", "dev": true, "requires": { "array-back": "^1.0.2" }, "dependencies": { "array-back": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=", "dev": true, "requires": { "typical": "^2.6.0" } } } }, "stream-via": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/stream-via/-/stream-via-1.0.4.tgz", "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==", "dev": true }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" }, "dependencies": { "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", "strip-ansi": "^3.0.0" } }, "stringify-package": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz", "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==", "dev": true }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" } }, "strip-bom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { "is-utf8": "^0.2.0" } }, "strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, "requires": { "min-indent": "^1.0.0" } }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, "table": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "dev": true, "requires": { "ajv": "^5.2.3", "ajv-keywords": "^2.1.0", "chalk": "^2.1.0", "lodash": "^4.17.4", "slice-ansi": "1.0.0", "string-width": "^2.1.1" }, "dependencies": { "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" } }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" } } } }, "table-layout": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz", "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==", "dev": true, "requires": { "array-back": "^2.0.0", "deep-extend": "~0.6.0", "lodash.padend": "^4.6.1", "typical": "^2.6.1", "wordwrapjs": "^3.0.0" }, "dependencies": { "array-back": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", "dev": true, "requires": { "typical": "^2.6.1" } } } }, "taffydb": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=", "dev": true }, "tar": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", "dev": true, "requires": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^3.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" }, "dependencies": { "chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true }, "fs-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, "requires": { "minipass": "^3.0.0" } }, "minipass": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", "dev": true, "requires": { "yallist": "^4.0.0" } }, "minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "dev": true, "requires": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } }, "tar-fs": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "requires": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "requires": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" }, "dependencies": { "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", "requires": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } } } }, "temp-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/temp-path/-/temp-path-1.0.0.tgz", "integrity": "sha1-JLFUOXOrRCiW2a02fdnL2/r+kYs=", "dev": true }, "test-value": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/test-value/-/test-value-3.0.0.tgz", "integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==", "dev": true, "requires": { "array-back": "^2.0.0", "typical": "^2.6.1" }, "dependencies": { "array-back": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", "dev": true, "requires": { "typical": "^2.6.1" } } } }, "text-extensions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", "dev": true }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, "through2": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { "readable-stream": ">=1.0.33-1 <1.1.0-0", "xtend": ">=4.0.0 <4.1.0-0" }, "dependencies": { "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "readable-stream": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "0.0.1", "string_decoder": "~0.10.x" } }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { "os-tmpdir": "~1.0.2" } }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { "psl": "^1.1.28", "punycode": "^2.1.1" } }, "traceur": { "version": "0.0.111", "resolved": "https://registry.npmjs.org/traceur/-/traceur-0.0.111.tgz", "integrity": "sha1-wE3nTRRpbDNzQn3k/Ajsr5E/w6E=", "dev": true, "requires": { "commander": "2.9.x", "glob": "5.0.x", "rsvp": "^3.0.13", "semver": "^4.3.3", "source-map-support": "~0.2.8" }, "dependencies": { "commander": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", "dev": true, "requires": { "graceful-readlink": ">= 1.0.0" } }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { "inflight": "^1.0.4", "inherits": "2", "minimatch": "2 || 3", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "semver": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", "dev": true } } }, "traverse": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", "dev": true }, "trim-newlines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, "trim-off-newlines": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", "dev": true }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "requires": { "safe-buffer": "^5.0.1" } }, "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, "type": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", "dev": true }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { "prelude-ls": "~1.1.2" } }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, "type-fest": { "version": "0.18.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, "typical": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=", "dev": true }, "uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", "dev": true }, "uglify-js": { "version": "3.13.9", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.9.tgz", "integrity": "sha512-wZbyTQ1w6Y7fHdt8sJnHfSIuWeDgk6B5rCb4E/AM6QNNPbOMIZph21PW5dRB3h7Df0GszN+t7RuUH6sWK5bF0g==", "dev": true, "optional": true }, "underscore": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==", "dev": true }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, "unzipper": { "version": "0.8.14", "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.8.14.tgz", "integrity": "sha512-8rFtE7EP5ssOwGpN2dt1Q4njl0N1hUXJ7sSPz0leU2hRdq6+pra57z4YPBlVqm40vcgv6ooKZEAx48fMTv9x4w==", "dev": true, "requires": { "big-integer": "^1.6.17", "binary": "~0.3.0", "bluebird": "~3.4.1", "buffer-indexof-polyfill": "~1.0.0", "duplexer2": "~0.1.4", "fstream": "~1.0.10", "listenercount": "~1.0.1", "readable-stream": "~2.1.5", "setimmediate": "~1.0.4" }, "dependencies": { "bluebird": { "version": "3.4.7", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", "dev": true }, "process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", "dev": true }, "readable-stream": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz", "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=", "dev": true, "requires": { "buffer-shims": "^1.0.0", "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "~1.0.0", "process-nextick-args": "~1.0.6", "string_decoder": "~0.10.x", "util-deprecate": "~1.0.1" } }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true } } }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { "punycode": "^2.1.0" } }, "url-join": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/url-join/-/url-join-0.0.1.tgz", "integrity": "sha1-HbSK1CLTQCRpqH99l73r/k+x48g=", "dev": true }, "url-template": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=", "dev": true }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "util-extend": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz", "integrity": "sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=", "dev": true }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "requires": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, "walk-back": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-4.0.0.tgz", "integrity": "sha512-kudCA8PXVQfrqv2mFTG72vDBRi8BKWxGgFLwPpzHcpZnSwZk93WMwUDVcLHWNsnm+Y0AC4Vb6MUNRgaHfyV2DQ==", "dev": true }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { "isexe": "^2.0.0" } }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "requires": { "string-width": "^1.0.2 || 2" } }, "window-size": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", "dev": true }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", "dev": true }, "wordwrapjs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz", "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==", "dev": true, "requires": { "reduce-flatten": "^1.0.1", "typical": "^2.6.1" } }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" } }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "dev": true, "requires": { "mkdirp": "^0.5.1" } }, "xmlcreate": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz", "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==", "dev": true }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true }, "y18n": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", "dev": true }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, "yargs": { "version": "3.32.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", "dev": true, "requires": { "camelcase": "^2.0.1", "cliui": "^3.0.3", "decamelize": "^1.1.1", "os-locale": "^1.4.0", "string-width": "^1.0.1", "window-size": "^0.1.4", "y18n": "^3.2.0" } }, "yargs-parser": { "version": "20.2.7", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", "dev": true }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true } } } libmongocrypt-1.3.0/bindings/node/package.json000066400000000000000000000041601414105245100214110ustar00rootroot00000000000000{ "name": "mongodb-client-encryption", "version": "2.0.0-beta.0", "description": "Official client encryption module for the MongoDB Node.js driver", "main": "index.js", "types": "index.d.ts", "files": [ "index.js", "README.md", "CHANGELOG.md", "lib", "src", "index.d.ts", "binding.gyp" ], "directories": { "lib": "lib" }, "scripts": { "install": "prebuild-install --runtime napi --tag-prefix node-v || node-gyp rebuild", "format-cxx": "git-clang-format", "format-js": "prettier --print-width 100 --tab-width 2 --single-quote --write index.js 'test/**/*.js' 'lib/**/*.js'", "lint": "eslint lib test", "docs": "jsdoc2md --template etc/README.hbs --plugin dmd-clear --files lib/**/*.js > README.md", "test": "mocha test", "rebuild": "prebuild --compile", "release": "standard-version --tag-prefix node-v --path bindings/node", "prebuild": "prebuild --runtime napi --strip --verbose --tag-prefix node-v --all" }, "author": { "name": "The MongoDB NodeJS Team", "email": "dbx-node@mongodb.com" }, "bugs": { "url": "https://jira.mongodb.org/projects/NODE/issues/" }, "license": "Apache-2.0", "gypfile": true, "dependencies": { "bindings": "^1.5.0", "bl": "^2.2.1", "node-addon-api": "^4.1.0", "prebuild-install": "6.1.2" }, "devDependencies": { "bson": "^4.4.0", "chai": "^4.3.4", "chai-subset": "^1.6.0", "clang-format": "^1.5.0", "dmd-clear": "^0.1.2", "eslint": "^4.19.1", "eslint-plugin-prettier": "^2.7.0", "jsdoc-to-markdown": "^5.0.3", "mocha": "^4.1.0", "mongodb": "^3.6.9", "node-gyp": "^5.1.1", "prebuild": "^10.0.1", "prettier": "^1.19.1", "segfault-handler": "^1.3.0", "sinon": "^4.5.0", "sinon-chai": "^3.6.0", "standard-version": "^9.3.0", "tar": "^6.1.0" }, "peerDependencies": { "mongodb": ">=3.4.0" }, "engines": { "node": ">=12.9.0" }, "binary": { "napi_versions": [ 4 ] }, "repository": { "type": "git", "url": "https://github.com/mongodb/libmongocrypt", "directory": "bindings/node" } } libmongocrypt-1.3.0/bindings/node/src/000077500000000000000000000000001414105245100177115ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/node/src/mongocrypt.cc000066400000000000000000000733521414105245100224330ustar00rootroot00000000000000#include "mongocrypt.h" #include namespace node_mongocrypt { using namespace Napi; // anonymous namepace for helpers namespace { struct InstanceData { Reference MongoCryptContextCtor; Reference MongoCryptKMSRequestCtor; }; struct MongoCryptStatusDeleter { void operator()(mongocrypt_status_t* status) { mongocrypt_status_destroy(status); } }; Object ExtractStatus(Env env, mongocrypt_status_t* status) { Object result = Object::New(env); result["type"] = Number::New(env, mongocrypt_status_type(status)); result["code"] = Number::New(env, mongocrypt_status_code(status)); const char* message = mongocrypt_status_message(status, nullptr); if (message != nullptr) { result["message"] = String::New(env, message); } return result; } std::unique_ptr BufferToBinary(Uint8Array node_buffer) { uint8_t* buffer = node_buffer.Data(); size_t buffer_len = node_buffer.ByteLength(); return std::unique_ptr( mongocrypt_binary_new_from_data(buffer, buffer_len)); } Uint8Array BufferFromBinary(Env env, mongocrypt_binary_t* binary) { const uint8_t* data = mongocrypt_binary_data(binary); size_t len = mongocrypt_binary_len(binary); return Buffer::Copy(env, data, len); } Uint8Array BufferWithLengthOf(Env env, mongocrypt_binary_t* binary) { size_t len = mongocrypt_binary_len(binary); return Buffer::New(env, len); } void CopyBufferData(mongocrypt_binary_t* out, Uint8Array buffer, size_t count) { assert(count <= mongocrypt_binary_len(out)); assert(count <= buffer.ByteLength()); memcpy(mongocrypt_binary_data(out), buffer.Data(), count); } void CopyBufferData(mongocrypt_binary_t* out, Uint8Array buffer) { CopyBufferData(out, buffer, mongocrypt_binary_len(out)); } std::string errorStringFromStatus(mongocrypt_t* crypt) { std::unique_ptr status(mongocrypt_status_new()); mongocrypt_status(crypt, status.get()); const char* errorMessage = mongocrypt_status_message(status.get(), nullptr); if (!errorMessage) { return "Operation failed"; } return errorMessage; } std::string errorStringFromStatus(mongocrypt_ctx_t* context) { std::unique_ptr status(mongocrypt_status_new()); mongocrypt_ctx_status(context, status.get()); const char* errorMessage = mongocrypt_status_message(status.get(), nullptr); if (!errorMessage) { return "Operation failed"; } return errorMessage; } } // anonymous namespace Function MongoCrypt::Init(Napi::Env env) { return DefineClass(env, "MongoCrypt", { InstanceMethod("makeEncryptionContext", &MongoCrypt::MakeEncryptionContext), InstanceMethod("makeExplicitEncryptionContext", &MongoCrypt::MakeExplicitEncryptionContext), InstanceMethod("makeDecryptionContext", &MongoCrypt::MakeDecryptionContext), InstanceMethod("makeExplicitDecryptionContext", &MongoCrypt::MakeExplicitDecryptionContext), InstanceMethod("makeDataKeyContext", &MongoCrypt::MakeDataKeyContext), InstanceAccessor("status", &MongoCrypt::Status, nullptr) }); } void MongoCrypt::logHandler(mongocrypt_log_level_t level, const char* message, uint32_t message_len, void* ctx) { MongoCrypt* mongoCrypt = static_cast(ctx); if (!mongoCrypt) { fprintf(stderr, "Log handler called without `MongoCrypt` instance\n"); return; } Napi::Env env = mongoCrypt->Env(); HandleScope scope(env); Function logger = mongoCrypt->GetCallback("logger"); if (logger.IsEmpty()) { fprintf(stderr, "No logger set, but log handler registered\n"); return; } try { logger.Call(std::initializer_list { Number::New(env, level), String::New(env, message, message_len) }); } catch (const std::exception& ex) { fprintf(stderr, "Uncaught exception in logger callback: %s\n", ex.what()); } catch (...) { fprintf(stderr, "Uncaught exception in logger callback\n"); } } static void MaybeSetCryptoHookErrorStatus(Value result, mongocrypt_status_t *status) { if (!result.IsObject()) { return; } Object hookError = result.As(); if (!hookError.Has("message")) { return; } std::string errorMessage = hookError.Get("message").ToString(); mongocrypt_status_set( status, MONGOCRYPT_STATUS_ERROR_CLIENT, 1, errorMessage.c_str(), errorMessage.length() + 1 ); } bool MongoCrypt::setupCryptoHooks() { auto aes_256_cbc_encrypt = [](void *ctx, mongocrypt_binary_t *key, mongocrypt_binary_t *iv, mongocrypt_binary_t *in, mongocrypt_binary_t *out, uint32_t *bytes_written, mongocrypt_status_t *status) -> bool { MongoCrypt* mongoCrypt = static_cast(ctx); Napi::Env env = mongoCrypt->Env(); HandleScope scope(env); Function hook = mongoCrypt->GetCallback("aes256CbcEncryptHook"); Uint8Array keyBuffer = BufferFromBinary(env, key); Uint8Array ivBuffer = BufferFromBinary(env, iv); Uint8Array inBuffer = BufferFromBinary(env, in); Uint8Array outBuffer = BufferWithLengthOf(env, out); Napi::Value result; try { result = hook.Call(std::initializer_list { keyBuffer, ivBuffer, inBuffer, outBuffer }); } catch (...) { return false; } if (!result.IsNumber()) { MaybeSetCryptoHookErrorStatus(result, status); return false; } *bytes_written = result.ToNumber().Uint32Value(); CopyBufferData(out, outBuffer, *bytes_written); return true; }; auto aes_256_cbc_decrypt = [](void *ctx, mongocrypt_binary_t *key, mongocrypt_binary_t *iv, mongocrypt_binary_t *in, mongocrypt_binary_t *out, uint32_t *bytes_written, mongocrypt_status_t *status) -> bool { MongoCrypt* mongoCrypt = static_cast(ctx); Napi::Env env = mongoCrypt->Env(); HandleScope scope(env); Function hook = mongoCrypt->GetCallback("aes256CbcDecryptHook"); Uint8Array keyBuffer = BufferFromBinary(env, key); Uint8Array ivBuffer = BufferFromBinary(env, iv); Uint8Array inBuffer = BufferFromBinary(env, in); Uint8Array outBuffer = BufferWithLengthOf(env, out); Napi::Value result; try { result = hook.Call(std::initializer_list { keyBuffer, ivBuffer, inBuffer, outBuffer }); } catch (...) { return false; } if (!result.IsNumber()) { MaybeSetCryptoHookErrorStatus(result, status); return false; } *bytes_written = result.ToNumber().Uint32Value(); CopyBufferData(out, outBuffer, *bytes_written); return true; }; auto random = [](void *ctx, mongocrypt_binary_t *out, uint32_t count, mongocrypt_status_t *status) -> bool { MongoCrypt* mongoCrypt = static_cast(ctx); Napi::Env env = mongoCrypt->Env(); HandleScope scope(env); Function hook = mongoCrypt->GetCallback("randomHook"); Uint8Array outBuffer = BufferWithLengthOf(env, out); Napi::Value result; try { result = hook.Call(std::initializer_list { outBuffer, Number::New(env, count) }); } catch (...) { return false; } if (!result.IsNumber()) { MaybeSetCryptoHookErrorStatus(result, status); return false; } CopyBufferData(out, outBuffer); return true; }; auto hmac_sha_512 = [](void *ctx, mongocrypt_binary_t *key, mongocrypt_binary_t *in, mongocrypt_binary_t *out, mongocrypt_status_t *status) -> bool { MongoCrypt* mongoCrypt = static_cast(ctx); Napi::Env env = mongoCrypt->Env(); HandleScope scope(env); Function hook = mongoCrypt->GetCallback("hmacSha512Hook"); Uint8Array keyBuffer = BufferFromBinary(env, key); Uint8Array inputBuffer = BufferFromBinary(env, in); Uint8Array outputBuffer = BufferWithLengthOf(env, out); Napi::Value result; try { result = hook.Call(std::initializer_list { keyBuffer, inputBuffer, outputBuffer }); } catch (...) { return false; } if (!result.IsNumber()) { MaybeSetCryptoHookErrorStatus(result, status); return false; } CopyBufferData(out, outputBuffer); return true; }; auto hmac_sha_256 = [](void *ctx, mongocrypt_binary_t *key, mongocrypt_binary_t *in, mongocrypt_binary_t *out, mongocrypt_status_t *status) -> bool { MongoCrypt* mongoCrypt = static_cast(ctx); Napi::Env env = mongoCrypt->Env(); HandleScope scope(env); Function hook = mongoCrypt->GetCallback("hmacSha256Hook"); Uint8Array keyBuffer = BufferFromBinary(env, key); Uint8Array inputBuffer = BufferFromBinary(env, in); Uint8Array outputBuffer = BufferWithLengthOf(env, out); Napi::Value result; try { result = hook.Call(std::initializer_list { keyBuffer, inputBuffer, outputBuffer }); } catch (...) { return false; } if (!result.IsNumber()) { MaybeSetCryptoHookErrorStatus(result, status); return false; } CopyBufferData(out, outputBuffer); return true; }; auto sha_256 = [](void *ctx, mongocrypt_binary_t *in, mongocrypt_binary_t *out, mongocrypt_status_t *status) -> bool { MongoCrypt* mongoCrypt = static_cast(ctx); Napi::Env env = mongoCrypt->Env(); HandleScope scope(env); Function hook = mongoCrypt->GetCallback("sha256Hook"); Uint8Array inputBuffer = BufferFromBinary(env, in); Uint8Array outputBuffer = BufferWithLengthOf(env, out); Napi::Value result; try { result = hook.Call(std::initializer_list { inputBuffer, outputBuffer }); } catch (...) { return false; } if (!result.IsNumber()) { MaybeSetCryptoHookErrorStatus(result, status); return false; } CopyBufferData(out, outputBuffer); return true; }; auto sign_rsa_sha256 = [](void *ctx, mongocrypt_binary_t *key, mongocrypt_binary_t *in, mongocrypt_binary_t *out, mongocrypt_status_t *status) -> bool { MongoCrypt* mongoCrypt = static_cast(ctx); Napi::Env env = mongoCrypt->Env(); HandleScope scope(env); Function hook = mongoCrypt->GetCallback("signRsaSha256Hook"); Uint8Array keyBuffer = BufferFromBinary(env, key); Uint8Array inputBuffer = BufferFromBinary(env, in); Uint8Array outputBuffer = BufferWithLengthOf(env, out); Napi::Value result; try { result = hook.Call(std::initializer_list { keyBuffer, inputBuffer, outputBuffer }); } catch (...) { return false; } if (!result.IsNumber()) { MaybeSetCryptoHookErrorStatus(result, status); return false; } CopyBufferData(out, outputBuffer); return true; }; // Added after `mongocrypt_setopt_crypto_hooks`, they should be treated as the same during configuration if (!mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5(_mongo_crypt.get(), sign_rsa_sha256, this)) { return false; } return mongocrypt_setopt_crypto_hooks(_mongo_crypt.get(), aes_256_cbc_encrypt, aes_256_cbc_decrypt, random, hmac_sha_512, hmac_sha_256, sha_256, this ); } MongoCrypt::MongoCrypt(const CallbackInfo& info) : ObjectWrap(info), _mongo_crypt(mongocrypt_new()) { if (info.Length() < 1 || !info[0].IsObject()) { throw TypeError::New(Env(), "First parameter must be an object"); } Object options = info[0].ToObject(); if (options.Has("kmsProviders")) { Napi::Value kmsProvidersOptions = options["kmsProviders"]; if (!kmsProvidersOptions.IsBuffer()) { throw TypeError::New(Env(), "Option `kmsProviders` must be a Buffer"); } std::unique_ptr kmsProvidersBinary( BufferToBinary(kmsProvidersOptions.As())); if (!mongocrypt_setopt_kms_providers(_mongo_crypt.get(), kmsProvidersBinary.get())) { throw TypeError::New(Env(), errorStringFromStatus(_mongo_crypt.get())); } } if (options.Has("schemaMap")) { Napi::Value schemaMapBuffer = options["schemaMap"]; if (!schemaMapBuffer.IsBuffer()) { throw TypeError::New(Env(), "Option `schemaMap` must be a Buffer"); } std::unique_ptr schemaMapBinary( BufferToBinary(schemaMapBuffer.As())); if (!mongocrypt_setopt_schema_map(_mongo_crypt.get(), schemaMapBinary.get())) { throw TypeError::New(Env(), errorStringFromStatus(_mongo_crypt.get())); } } if (options.Has("logger")) { SetCallback("logger", options["logger"]); if (!mongocrypt_setopt_log_handler( _mongo_crypt.get(), MongoCrypt::logHandler, this)) { throw TypeError::New(Env(), errorStringFromStatus(_mongo_crypt.get())); } } if (options.Has("cryptoCallbacks")) { Object cryptoCallbacks = options.Get("cryptoCallbacks").ToObject(); SetCallback("aes256CbcEncryptHook", cryptoCallbacks["aes256CbcEncryptHook"]); SetCallback("aes256CbcDecryptHook", cryptoCallbacks["aes256CbcDecryptHook"]); SetCallback("randomHook", cryptoCallbacks["randomHook"]); SetCallback("hmacSha512Hook", cryptoCallbacks["hmacSha512Hook"]); SetCallback("hmacSha256Hook", cryptoCallbacks["hmacSha256Hook"]); SetCallback("sha256Hook", cryptoCallbacks["sha256Hook"]); SetCallback("signRsaSha256Hook", cryptoCallbacks["signRsaSha256Hook"]); if (!setupCryptoHooks()) { throw Error::New(Env(), "unable to configure crypto hooks"); } } // initialize afer all options are set, but after `MongoCrypt` instance is created so we can // optionally pass the instance to the logging function. if (!mongocrypt_init(_mongo_crypt.get())) { throw TypeError::New(Env(), errorStringFromStatus(_mongo_crypt.get())); } } Value MongoCrypt::Status(const CallbackInfo& info) { std::unique_ptr status(mongocrypt_status_new()); mongocrypt_status(_mongo_crypt.get(), status.get()); return ExtractStatus(Env(), status.get()); } Value MongoCrypt::MakeEncryptionContext(const CallbackInfo& info) { std::string ns = info[0].ToString(); std::unique_ptr context( mongocrypt_ctx_new(_mongo_crypt.get())); Napi::Value commandBuffer = info[1]; if (!commandBuffer.IsBuffer()) { throw TypeError::New(Env(), "Parameter `command` must be a Buffer"); } std::unique_ptr binaryCommand(BufferToBinary(commandBuffer.As())); if (!mongocrypt_ctx_encrypt_init( context.get(), ns.c_str(), ns.size(), binaryCommand.get())) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); } return MongoCryptContext::NewInstance(Env(), std::move(context)); } Value MongoCrypt::MakeExplicitEncryptionContext(const CallbackInfo& info) { std::unique_ptr context( mongocrypt_ctx_new(_mongo_crypt.get())); Napi::Value valueBuffer = info[0]; if (!valueBuffer.IsBuffer()) { throw TypeError::New(Env(), "Parameter `value` must be a Buffer"); } if (info.Length() > 1) { Object options = info[1].ToObject(); if (options.Has("keyId")) { Napi::Value keyId = options["keyId"]; if (!keyId.IsBuffer()) { throw TypeError::New(Env(), "`keyId` must be a Buffer"); } std::unique_ptr binary(BufferToBinary(keyId.As())); if (!mongocrypt_ctx_setopt_key_id(context.get(), binary.get())) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); } } if (options.Has("keyAltName")) { Napi::Value keyAltName = options["keyAltName"]; if (!keyAltName.IsBuffer()) { throw TypeError::New(Env(), "`keyAltName` must be a Buffer"); } std::unique_ptr binary( BufferToBinary(keyAltName.As())); if (!mongocrypt_ctx_setopt_key_alt_name(context.get(), binary.get())) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); } } if (options.Has("algorithm")) { std::string algorithm = options.Get("algorithm").ToString(); if (!mongocrypt_ctx_setopt_algorithm( context.get(), const_cast(algorithm.c_str()), algorithm.size())) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); } } } std::unique_ptr binaryValue(BufferToBinary(valueBuffer.As())); if (!mongocrypt_ctx_explicit_encrypt_init(context.get(), binaryValue.get())) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); } return MongoCryptContext::NewInstance(Env(), std::move(context)); } Value MongoCrypt::MakeDecryptionContext(const CallbackInfo& info) { if (!info[0].IsBuffer()) { throw TypeError::New(Env(), "First parameter must be a Buffer"); } std::unique_ptr binary( BufferToBinary(info[0].As())); std::unique_ptr context( mongocrypt_ctx_new(_mongo_crypt.get())); if (!mongocrypt_ctx_decrypt_init(context.get(), binary.get())) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); } return MongoCryptContext::NewInstance(Env(), std::move(context)); } Value MongoCrypt::MakeExplicitDecryptionContext(const CallbackInfo& info) { if (!info[0].IsBuffer()) { throw TypeError::New(Env(), "First parameter must be a Buffer"); } std::unique_ptr binary( BufferToBinary(info[0].As())); std::unique_ptr context( mongocrypt_ctx_new(_mongo_crypt.get())); if (!mongocrypt_ctx_explicit_decrypt_init(context.get(), binary.get())) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); } return MongoCryptContext::NewInstance(Env(), std::move(context)); } Value MongoCrypt::MakeDataKeyContext(const CallbackInfo& info) { Napi::Value optionsBuffer = info[0]; if (!optionsBuffer.IsBuffer()) { throw TypeError::New(Env(), "Parameter `options` must be a Buffer"); } std::unique_ptr context( mongocrypt_ctx_new(_mongo_crypt.get())); std::unique_ptr binary( BufferToBinary(optionsBuffer.As())); if (!mongocrypt_ctx_setopt_key_encryption_key(context.get(), binary.get())) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); } Object options = info[1].ToObject(); if (options.Has("keyAltNames")) { Napi::Value keyAltNames = options["keyAltNames"]; if (keyAltNames.IsArray()) { Array keyAltNamesArray = keyAltNames.As(); uint32_t keyAltNamesLength = keyAltNamesArray.Length(); for (uint32_t i = 0; i < keyAltNamesLength; i += 1) { if (keyAltNamesArray.Has(i)) { Napi::Value keyAltName = keyAltNamesArray[i]; if (!keyAltName.IsBuffer()) { // We should never get here throw TypeError::New(Env(), "Serialized keyAltName must be a Buffer"); } std::unique_ptr binary( BufferToBinary(keyAltName.As())); if (!mongocrypt_ctx_setopt_key_alt_name(context.get(), binary.get())) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); } } } } } if (!mongocrypt_ctx_datakey_init(context.get())) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); } return MongoCryptContext::NewInstance(Env(), std::move(context)); } // Store callbacks as nested properties on the MongoCrypt binding object // itself, and use these helpers to do so. Storing them as JS engine // References is a big memory leak footgun. Function MongoCrypt::GetCallback(const char* name) { Napi::Value storage = Value().Get("__callbackStorage"); if (!storage.IsObject()) { throw Error::New(Env(), "Cannot get callbacks becauses none were registered"); } Napi::Value entry = storage.As().Get(name); if (!entry.IsFunction()) { throw Error::New(Env(), std::string("Trying to look up unknown callback ") + name); } return entry.As(); } void MongoCrypt::SetCallback(const char* name, Napi::Value fn) { if (!fn.IsFunction()) { throw Error::New(Env(), std::string("Storing non-function as callback ") + name); } Napi::Value storage = Value().Get("__callbackStorage"); if (!storage.IsObject()) { storage = Object::New(Env()); Value().Set("__callbackStorage", storage); } storage.As().Set(name, fn); } Function MongoCryptContext::Init(Napi::Env env) { return DefineClass(env, "MongoCryptContext", { InstanceMethod("nextMongoOperation", &MongoCryptContext::NextMongoOperation), InstanceMethod("addMongoOperationResponse", &MongoCryptContext::AddMongoOperationResponse), InstanceMethod("finishMongoOperation", &MongoCryptContext::FinishMongoOperation), InstanceMethod("nextKMSRequest", &MongoCryptContext::NextKMSRequest), InstanceMethod("finishKMSRequests", &MongoCryptContext::FinishKMSRequests), InstanceMethod("finalize", &MongoCryptContext::FinalizeContext), InstanceAccessor("status", &MongoCryptContext::Status, nullptr), InstanceAccessor("state", &MongoCryptContext::State, nullptr) }); } Object MongoCryptContext::NewInstance(Napi::Env env, std::unique_ptr context) { InstanceData* instance_data = env.GetInstanceData(); Object obj = instance_data->MongoCryptContextCtor.Value().New({}); MongoCryptContext* instance = MongoCryptContext::Unwrap(obj); instance->_context = std::move(context); return obj; } MongoCryptContext::MongoCryptContext(const CallbackInfo& info) : ObjectWrap(info) {} Value MongoCryptContext::Status(const CallbackInfo& info) { std::unique_ptr status(mongocrypt_status_new()); mongocrypt_ctx_status(_context.get(), status.get()); return ExtractStatus(Env(), status.get()); } Value MongoCryptContext::State(const CallbackInfo& info) { return Number::New(Env(), mongocrypt_ctx_state(_context.get())); } Value MongoCryptContext::NextMongoOperation(const CallbackInfo& info) { std::unique_ptr op_bson(mongocrypt_binary_new()); mongocrypt_ctx_mongo_op(_context.get(), op_bson.get()); return BufferFromBinary(Env(), op_bson.get()); } void MongoCryptContext::AddMongoOperationResponse(const CallbackInfo& info) { if (info.Length() != 1 || !info[0].IsObject()) { throw TypeError::New(Env(), "Missing required parameter `buffer`"); } if (!info[0].IsBuffer()) { throw TypeError::New(Env(), "First parameter must be a Buffer"); } std::unique_ptr reply_bson( BufferToBinary(info[0].As())); mongocrypt_ctx_mongo_feed(_context.get(), reply_bson.get()); // return value } void MongoCryptContext::FinishMongoOperation(const CallbackInfo& info) { mongocrypt_ctx_mongo_done(_context.get()); } Value MongoCryptContext::NextKMSRequest(const CallbackInfo& info) { mongocrypt_kms_ctx_t* kms_context = mongocrypt_ctx_next_kms_ctx(_context.get()); if (kms_context == nullptr) { return Env().Null(); } else { Object result = MongoCryptKMSRequest::NewInstance(Env(), kms_context); // The lifetime of the `kms_context` pointer is not specified // anywhere, so it seems reasonable to assume that it is at // least the lifetime of this context object. // Use a symbol to enforce that lifetime dependency. result.Set("__kmsRequestContext", Value()); return result; } } void MongoCryptContext::FinishKMSRequests(const CallbackInfo& info) { mongocrypt_ctx_kms_done(_context.get()); } Value MongoCryptContext::FinalizeContext(const CallbackInfo& info) { std::unique_ptr output(mongocrypt_binary_new()); mongocrypt_ctx_finalize(_context.get(), output.get()); return BufferFromBinary(Env(), output.get()); } Function MongoCryptKMSRequest::Init(Napi::Env env) { return DefineClass(env, "MongoCryptKMSRequest", { InstanceMethod("addResponse", &MongoCryptKMSRequest::AddResponse), InstanceAccessor("status", &MongoCryptKMSRequest::Status, nullptr), InstanceAccessor("bytesNeeded", &MongoCryptKMSRequest::BytesNeeded, nullptr), InstanceAccessor("endpoint", &MongoCryptKMSRequest::Endpoint, nullptr), InstanceAccessor("message", &MongoCryptKMSRequest::Message, nullptr) }); } Object MongoCryptKMSRequest::NewInstance(Napi::Env env, mongocrypt_kms_ctx_t* kms_context) { InstanceData* instance_data = env.GetInstanceData(); Object obj = instance_data->MongoCryptKMSRequestCtor.Value().New({}); MongoCryptKMSRequest* instance = MongoCryptKMSRequest::Unwrap(obj); instance->_kms_context = kms_context; return obj; } MongoCryptKMSRequest::MongoCryptKMSRequest(const CallbackInfo& info) : ObjectWrap(info), _kms_context(nullptr) {} Value MongoCryptKMSRequest::Status(const CallbackInfo& info) { std::unique_ptr status(mongocrypt_status_new()); mongocrypt_kms_ctx_status(_kms_context, status.get()); return ExtractStatus(Env(), status.get()); } Value MongoCryptKMSRequest::BytesNeeded(const CallbackInfo& info) { return Number::New(Env(), mongocrypt_kms_ctx_bytes_needed(_kms_context)); } Value MongoCryptKMSRequest::Message(const CallbackInfo& info) { std::unique_ptr message(mongocrypt_binary_new()); mongocrypt_kms_ctx_message(_kms_context, message.get()); return BufferFromBinary(Env(), message.get()); } Value MongoCryptKMSRequest::Endpoint(const CallbackInfo& info) { std::unique_ptr message(mongocrypt_binary_new()); const char* endpoint; mongocrypt_kms_ctx_endpoint(_kms_context, &endpoint); return String::New(Env(), endpoint); } void MongoCryptKMSRequest::AddResponse(const CallbackInfo& info) { if (!info[0].IsBuffer()) { throw TypeError::New(Env(), "First parameter must be of type Buffer"); } std::unique_ptr reply_bytes( BufferToBinary(info[0].As())); mongocrypt_kms_ctx_feed(_kms_context, reply_bytes.get()); } static Object Init(Env env, Object exports) { Function MongoCryptCtor = MongoCrypt::Init(env); Function MongoCryptContextCtor = MongoCryptContext::Init(env); Function MongoCryptKMSRequestCtor = MongoCryptKMSRequest::Init(env); exports["MongoCrypt"] = MongoCryptCtor; exports["MongoCryptContextCtor"] = MongoCryptContextCtor; exports["MongoCryptKMSRequestCtor"] = MongoCryptKMSRequestCtor; env.SetInstanceData(new InstanceData { Reference::New(MongoCryptContextCtor, 1), Reference::New(MongoCryptKMSRequestCtor, 1) }); return exports; } NODE_API_MODULE(mongocrypt, Init) } // namespace node_mongocrypt libmongocrypt-1.3.0/bindings/node/src/mongocrypt.h000066400000000000000000000071501414105245100222660ustar00rootroot00000000000000#ifndef NODE_MONGOCRYPT_H #define NODE_MONGOCRYPT_H // We generally only target N-API version 4, but the instance data // feature is only available in N-API version 6. However, it is // available in all Node.js versions that have N-API version 4 // as an experimental feature (that has not been changed since then). #define NAPI_VERSION 6 #define NAPI_EXPERIMENTAL #include #include extern "C" { #include } namespace node_mongocrypt { struct MongoCryptBinaryDeleter { void operator()(mongocrypt_binary_t* binary) { mongocrypt_binary_destroy(binary); } }; struct MongoCryptDeleter { void operator()(mongocrypt_t* mongo_crypt) { mongocrypt_destroy(mongo_crypt); } }; struct MongoCryptContextDeleter { void operator()(mongocrypt_ctx_t* context) { mongocrypt_ctx_destroy(context); } }; class MongoCrypt : public Napi::ObjectWrap { public: static Napi::Function Init(Napi::Env env); private: Napi::Value MakeEncryptionContext(const Napi::CallbackInfo& info); Napi::Value MakeExplicitEncryptionContext(const Napi::CallbackInfo& info); Napi::Value MakeDecryptionContext(const Napi::CallbackInfo& info); Napi::Value MakeExplicitDecryptionContext(const Napi::CallbackInfo& info); Napi::Value MakeDataKeyContext(const Napi::CallbackInfo& info); Napi::Value Status(const Napi::CallbackInfo& info); private: friend class Napi::ObjectWrap; Napi::Function GetCallback(const char* name); void SetCallback(const char* name, Napi::Value fn); explicit MongoCrypt(const Napi::CallbackInfo& info); bool setupCryptoHooks(); static void logHandler(mongocrypt_log_level_t level, const char* message, uint32_t message_len, void* ctx); std::unique_ptr _mongo_crypt; }; class MongoCryptContext : public Napi::ObjectWrap { public: static Napi::Function Init(Napi::Env env); static Napi::Object NewInstance(Napi::Env env, std::unique_ptr context); private: Napi::Value NextMongoOperation(const Napi::CallbackInfo& info); void AddMongoOperationResponse(const Napi::CallbackInfo& info); void FinishMongoOperation(const Napi::CallbackInfo& info); Napi::Value NextKMSRequest(const Napi::CallbackInfo& info); void FinishKMSRequests(const Napi::CallbackInfo& info); Napi::Value FinalizeContext(const Napi::CallbackInfo& info); Napi::Value Status(const Napi::CallbackInfo& info); Napi::Value State(const Napi::CallbackInfo& info); private: friend class Napi::ObjectWrap; explicit MongoCryptContext(const Napi::CallbackInfo& info); std::unique_ptr _context; }; class MongoCryptKMSRequest : public Napi::ObjectWrap { public: static Napi::Function Init(Napi::Env env); static Napi::Object NewInstance(Napi::Env env, mongocrypt_kms_ctx_t* kms_context); private: void AddResponse(const Napi::CallbackInfo& info); Napi::Value Status(const Napi::CallbackInfo& info); Napi::Value Message(const Napi::CallbackInfo& info); Napi::Value BytesNeeded(const Napi::CallbackInfo& info); Napi::Value Endpoint(const Napi::CallbackInfo& info); private: friend class Napi::ObjectWrap; explicit MongoCryptKMSRequest(const Napi::CallbackInfo& info); mongocrypt_kms_ctx_t* _kms_context; }; } // namespace node_mongocrypt #endif // NODE_MONGOCRYPT_H libmongocrypt-1.3.0/bindings/node/test/000077500000000000000000000000001414105245100201015ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/node/test/autoEncrypter.test.js000066400000000000000000000337421414105245100242720ustar00rootroot00000000000000'use strict'; const fs = require('fs'); const BSON = require('bson'); const EJSON = require('bson').EJSON; const sinon = require('sinon'); const mongodb = require('mongodb'); const MongoNetworkTimeoutError = mongodb.MongoNetworkTimeoutError || mongodb.MongoTimeoutError; const stateMachine = require('../lib/stateMachine')({ mongodb }); const StateMachine = stateMachine.StateMachine; const MongocryptdManager = require('../lib/mongocryptdManager').MongocryptdManager; const chai = require('chai'); const expect = chai.expect; chai.use(require('chai-subset')); chai.use(require('sinon-chai')); const SegfaultHandler = require('segfault-handler'); SegfaultHandler.registerHandler(); function readExtendedJsonToBuffer(path) { const ejson = EJSON.parse(fs.readFileSync(path, 'utf8')); return BSON.serialize(ejson); } function readHttpResponse(path) { let data = fs.readFileSync(path, 'utf8').toString(); data = data.split('\n').join('\r\n'); return Buffer.from(data, 'utf8'); } const TEST_COMMAND = JSON.parse(fs.readFileSync(`${__dirname}/data/cmd.json`)); const MOCK_COLLINFO_RESPONSE = readExtendedJsonToBuffer(`${__dirname}/data/collection-info.json`); const MOCK_MONGOCRYPTD_RESPONSE = readExtendedJsonToBuffer( `${__dirname}/data/mongocryptd-reply.json` ); const MOCK_KEYDOCUMENT_RESPONSE = readExtendedJsonToBuffer(`${__dirname}/data/key-document.json`); const MOCK_KMS_DECRYPT_REPLY = readHttpResponse(`${__dirname}/data/kms-decrypt-reply.txt`); class MockClient { constructor() { this.topology = { bson: BSON }; } } const AutoEncrypter = require('../lib/autoEncrypter')({ mongodb, stateMachine }).AutoEncrypter; describe('AutoEncrypter', function() { let ENABLE_LOG_TEST = false; let sandbox = sinon.createSandbox(); beforeEach(() => { sandbox.restore(); sandbox.stub(StateMachine.prototype, 'kmsRequest').callsFake(request => { request.addResponse(MOCK_KMS_DECRYPT_REPLY); return Promise.resolve(); }); sandbox .stub(StateMachine.prototype, 'fetchCollectionInfo') .callsFake((client, ns, filter, callback) => { callback(null, MOCK_COLLINFO_RESPONSE); }); sandbox .stub(StateMachine.prototype, 'markCommand') .callsFake((client, ns, command, callback) => { if (ENABLE_LOG_TEST) { const response = BSON.deserialize(MOCK_MONGOCRYPTD_RESPONSE); response.schemaRequiresEncryption = false; ENABLE_LOG_TEST = false; // disable test after run callback(null, BSON.serialize(response)); return; } callback(null, MOCK_MONGOCRYPTD_RESPONSE); }); sandbox.stub(StateMachine.prototype, 'fetchKeys').callsFake((client, ns, filter, callback) => { // mock data is already seriaized, our action deals with the result of a cursor const deserializedKey = BSON.deserialize(MOCK_KEYDOCUMENT_RESPONSE); callback(null, [deserializedKey]); }); }); afterEach(() => { sandbox.restore(); }); it('should support `bypassAutoEncryption`', function(done) { const client = new MockClient(); const autoEncrypter = new AutoEncrypter(client, { bypassAutoEncryption: true, mongocryptdBypassSpawn: true, keyVaultNamespace: 'admin.datakeys', logger: () => {}, kmsProviders: { aws: { accessKeyId: 'example', secretAccessKey: 'example' }, local: { key: Buffer.alloc(96) } } }); autoEncrypter.encrypt('test.test', { test: 'command' }, (err, encrypted) => { expect(err).to.not.exist; expect(encrypted).to.eql({ test: 'command' }); done(); }); }); describe('state machine', function() { it('should decrypt mock data', function(done) { const input = readExtendedJsonToBuffer(`${__dirname}/data/encrypted-document.json`); const client = new MockClient(); const mc = new AutoEncrypter(client, { keyVaultNamespace: 'admin.datakeys', logger: () => {}, kmsProviders: { aws: { accessKeyId: 'example', secretAccessKey: 'example' }, local: { key: Buffer.alloc(96) } } }); mc.decrypt(input, (err, decrypted) => { if (err) return done(err); expect(decrypted).to.eql({ filter: { find: 'test', ssn: '457-55-5462' } }); done(); }); }); it('should encrypt mock data', function(done) { const client = new MockClient(); const mc = new AutoEncrypter(client, { keyVaultNamespace: 'admin.datakeys', logger: () => {}, kmsProviders: { aws: { accessKeyId: 'example', secretAccessKey: 'example' }, local: { key: Buffer.alloc(96) } } }); mc.encrypt('test.test', TEST_COMMAND, (err, encrypted) => { if (err) return done(err); const expected = EJSON.parse( JSON.stringify({ find: 'test', filter: { ssn: { $binary: { base64: 'AWFhYWFhYWFhYWFhYWFhYWECRTOW9yZzNDn5dGwuqsrJQNLtgMEKaujhs9aRWRp+7Yo3JK8N8jC8P0Xjll6C1CwLsE/iP5wjOMhVv1KMMyOCSCrHorXRsb2IKPtzl2lKTqQ=', subType: '6' } } } }) ); expect(encrypted).to.containSubset(expected); done(); }); }); }); describe('logging', function() { it('should allow registration of a log handler', function(done) { ENABLE_LOG_TEST = true; let loggerCalled = false; const logger = (level, message) => { if (loggerCalled) return; loggerCalled = true; expect(level).to.be.oneOf([2, 3]); expect(message).to.not.be.empty; }; const client = new MockClient(); const mc = new AutoEncrypter(client, { logger, kmsProviders: { aws: { accessKeyId: 'example', secretAccessKey: 'example' }, local: { key: Buffer.alloc(96) } } }); mc.encrypt('test.test', TEST_COMMAND, (err, encrypted) => { if (err) return done(err); const expected = EJSON.parse( JSON.stringify({ find: 'test', filter: { ssn: '457-55-5462' } }) ); expect(encrypted).to.containSubset(expected); done(); }); }); }); describe('autoSpawn', function() { beforeEach(function() { if (process.env.MONGODB_NODE_SKIP_LIVE_TESTS) { this.test.skip(); return; } }); afterEach(function(done) { if (this.mc) { this.mc.teardown(false, err => { this.mc = undefined; done(err); }); } else { done(); } }); it('should autoSpawn a mongocryptd on init by default', function(done) { const client = new MockClient(); this.mc = new AutoEncrypter(client, { keyVaultNamespace: 'admin.datakeys', logger: () => {}, kmsProviders: { aws: { accessKeyId: 'example', secretAccessKey: 'example' }, local: { key: Buffer.alloc(96) } } }); const localMcdm = this.mc._mongocryptdManager; sandbox.spy(localMcdm, 'spawn'); this.mc.init(err => { if (err) return done(err); expect(localMcdm.spawn).to.have.been.calledOnce; done(); }); }); it('should not attempt to kick off mongocryptd on a normal error', function(done) { let called = false; StateMachine.prototype.markCommand.callsFake((client, ns, filter, callback) => { if (!called) { called = true; callback(new Error('msg')); return; } callback(null, MOCK_MONGOCRYPTD_RESPONSE); }); const client = new MockClient(); this.mc = new AutoEncrypter(client, { keyVaultNamespace: 'admin.datakeys', logger: () => {}, kmsProviders: { aws: { accessKeyId: 'example', secretAccessKey: 'example' }, local: { key: Buffer.alloc(96) } } }); const localMcdm = this.mc._mongocryptdManager; this.mc.init(err => { if (err) return done(err); sandbox.spy(localMcdm, 'spawn'); this.mc.encrypt('test.test', TEST_COMMAND, err => { expect(localMcdm.spawn).to.not.have.been.called; expect(err).to.be.an.instanceOf(Error); done(); }); }); }); it('should restore the mongocryptd and retry once if a MongoNetworkTimeoutError is experienced', function(done) { let called = false; StateMachine.prototype.markCommand.callsFake((client, ns, filter, callback) => { if (!called) { called = true; callback(new MongoNetworkTimeoutError('msg')); return; } callback(null, MOCK_MONGOCRYPTD_RESPONSE); }); const client = new MockClient(); this.mc = new AutoEncrypter(client, { keyVaultNamespace: 'admin.datakeys', logger: () => {}, kmsProviders: { aws: { accessKeyId: 'example', secretAccessKey: 'example' }, local: { key: Buffer.alloc(96) } } }); const localMcdm = this.mc._mongocryptdManager; this.mc.init(err => { if (err) return done(err); sandbox.spy(localMcdm, 'spawn'); this.mc.encrypt('test.test', TEST_COMMAND, err => { expect(localMcdm.spawn).to.have.been.calledOnce; expect(err).to.not.exist; done(); }); }); }); it('should propagate error if MongoNetworkTimeoutError is experienced twice in a row', function(done) { let counter = 2; StateMachine.prototype.markCommand.callsFake((client, ns, filter, callback) => { if (counter) { counter -= 1; callback(new MongoNetworkTimeoutError('msg')); return; } callback(null, MOCK_MONGOCRYPTD_RESPONSE); }); const client = new MockClient(); this.mc = new AutoEncrypter(client, { keyVaultNamespace: 'admin.datakeys', logger: () => {}, kmsProviders: { aws: { accessKeyId: 'example', secretAccessKey: 'example' }, local: { key: Buffer.alloc(96) } } }); const localMcdm = this.mc._mongocryptdManager; this.mc.init(err => { if (err) return done(err); sandbox.spy(localMcdm, 'spawn'); this.mc.encrypt('test.test', TEST_COMMAND, err => { expect(localMcdm.spawn).to.have.been.calledOnce; expect(err).to.be.an.instanceof(MongoNetworkTimeoutError); done(); }); }); }); it('should return a useful message if mongocryptd fails to autospawn', function(done) { const client = new MockClient(); this.mc = new AutoEncrypter(client, { keyVaultNamespace: 'admin.datakeys', logger: () => {}, kmsProviders: { aws: { accessKeyId: 'example', secretAccessKey: 'example' }, local: { key: Buffer.alloc(96) } }, extraOptions: { mongocryptdURI: 'mongodb://something.invalid:27020/' } }); sandbox.stub(MongocryptdManager.prototype, 'spawn').callsFake(callback => { callback(); }); this.mc.init(err => { expect(err).to.exist; expect(err).to.match(/Unable to connect to `mongocryptd`/); done(); }); }); }); describe('noAutoSpawn', function() { beforeEach(function(done) { if (process.env.MONGODB_NODE_SKIP_LIVE_TESTS) { this.test.skip(); return; } this.mcdm = new MongocryptdManager({}); this.mcdm.spawn(done); }); afterEach(function(done) { if (this.mc) { this.mc.teardown(false, err => { this.mc = undefined; done(err); }); } else { done(); } }); ['mongocryptdBypassSpawn', 'bypassAutoEncryption'].forEach(opt => { const encryptionOptions = { keyVaultNamespace: 'admin.datakeys', logger: () => {}, kmsProviders: { aws: { accessKeyId: 'example', secretAccessKey: 'example' }, local: { key: Buffer.alloc(96) } }, extraOptions: { mongocryptdBypassSpawn: opt === 'mongocryptdBypassSpawn' }, bypassAutoEncryption: opt === 'bypassAutoEncryption' }; it(`should not spawn mongocryptd on startup if ${opt} is true`, function(done) { const client = new MockClient(); this.mc = new AutoEncrypter(client, encryptionOptions); const localMcdm = this.mc._mongocryptdManager; sandbox.spy(localMcdm, 'spawn'); this.mc.init(err => { expect(err).to.not.exist; expect(localMcdm.spawn).to.have.a.callCount(0); done(); }); }); it('should not spawn a mongocryptd or retry on a server selection error if mongocryptdBypassSpawn: true', function(done) { let called = false; const timeoutError = new MongoNetworkTimeoutError('msg'); StateMachine.prototype.markCommand.callsFake((client, ns, filter, callback) => { if (!called) { called = true; callback(timeoutError); return; } callback(null, MOCK_MONGOCRYPTD_RESPONSE); }); const client = new MockClient(); this.mc = new AutoEncrypter(client, { keyVaultNamespace: 'admin.datakeys', logger: () => {}, kmsProviders: { aws: { accessKeyId: 'example', secretAccessKey: 'example' }, local: { key: Buffer.alloc(96) } }, extraOptions: { mongocryptdBypassSpawn: true } }); const localMcdm = this.mc._mongocryptdManager; sandbox.spy(localMcdm, 'spawn'); this.mc.init(err => { expect(err).to.not.exist; expect(localMcdm.spawn).to.not.have.been.called; this.mc.encrypt('test.test', TEST_COMMAND, (err, response) => { expect(localMcdm.spawn).to.not.have.been.called; expect(response).to.not.exist; expect(err).to.equal(timeoutError); done(); }); }); }); }); }); }); libmongocrypt-1.3.0/bindings/node/test/clientEncryption.test.js000066400000000000000000000252411414105245100247520ustar00rootroot00000000000000'use strict'; const fs = require('fs'); const expect = require('chai').expect; const sinon = require('sinon'); const mongodb = require('mongodb'); const MongoClient = mongodb.MongoClient; const stateMachine = require('../lib/stateMachine')({ mongodb }); const StateMachine = stateMachine.StateMachine; const SegfaultHandler = require('segfault-handler'); SegfaultHandler.registerHandler(); function readHttpResponse(path) { let data = fs.readFileSync(path, 'utf8').toString(); data = data.split('\n').join('\r\n'); return Buffer.from(data, 'utf8'); } const ClientEncryption = require('../lib/clientEncryption')({ mongodb, stateMachine }) .ClientEncryption; const requirements = require('./requirements.helper'); describe('ClientEncryption', function() { let client; function setup() { client = new MongoClient('mongodb://localhost:27017/test', { useNewUrlParser: true, useUnifiedTopology: true }); return client.connect().then(() => client .db('client') .collection('encryption') .drop() .catch(err => { if (err.message.match(/ns not found/)) { return; } throw err; }) ); } function teardown() { if (requirements.SKIP_LIVE_TESTS) { return; } return client.close(); } describe('stubbed stateMachine', function() { let sandbox = sinon.createSandbox(); after(() => sandbox.restore()); before(() => { // stubbed out for AWS unit testing below const MOCK_KMS_ENCRYPT_REPLY = readHttpResponse(`${__dirname}/data/kms-encrypt-reply.txt`); sandbox.stub(StateMachine.prototype, 'kmsRequest').callsFake(request => { request.addResponse(MOCK_KMS_ENCRYPT_REPLY); return Promise.resolve(); }); }); beforeEach(function() { if (requirements.SKIP_LIVE_TESTS) { this.test.skip(); return; } return setup(); }); afterEach(function() { return teardown(); }); [ { name: 'local', kmsProviders: { local: { key: Buffer.alloc(96) } } }, { name: 'aws', kmsProviders: { aws: { accessKeyId: 'example', secretAccessKey: 'example' } }, options: { masterKey: { region: 'region', key: 'cmk' } } } ].forEach(providerTest => { it(`should create a data key with the "${providerTest.name}" KMS provider`, function(done) { const providerName = providerTest.name; const encryption = new ClientEncryption(client, { keyVaultNamespace: 'client.encryption', kmsProviders: providerTest.kmsProviders }); const dataKeyOptions = providerTest.options || {}; encryption.createDataKey(providerName, dataKeyOptions, (err, dataKey) => { expect(err).to.not.exist; expect(dataKey._bsontype).to.equal('Binary'); client .db('client') .collection('encryption') .findOne({ _id: dataKey }, (err, doc) => { expect(err).to.not.exist; expect(doc).to.have.property('masterKey'); expect(doc.masterKey).to.have.property('provider'); expect(doc.masterKey.provider).to.eql(providerName); done(); }); }); }); }); it('should explicitly encrypt and decrypt with the "local" KMS provider', function(done) { const encryption = new ClientEncryption(client, { keyVaultNamespace: 'client.encryption', kmsProviders: { local: { key: Buffer.alloc(96) } } }); encryption.createDataKey('local', (err, dataKey) => { expect(err).to.not.exist; const encryptOptions = { keyId: dataKey, algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' }; encryption.encrypt('hello', encryptOptions, (err, encrypted) => { expect(err).to.not.exist; expect(encrypted._bsontype).to.equal('Binary'); expect(encrypted.sub_type).to.equal(6); encryption.decrypt(encrypted, (err, decrypted) => { expect(err).to.not.exist; expect(decrypted).to.equal('hello'); done(); }); }); }); }); it('should explicitly encrypt and decrypt with the "local" KMS provider (promise)', function() { const encryption = new ClientEncryption(client, { keyVaultNamespace: 'client.encryption', kmsProviders: { local: { key: Buffer.alloc(96) } } }); return encryption .createDataKey('local') .then(dataKey => { const encryptOptions = { keyId: dataKey, algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' }; return encryption.encrypt('hello', encryptOptions); }) .then(encrypted => { expect(encrypted._bsontype).to.equal('Binary'); expect(encrypted.sub_type).to.equal(6); return encryption.decrypt(encrypted); }) .then(decrypted => { expect(decrypted).to.equal('hello'); }); }); // TODO(NODE-3371): resolve KMS JSON response does not include string 'Plaintext'. HTTP status=200 error it.skip('should explicitly encrypt and decrypt with the "aws" KMS provider', function(done) { const encryption = new ClientEncryption(client, { keyVaultNamespace: 'client.encryption', kmsProviders: { aws: { accessKeyId: 'example', secretAccessKey: 'example' } } }); const dataKeyOptions = { masterKey: { region: 'region', key: 'cmk' } }; encryption.createDataKey('aws', dataKeyOptions, (err, dataKey) => { expect(err).to.not.exist; const encryptOptions = { keyId: dataKey, algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' }; encryption.encrypt('hello', encryptOptions, (err, encrypted) => { expect(err).to.not.exist; expect(encrypted).to.have.property('v'); expect(encrypted.v._bsontype).to.equal('Binary'); expect(encrypted.v.sub_type).to.equal(6); encryption.decrypt(encrypted, (err, decrypted) => { expect(err).to.not.exist; expect(decrypted).to.equal('hello'); done(); }); }); }); }); it('should be able to auto decrypt explicit encryption'); }); describe('ClientEncryptionKeyAltNames', function() { const kmsProviders = requirements.awsKmsProviders; const dataKeyOptions = requirements.awsDataKeyOptions; beforeEach(function() { if (requirements.SKIP_AWS_TESTS) { this.skip(); return; } return setup().then(() => { this.client = client; this.collection = client.db('client').collection('encryption'); this.encryption = new ClientEncryption(this.client, { keyVaultNamespace: 'client.encryption', kmsProviders }); }); }); afterEach(function() { return teardown().then(() => { this.encryption = undefined; this.collection = undefined; this.client = undefined; }); }); function makeOptions(keyAltNames) { expect(dataKeyOptions.masterKey).to.be.an('object'); expect(dataKeyOptions.masterKey.key).to.be.a('string'); expect(dataKeyOptions.masterKey.region).to.be.a('string'); return { masterKey: { key: dataKeyOptions.masterKey.key, region: dataKeyOptions.masterKey.region }, keyAltNames }; } describe('errors', function() { [42, 'hello', { keyAltNames: 'foobar' }, /foobar/].forEach(val => { it(`should fail if typeof keyAltNames = ${typeof val}`, function() { const options = makeOptions(val); expect(() => this.encryption.createDataKey('aws', options, () => undefined)).to.throw( TypeError ); }); }); [undefined, null, 42, { keyAltNames: 'foobar' }, ['foobar'], /foobar/].forEach(val => { it(`should fail if typeof keyAltNames[x] = ${typeof val}`, function() { const options = makeOptions([val]); expect(() => this.encryption.createDataKey('aws', options, () => undefined)).to.throw( TypeError ); }); }); }); it('should create a key with keyAltNames', function() { let dataKey; const options = makeOptions(['foobar']); return this.encryption .createDataKey('aws', options) .then(_dataKey => (dataKey = _dataKey)) .then(() => this.collection.findOne({ keyAltNames: 'foobar' })) .then(document => { expect(document).to.be.an('object'); expect(document) .to.have.property('keyAltNames') .that.includes.members(['foobar']); expect(document) .to.have.property('_id') .that.deep.equals(dataKey); }); }); it('should create a key with multiple keyAltNames', function() { let dataKey; return this.encryption .createDataKey('aws', makeOptions(['foobar', 'fizzbuzz'])) .then(_dataKey => (dataKey = _dataKey)) .then(() => Promise.all([ this.collection.findOne({ keyAltNames: 'foobar' }), this.collection.findOne({ keyAltNames: 'fizzbuzz' }) ]) ) .then(docs => { expect(docs).to.have.lengthOf(2); const doc1 = docs[0]; const doc2 = docs[1]; expect(doc1).to.be.an('object'); expect(doc2).to.be.an('object'); expect(doc1) .to.have.property('keyAltNames') .that.includes.members(['foobar', 'fizzbuzz']); expect(doc1) .to.have.property('_id') .that.deep.equals(dataKey); expect(doc2) .to.have.property('keyAltNames') .that.includes.members(['foobar', 'fizzbuzz']); expect(doc2) .to.have.property('_id') .that.deep.equals(dataKey); }); }); it('should be able to reference a key with `keyAltName` during encryption', function() { let keyId; const keyAltName = 'mySpecialKey'; const algorithm = 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'; const valueToEncrypt = 'foobar'; return this.encryption .createDataKey('aws', makeOptions([keyAltName])) .then(_dataKey => (keyId = _dataKey)) .then(() => this.encryption.encrypt(valueToEncrypt, { keyId, algorithm })) .then(encryptedValue => { return this.encryption .encrypt(valueToEncrypt, { keyAltName, algorithm }) .then(encryptedValue2 => { expect(encryptedValue).to.deep.equal(encryptedValue2); }); }); }); }); }); libmongocrypt-1.3.0/bindings/node/test/cryptoCallbacks.test.js000066400000000000000000000216041414105245100245400ustar00rootroot00000000000000'use strict'; const sinon = require('sinon'); const chai = require('chai'); const expect = chai.expect; chai.use(require('sinon-chai')); const mongodb = require('mongodb'); const MongoClient = mongodb.MongoClient; const stateMachine = require('../lib/stateMachine')({ mongodb }); const cryptoCallbacks = require('../lib/cryptoCallbacks'); const ClientEncryption = require('../lib/clientEncryption')({ mongodb, stateMachine }) .ClientEncryption; const SegfaultHandler = require('segfault-handler'); SegfaultHandler.registerHandler(); const requirements = require('./requirements.helper'); // Data Key Stuff const kmsProviders = Object.assign({}, requirements.awsKmsProviders); const dataKeyOptions = Object.assign({}, requirements.awsDataKeyOptions); describe('cryptoCallbacks', function() { before(function() { if (requirements.SKIP_AWS_TESTS) { console.log('Skipping crypto callback tests'); return; } this.sinon = sinon.createSandbox(); }); beforeEach(function() { if (requirements.SKIP_AWS_TESTS) { this.test.skip(); return; } this.sinon.restore(); this.client = new MongoClient('mongodb://localhost:27017/', { useUnifiedTopology: true, useNewUrlParser: true }); return this.client.connect(); }); afterEach(function() { if (requirements.SKIP_AWS_TESTS) { return; } this.sinon.restore(); let p = Promise.resolve(); if (this.client) { p = p.then(() => this.client.close()).then(() => (this.client = undefined)); } return p; }); after(function() { this.sinon = undefined; }); // TODO(NODE-3370): fix key formatting error "asn1_check_tlen:wrong tag" it.skip('should support support crypto callback for signing RSA-SHA256', function() { const input = Buffer.from('data to sign'); const pemFileData = '-----BEGIN PRIVATE KEY-----\n' + 'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC4JOyv5z05cL18ztpknRC7CFY2gYol4DAKerdVUoDJxCTmFMf39dVUEqD0WDiw/qcRtSO1/FRut08PlSPmvbyKetsLoxlpS8lukSzEFpFK7+L+R4miFOl6HvECyg7lbC1H/WGAhIz9yZRlXhRo9qmO/fB6PV9IeYtU+1xYuXicjCDPp36uuxBAnCz7JfvxJ3mdVc0vpSkbSb141nWuKNYR1mgyvvL6KzxO6mYsCo4hRAdhuizD9C4jDHk0V2gDCFBk0h8SLEdzStX8L0jG90/Og4y7J1b/cPo/kbYokkYisxe8cPlsvGBf+rZex7XPxc1yWaP080qeABJb+S88O//LAgMBAAECggEBAKVxP1m3FzHBUe2NZ3fYCc0Qa2zjK7xl1KPFp2u4CU+9sy0oZJUqQHUdm5CMprqWwIHPTftWboFenmCwrSXFOFzujljBO7Z3yc1WD3NJl1ZNepLcsRJ3WWFH5V+NLJ8Bdxlj1DMEZCwr7PC5+vpnCuYWzvT0qOPTl9RNVaW9VVjHouJ9Fg+s2DrShXDegFabl1iZEDdI4xScHoYBob06A5lw0WOCTayzw0Naf37lM8Y4psRAmI46XLiF/Vbuorna4hcChxDePlNLEfMipICcuxTcei1RBSlBa2t1tcnvoTy6cuYDqqImRYjp1KnMKlKQBnQ1NjS2TsRGm+F0FbreVCECgYEA4IDJlm8q/hVyNcPe4OzIcL1rsdYN3bNm2Y2O/YtRPIkQ446ItyxD06d9VuXsQpFp9jNACAPfCMSyHpPApqlxdc8z/xATlgHkcGezEOd1r4E7NdTpGg8y6Rj9b8kVlED6v4grbRhKcU6moyKUQT3+1B6ENZTOKyxuyDEgTwZHtFECgYEA0fqdv9h9s77d6eWmIioP7FSymq93pC4umxf6TVicpjpMErdD2ZfJGulN37dq8FOsOFnSmFYJdICj/PbJm6p1i8O21lsFCltEqVoVabJ7/0alPfdG2U76OeBqI8ZubL4BMnWXAB/VVEYbyWCNpQSDTjHQYs54qa2I0dJB7OgJt1sCgYEArctFQ02/7H5Rscl1yo3DBXO94SeiCFSPdC8f2Kt3MfOxvVdkAtkjkMACSbkoUsgbTVqTYSEOEc2jTgR3iQ13JgpHaFbbsq64V0QP3TAxbLIQUjYGVgQaF1UfLOBv8hrzgj45z/ST/G80lOl595+0nCUbmBcgG1AEWrmdF0/3RmECgYAKvIzKXXB3+19vcT2ga5Qq2l3TiPtOGsppRb2XrNs9qKdxIYvHmXo/9QP1V3SRW0XoD7ez8FpFabp42cmPOxUNk3FK3paQZABLxH5pzCWI9PzIAVfPDrm+sdnbgG7vAnwfL2IMMJSA3aDYGCbF9EgefG+STcpfqq7fQ6f5TBgLFwKBgCd7gn1xYL696SaKVSm7VngpXlczHVEpz3kStWR5gfzriPBxXgMVcWmcbajRser7ARpCEfbxM1UJyv6oAYZWVSNErNzNVb4POqLYcCNySuC6xKhs9FrEQnyKjyk8wI4VnrEMGrQ8e+qYSwYk9Gh6dKGoRMAPYVXQAO0fIsHF/T0a\n' + '-----END PRIVATE KEY-----'; const key = Buffer.from(pemFileData); const output = Buffer.alloc(256); const expectedOutput = Buffer.from( 'VocBRhpMmQ2XCzVehWSqheQLnU889gf3dhU4AnVnQTJjsKx/CM23qKDPkZDd2A/BnQsp99SN7ksIX5Raj0TPwyN5OCN/YrNFNGoOFlTsGhgP/hyE8X3Duiq6sNO0SMvRYNPFFGlJFsp1Fw3Z94eYMg4/Wpw5s4+Jo5Zm/qY7aTJIqDKDQ3CNHLeJgcMUOc9sz01/GzoUYKDVODHSxrYEk5ireFJFz9vP8P7Ha+VDUZuQIQdXer9NBbGFtYmWprY3nn4D3Dw93Sn0V0dIqYeIo91oKyslvMebmUM95S2PyIJdEpPb2DJDxjvX/0LLwSWlSXRWy9gapWoBkb4ynqZBsg==', 'base64' ); const { signRsaSha256Hook } = cryptoCallbacks; const err = signRsaSha256Hook(key, input, output); if (err instanceof Error) { expect(err).to.not.exist; } expect(output).to.deep.equal(expectedOutput); }); const hookNames = new Set([ 'aes256CbcEncryptHook', 'aes256CbcDecryptHook', 'randomHook', 'hmacSha512Hook', 'hmacSha256Hook', 'sha256Hook' ]); it('should invoke crypto callbacks when doing encryption', function(done) { for (const name of hookNames) { this.sinon.spy(cryptoCallbacks, name); } function assertCertainHooksCalled(expectedSet) { expectedSet = expectedSet || new Set([]); for (const name of hookNames) { const hook = cryptoCallbacks[name]; if (expectedSet.has(name)) { expect(hook).to.have.been.called; } else { expect(hook).to.not.have.been.called; } hook.resetHistory(); } } const encryption = new ClientEncryption(this.client, { keyVaultNamespace: 'test.encryption', kmsProviders }); try { assertCertainHooksCalled(); } catch (e) { return done(e); } encryption.createDataKey('aws', dataKeyOptions, (err, dataKey) => { try { expect(err).to.not.exist; assertCertainHooksCalled(new Set(['hmacSha256Hook', 'sha256Hook', 'randomHook'])); } catch (e) { return done(e); } const encryptOptions = { keyId: dataKey, algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' }; encryption.encrypt('hello', encryptOptions, (err, encryptedValue) => { try { expect(err).to.not.exist; assertCertainHooksCalled( new Set(['aes256CbcEncryptHook', 'hmacSha512Hook', 'hmacSha256Hook', 'sha256Hook']) ); } catch (e) { return done(e); } encryption.decrypt(encryptedValue, err => { try { expect(err).to.not.exist; assertCertainHooksCalled(new Set(['aes256CbcDecryptHook', 'hmacSha512Hook'])); } catch (e) { return done(e); } done(); }); }); }); }); describe('error testing', function() { ['aes256CbcEncryptHook', 'aes256CbcDecryptHook', 'hmacSha512Hook'].forEach(hookName => { it(`should properly propagate an error when ${hookName} fails`, function(done) { const error = new Error('some random error text'); this.sinon.stub(cryptoCallbacks, hookName).returns(error); const encryption = new ClientEncryption(this.client, { keyVaultNamespace: 'test.encryption', kmsProviders }); function finish(err) { try { expect(err, 'Expected an error to exist').to.exist; expect(err).to.have.property('message', error.message); done(); } catch (e) { done(e); } } try { encryption.createDataKey('aws', dataKeyOptions, (err, dataKey) => { if (err) return finish(err); const encryptOptions = { keyId: dataKey, algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' }; encryption.encrypt('hello', encryptOptions, (err, encryptedValue) => { if (err) return finish(err); encryption.decrypt(encryptedValue, err => finish(err)); }); }); } catch (e) { done(new Error('We should not be here')); } }); }); // These ones will fail with an error, but that error will get overridden // with "failed to create KMS message" in mongocrypt-kms-ctx.c ['hmacSha256Hook', 'sha256Hook'].forEach(hookName => { it(`should error with a specific kms error when ${hookName} fails`, function() { const error = new Error('some random error text'); this.sinon.stub(cryptoCallbacks, hookName).returns(error); const encryption = new ClientEncryption(this.client, { keyVaultNamespace: 'test.encryption', kmsProviders }); expect(() => encryption.createDataKey('aws', dataKeyOptions, () => undefined)).to.throw( 'failed to create KMS message' ); }); }); it('should error synchronously with error when randomHook fails', function(done) { const error = new Error('some random error text'); this.sinon.stub(cryptoCallbacks, 'randomHook').returns(error); const encryption = new ClientEncryption(this.client, { keyVaultNamespace: 'test.encryption', kmsProviders }); try { encryption.createDataKey('aws', dataKeyOptions, () => { done(new Error('We should not be here')); }); } catch (err) { try { expect(err).to.have.property('message', 'some random error text'); done(); } catch (e) { done(e); } } }); }); }); libmongocrypt-1.3.0/bindings/node/test/data/000077500000000000000000000000001414105245100210125ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/node/test/data/README.md000066400000000000000000000005401414105245100222700ustar00rootroot00000000000000# libmongocrypt example data # This directory contains a simple example of mocked responses to test libmongocrypt and driver wrappers. Data for other scenarios and edge cases is in the `data` directory. The HTTP reply file, kms-decrypt-reply.txt, has regular newline endings \n that MUST be replaced by \r\n endings when reading the file for testing.libmongocrypt-1.3.0/bindings/node/test/data/cmd.json000066400000000000000000000001131414105245100224430ustar00rootroot00000000000000{ "find": "test", "filter": { "ssn": "457-55-5462" } } libmongocrypt-1.3.0/bindings/node/test/data/collection-info.json000066400000000000000000000017321414105245100247740ustar00rootroot00000000000000{ "type": "collection", "name": "test", "idIndex": { "ns": "test.test", "name": "_id_", "key": { "_id": { "$numberInt": "1" } }, "v": { "$numberInt": "2" } }, "options": { "validator": { "$jsonSchema": { "properties": { "ssn": { "encrypt": { "keyId": { "$binary": { "base64": "YWFhYWFhYWFhYWFhYWFhYQ==", "subType": "04" } }, "type": "string", "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" } } }, "bsonType": "object" } } } } libmongocrypt-1.3.0/bindings/node/test/data/encrypted-document.json000066400000000000000000000004261414105245100255200ustar00rootroot00000000000000{ "filter": { "find": "test", "ssn": { "$binary": { "base64": "AWFhYWFhYWFhYWFhYWFhYWECRTOW9yZzNDn5dGwuqsrJQNLtgMEKaujhs9aRWRp+7Yo3JK8N8jC8P0Xjll6C1CwLsE/iP5wjOMhVv1KMMyOCSCrHorXRsb2IKPtzl2lKTqQ=", "subType": "06" } } } } libmongocrypt-1.3.0/bindings/node/test/data/key-document.json000066400000000000000000000017571414105245100243230ustar00rootroot00000000000000{ "status": { "$numberInt": "1" }, "_id": { "$binary": { "base64": "YWFhYWFhYWFhYWFhYWFhYQ==", "subType": "04" } }, "masterKey": { "region": "us-east-1", "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", "provider": "aws" }, "updateDate": { "$date": { "$numberLong": "1557827033449" } }, "keyMaterial": { "$binary": { "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", "subType": "00" } }, "creationDate": { "$date": { "$numberLong": "1557827033449" } } } libmongocrypt-1.3.0/bindings/node/test/data/kms-decrypt-reply.txt000066400000000000000000000005561414105245100251540ustar00rootroot00000000000000HTTP/1.1 200 OK x-amzn-RequestId: deeb35e5-4ecb-4bf1-9af5-84a54ff0af0e Content-Type: application/x-amz-json-1.1 Content-Length: 233 {"KeyId": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", "Plaintext": "TqhXy3tKckECjy4/ZNykMWG8amBF46isVPzeOgeusKrwheBmYaU8TMG5AHR/NeUDKukqo8hBGgogiQOVpLPkqBQHD8YkLsNbDmHoGOill5QAHnniF/Lz405bGucB5TfR"}libmongocrypt-1.3.0/bindings/node/test/data/kms-encrypt-reply.txt000066400000000000000000000011251414105245100251570ustar00rootroot00000000000000HTTP/1.1 200 OK x-amzn-RequestId: deeb35e5-4ecb-4bf1-9af5-84a54ff0af0e Content-Type: application/x-amz-json-1.1 Content-Length: 446 Connection: close {"KeyId": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", "CiphertextBlob": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gHCPOT4UQIpMTvAVABLqnXlAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDLxAm0nO3rccdoWA6AIBEIB7HUe6+aPvgNu/4sLEXBQVDIJVBueI3q7zdOMBSkRKkgZWqEuQgA6iDuEZbhHhOVCUXPBaLX6QWRwyMmjvIy/2Bg5q+TmwnfRo6QKdw2vee1W32/FdPWIoQy1yKOoIhNy6XMWldS3JuWK8ffQOYkssEqx0V4LW6PKuFv7D"}libmongocrypt-1.3.0/bindings/node/test/data/mongocryptd-reply.json000066400000000000000000000006551414105245100254110ustar00rootroot00000000000000{ "schemaRequiresEncryption": true, "ok": { "$numberInt": "1" }, "result": { "filter": { "ssn": { "$binary": { "base64": "ADgAAAAQYQABAAAABWtpABAAAAAEYWFhYWFhYWFhYWFhYWFhYQJ2AAwAAAA0NTctNTUtNTQ2MgAA", "subType": "06" } } }, "find": "test" }, "hasEncryptedPlaceholders": true } libmongocrypt-1.3.0/bindings/node/test/mongocryptdManager.test.js000066400000000000000000000033071414105245100252600ustar00rootroot00000000000000'use strict'; const MongocryptdManager = require('../lib/mongocryptdManager').MongocryptdManager; const expect = require('chai').expect; describe('MongocryptdManager', function() { it('should default to having spawnArgs of --idleShutdownTimeoutSecs=60', function() { const mcdm = new MongocryptdManager(); expect(mcdm.spawnArgs).to.deep.equal(['--idleShutdownTimeoutSecs', 60]); }); it('should concat --idleShutdownTimeoutSecs=60 to provided args', function() { const mcdm = new MongocryptdManager({ mongocryptdSpawnArgs: ['foo', 12] }); expect(mcdm.spawnArgs).to.deep.equal(['foo', 12, '--idleShutdownTimeoutSecs', 60]); }); it('should not override `idleShutdownTimeoutSecs` if the user sets it using `key value` form', function() { const mcdm = new MongocryptdManager({ mongocryptdSpawnArgs: ['--idleShutdownTimeoutSecs', 12] }); expect(mcdm.spawnArgs).to.deep.equal(['--idleShutdownTimeoutSecs', 12]); }); it('should not override `idleShutdownTimeoutSecs` if the user sets it using `key=value` form', function() { const mcdm = new MongocryptdManager({ mongocryptdSpawnArgs: ['--idleShutdownTimeoutSecs=12'] }); expect(mcdm.spawnArgs).to.deep.equal(['--idleShutdownTimeoutSecs=12']); }); it('should support construction with options', function() { const mcdm = new MongocryptdManager({ mongocryptdURI: 'some-uri', mongocryptdBypassSpawn: true, mongocryptdSpawnPath: 'some-spawn-path', mongocryptdSpawnArgs: ['--idleShutdownTimeoutSecs=12'] }); expect(mcdm).to.eql({ uri: 'some-uri', bypassSpawn: true, spawnPath: 'some-spawn-path', spawnArgs: ['--idleShutdownTimeoutSecs=12'] }); }); }); libmongocrypt-1.3.0/bindings/node/test/release.test.js000066400000000000000000000027571414105245100230500ustar00rootroot00000000000000'use strict'; const expect = require('chai').expect; const tar = require('tar'); const cp = require('child_process'); const fs = require('fs'); const pkg = require('../package.json'); const packFile = `mongodb-client-encryption-${pkg.version}.tgz`; const REQUIRED_FILES = [ 'package/binding.gyp', 'package/CHANGELOG.md', 'package/index.d.ts', 'package/index.js', 'package/lib/autoEncrypter.js', 'package/lib/clientEncryption.js', 'package/lib/common.js', 'package/lib/cryptoCallbacks.js', 'package/lib/mongocryptdManager.js', 'package/lib/stateMachine.js', 'package/LICENSE', 'package/package.json', 'package/README.md', 'package/src/mongocrypt.cc', 'package/src/mongocrypt.h' ]; describe(`Release ${packFile}`, () => { let tarFileList; before(() => { expect(fs.existsSync(packFile)).to.equal(false); cp.execSync('npm pack', { stdio: 'ignore' }); tarFileList = []; tar.list({ file: packFile, sync: true, onentry(entry) { tarFileList.push(entry.path); } }); }); after(() => { fs.unlinkSync(packFile); }); for (const requiredFile of REQUIRED_FILES) { it(`should contain ${requiredFile}`, () => { expect(tarFileList).to.includes(requiredFile); }); } it('should not have extraneous files', () => { const unexpectedFileList = tarFileList.filter(f => !REQUIRED_FILES.some(r => r === f)); expect(unexpectedFileList).to.have.lengthOf(0, `Extra files: ${unexpectedFileList.join(', ')}`); }); }); libmongocrypt-1.3.0/bindings/node/test/requirements.helper.js000066400000000000000000000014631414105245100244440ustar00rootroot00000000000000'use strict'; // Data Key Stuff const AWS_ACCESS_KEY_ID = process.env.AWS_ACCESS_KEY_ID; const AWS_SECRET_ACCESS_KEY = process.env.AWS_SECRET_ACCESS_KEY; const AWS_REGION = process.env.AWS_REGION; const AWS_CMK_ID = process.env.AWS_CMK_ID; const awsKmsProviders = { aws: { accessKeyId: AWS_ACCESS_KEY_ID, secretAccessKey: AWS_SECRET_ACCESS_KEY } }; const awsDataKeyOptions = { masterKey: { key: AWS_CMK_ID, region: AWS_REGION } }; const SKIP_LIVE_TESTS = !!process.env.MONGODB_NODE_SKIP_LIVE_TESTS; const SKIP_AWS_TESTS = SKIP_LIVE_TESTS || !AWS_ACCESS_KEY_ID || !AWS_SECRET_ACCESS_KEY || !AWS_REGION || !AWS_CMK_ID; module.exports = { SKIP_LIVE_TESTS, SKIP_AWS_TESTS, KEYS: { AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, AWS_CMK_ID }, awsKmsProviders, awsDataKeyOptions }; libmongocrypt-1.3.0/bindings/node/test/stateMachine.test.js000066400000000000000000000046721414105245100240330ustar00rootroot00000000000000'use strict'; const BSON = require('bson'); const EventEmitter = require('events').EventEmitter; const tls = require('tls'); const expect = require('chai').expect; const sinon = require('sinon'); const mongodb = require('mongodb'); const StateMachine = require('../lib/stateMachine')({ mongodb }).StateMachine; describe('StateMachine', function() { describe('kmsRequest', function() { class MockRequest { constructor(message, bytesNeeded) { this._bytesNeeded = typeof bytesNeeded === 'number' ? bytesNeeded : 1024; this._message = message; this.endpoint = 'some.fake.host.com'; } get message() { return this._message; } get bytesNeeded() { return this._bytesNeeded; } addResponse(buffer) { this._bytesNeeded -= buffer.length; } } class MockSocket extends EventEmitter { constructor(callback) { super(); this.on('connect', callback); } write() {} destroy() {} end(callback) { Promise.resolve().then(callback); } } before(function() { this.sinon = sinon.createSandbox(); }); beforeEach(function() { this.fakeSocket = undefined; this.sinon.stub(tls, 'connect').callsFake((options, callback) => { this.fakeSocket = new MockSocket(callback); return this.fakeSocket; }); }); it('should only resolve once bytesNeeded drops to zero', function(done) { const stateMachine = new StateMachine({ bson: BSON }); const request = new MockRequest(Buffer.from('foobar'), 500); let status = 'pending'; stateMachine .kmsRequest(request) .then( () => (status = 'resolved'), () => (status = 'rejected') ) .catch(() => {}); this.fakeSocket.emit('connect'); setTimeout(() => { expect(status).to.equal('pending'); expect(request.bytesNeeded).to.equal(500); this.fakeSocket.emit('data', Buffer.alloc(300)); setTimeout(() => { expect(status).to.equal('pending'); expect(request.bytesNeeded).to.equal(200); this.fakeSocket.emit('data', Buffer.alloc(200)); setTimeout(() => { expect(status).to.equal('resolved'); expect(request.bytesNeeded).to.equal(0); done(); }); }); }); }); afterEach(function() { this.sinon.restore(); }); }); }); libmongocrypt-1.3.0/bindings/python/000077500000000000000000000000001414105245100175165ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/python/.evergreen/000077500000000000000000000000001414105245100215565ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/python/.evergreen/test.sh000077500000000000000000000043171414105245100231010ustar00rootroot00000000000000#!/bin/bash # Test the Python bindings for libmongocrypt set -o xtrace # Write all commands first to stderr set -o errexit # Exit the script with error if any of the commands fail # For createvirtualenv. . .evergreen/utils.sh # MONGOCRYPT_DIR is set by libmongocrypt/.evergreen/config.yml MONGOCRYPT_DIR="$MONGOCRYPT_DIR" if [ "Windows_NT" = "$OS" ]; then # Magic variable in cygwin PYMONGOCRYPT_LIB=${MONGOCRYPT_DIR}/nocrypto/bin/mongocrypt.dll export PYMONGOCRYPT_LIB=$(cygpath -m $PYMONGOCRYPT_LIB) PYTHONS=("C:/python/Python27/python.exe" "C:/python/Python34/python.exe" "C:/python/Python35/python.exe" "C:/python/Python36/python.exe" "C:/python/Python37/python.exe" "C:/python/Python38/python.exe" "C:/python/Python39/python.exe") elif [ "Darwin" = "$(uname -s)" ]; then export PYMONGOCRYPT_LIB=${MONGOCRYPT_DIR}/nocrypto/lib/libmongocrypt.dylib PYTHONS=("python" # Python 2.7 from brew "python3" # Python 3 from brew "/System/Library/Frameworks/Python.framework/Versions/2.7/bin/python" "/Library/Frameworks/Python.framework/Versions/3.4/bin/python3" "/Library/Frameworks/Python.framework/Versions/3.5/bin/python3" "/Library/Frameworks/Python.framework/Versions/3.6/bin/python3" "/Library/Frameworks/Python.framework/Versions/3.7/bin/python3" "/Library/Frameworks/Python.framework/Versions/3.8/bin/python3" "/Library/Frameworks/Python.framework/Versions/3.9/bin/python3") else export PYMONGOCRYPT_LIB=${MONGOCRYPT_DIR}/nocrypto/lib64/libmongocrypt.so PYTHONS=("/opt/python/2.7/bin/python" "/opt/python/3.4/bin/python3" "/opt/python/3.5/bin/python3" "/opt/python/3.6/bin/python3" "/opt/python/pypy/bin/pypy" "/opt/python/pypy3.6/bin/pypy3") fi for PYTHON_BINARY in "${PYTHONS[@]}"; do echo "Running test with python: $PYTHON_BINARY" $PYTHON_BINARY -c 'import sys; print(sys.version)' createvirtualenv $PYTHON_BINARY .venv python -m pip install --prefer-binary -r test-requirements.txt python setup.py test deactivate rm -rf .venv done libmongocrypt-1.3.0/bindings/python/.evergreen/utils.sh000077500000000000000000000027201414105245100232560ustar00rootroot00000000000000#!/bin/bash -ex # Usage: # createvirtualenv /path/to/python /output/path/for/venv # * param1: Python binary to use for the virtualenv # * param2: Path to the virtualenv to create createvirtualenv () { PYTHON=$1 VENVPATH=$2 if $PYTHON -m virtualenv --version; then VIRTUALENV="$PYTHON -m virtualenv --system-site-packages --never-download" elif $PYTHON -m venv -h>/dev/null; then VIRTUALENV="$PYTHON -m venv --system-site-packages" elif command -v virtualenv; then VIRTUALENV="$(command -v virtualenv) -p $PYTHON --system-site-packages --never-download" else echo "Cannot test without virtualenv" exit 1 fi $VIRTUALENV $VENVPATH if [ "Windows_NT" = "$OS" ]; then . $VENVPATH/Scripts/activate else . $VENVPATH/bin/activate fi # Upgrade to the latest versions of pip setuptools wheel so that # pip can always download the latest cryptography+cffi wheels. PYTHON_VERSION=$(python -c 'import sys;print("%s.%s" % sys.version_info[:2])') if [[ $PYTHON_VERSION == "2.7" || $PYTHON_VERSION == "3.4" || $PYTHON_VERSION == "3.5" ]]; then # pip 19.2 dropped support for Python 3.4. # pip 21 dropped support for Python 2.7 and 3.5. curl -sSL https://bootstrap.pypa.io/pip/${PYTHON_VERSION}/get-pip.py -o get-pip.py python get-pip.py else python -m pip install --upgrade pip fi python -m pip install --upgrade pip setuptools wheel } libmongocrypt-1.3.0/bindings/python/.gitignore000066400000000000000000000001501414105245100215020ustar00rootroot00000000000000*~ *#* .DS* *.cm *.class *.pyc *.pyd build/ doc/_build/ dist/ *.so *.egg .tox .eggs/ .idea/ *.egg-info/ libmongocrypt-1.3.0/bindings/python/CHANGELOG.rst000066400000000000000000000026461414105245100215470ustar00rootroot00000000000000Changelog ========= Changes in Version 1.1.1 ------------------------ - Bundle libmongocrypt 1.2.1 in release wheels. Changes in Version 1.1.0 ------------------------ - Add support for Azure and GCP KMS providers. - Add support for temporary AWS credentials via the "sessionToken" option. - Bundle libmongocrypt 1.2.0 in release wheels. - **Remove support for libmongocrypt 1.0 and 1.1, libmongocrypt >=1.2 is now required.** Note this is only relevant for users that install from source or use the ``PYMONGOCRYPT_LIB`` envirnoment variable. Changes in Version 1.0.1 ------------------------ - Bundle libmongocrypt 1.0.4 in release wheels. Changes in Version 1.0.0 ------------------------ - The first stable version. - Bundle libmongocrypt 1.0.0 in release wheels. Changes in Version 0.1b3 ------------------------ - Add support for custom KMS endpoints with the AWS masterkey provider. - Bundle libmongocrypt 1.0.0 in release wheels. Changes in Version 0.1b2 ------------------------ - Document that pip 19 is required for manylinux2010 wheel installation. - Bundle libmongocrypt 1.0.0-beta5 in release wheels. Changes in Version 0.1b1 ------------------------ - Make pymongocrypt compatible with manylinux2010 releases. - Bundle libmongocrypt 1.0.0-beta4 in release wheels. Changes in Version 0.1b0 ------------------------ - Initial Python binding for libmongocrypt. - Bundle libmongocrypt 1.0.0-beta4 in release wheels. libmongocrypt-1.3.0/bindings/python/LICENSE000066400000000000000000000261351414105245100205320ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. libmongocrypt-1.3.0/bindings/python/README.rst000066400000000000000000000163351414105245100212150ustar00rootroot00000000000000============ PyMongoCrypt ============ :Info: Python bindings for libmongocrypt. See `GitHub `_ for the latest source. :Author: Shane Harvey About ===== Python wrapper library for libmongocrypt that supports client side encryption in drivers. PyMongoCrypt uses `cffi `_ and `cryptography `_. PyMongoCrypt supports Python 2.7, 3.4+, and PyPy3.5+. Support / Feedback ================== For issues with, questions about, or feedback for PyMongoCrypt, please look into our `support channels `_. Please do not email any of the PyMongoCrypt developers directly with issues or questions - you're more likely to get an answer on the `mongodb-user `_ list on Google Groups. Bugs / Feature Requests ======================= Think you’ve found a bug? Want to see a new feature in PyMongoCrypt? Please open a case in our issue management tool, JIRA: - `Create an account and login `_. - Navigate to `the PYTHON project `_. - Click **Create Issue** - Please provide as much information as possible about the issue type and how to reproduce it. Bug reports in JIRA for all driver projects (i.e. PYTHON, CSHARP, JAVA) and the Core Server (i.e. SERVER) project are **public**. How To Ask For Help ------------------- Please include all of the following information when opening an issue: - Detailed steps to reproduce the problem, including full traceback, if possible. - The exact python version used, with patch level:: $ python -c "import sys; print(sys.version)" - The exact version of PyMongoCrypt used:: $ python -c "import pymongocrypt; print(pymongocrypt.__version__)" - The exact version of libbmongocrypt used by PyMongoCrypt:: $ python -c "import pymongocrypt; print(pymongocrypt.libmongocrypt_version())" - The exact version of PyMongo used (if applicable), with patch level:: $ python -c "import pymongo; print(pymongo.version); print(pymongo.has_c())" - The operating system and version (e.g. Windows 7, OSX 10.8, ...) - Web framework or asynchronous network library used, if any, with version (e.g. Django 1.7, mod_wsgi 4.3.0, gevent 1.0.1, Tornado 4.0.2, ...) Security Vulnerabilities ------------------------ If you've identified a security vulnerability in a driver or any other MongoDB project, please report it according to the `instructions here `_. Installation ============ PyMongoCrypt can be installed with `pip `_:: $ python -m pip install pymongocrypt $ python -c "import pymongocrypt; print(pymongocrypt.libmongocrypt_version())" 1.2.1 PyMongoCrypt ships wheels for macOS, Windows, and manylinux2010 that include an embedded libmongocrypt build. Installing from wheels on Linux requires pip 19 or later because it adds `support for manylinux2010 wheels `_. Older versions of pip will attempt installation using the pymongocrypt-X.Y.tar.gz source distribution which requires the extra step of downloading and installing libmongocrypt as described below. Users can upgrade to pip 19 by running:: $ python -m pip install --upgrade 'pip>=19' Installing from source ---------------------- Installing from source (or the pymongocrypt-X.Y.tar.gz source distribution, or pip < 19 on Linux) requires an extra step of installing libmongocrypt. First, install PyMongoCrypt from source:: $ git clone git@github.com:mongodb/libmongocrypt.git $ python -m pip install ./libmongocrypt/bindings/python Next, install libmongocrypt. libmongocrypt is `continuously built and published on evergreen `_. The latest tarball containing libmongocrypt built on all supported variants is `published here `_. Download and extract ``libmongocrypt-all.tar.gz`` and set ``PYMONGOCRYPT_LIB`` to the path to your operating system's libmongocrypt.so file. For example:: $ curl -O https://s3.amazonaws.com/mciuploads/libmongocrypt/all/master/latest/libmongocrypt-all.tar.gz $ mkdir libmongocrypt-all && tar xzf libmongocrypt-all.tar.gz -C libmongocrypt-all $ ls libmongocrypt-all amazon2 rhel-62-64-bit rhel72-zseries-test ubuntu1604-arm64 debian10 rhel-67-s390x suse12-64 ubuntu1804-64 debian92 rhel-70-64-bit suse12-s390x ubuntu1804-arm64 linux-64-amazon-ami rhel-71-ppc64el suse15-64 windows-test macos rhel-80-64-bit ubuntu1604 macOS:: $ # Set PYMONGOCRYPT_LIB for macOS: $ export PYMONGOCRYPT_LIB=$(pwd)/libmongocrypt-all/macos/nocrypto/lib/libmongocrypt.dylib $ python -c "import pymongocrypt; print(pymongocrypt.libmongocrypt_version())" 1.2.1 Windows:: $ # Set PYMONGOCRYPT_LIB for Windows: $ chmod +x $(pwd)/libmongocrypt-all/windows-test/nocrypto/bin/mongocrypt.dll $ export PYMONGOCRYPT_LIB=$(pwd)/libmongocrypt-all/windows-test/nocrypto/bin/mongocrypt.dll $ python -c "import pymongocrypt; print(pymongocrypt.libmongocrypt_version())" 1.2.1 Linux:: $ # Set PYMONGOCRYPT_LIB for RHEL 6.2 x86_64: $ export PYMONGOCRYPT_LIB=$(pwd)/libmongocrypt-all/rhel-62-64-bit/nocrypto/lib64/libmongocrypt.so $ python -c "import pymongocrypt; print(pymongocrypt.libmongocrypt_version())" 1.2.1 Dependencies ============ PyMongoCrypt supports CPython 2.7, 3.4+, PyPy, and PyPy3.5+. PyMongoCrypt requires `cffi `_ and `cryptography `_. PyMongoCrypt also requires libmongocrypt to be installed on your system. If libmongocrypt is not installed you will see an error like this: .. code-block:: python >>> import pymongocrypt Traceback (most recent call last): File "", line 1, in File "pymongocrypt/__init__.py", line 15, in from pymongocrypt.binding import libmongocrypt_version, lib File "pymongocrypt/binding.py", line 803, in lib = ffi.dlopen(os.environ.get('PYMONGOCRYPT_LIB', 'mongocrypt')) File "/.../lib/python3.7/site-packages/cffi/api.py", line 146, in dlopen lib, function_cache = _make_ffi_library(self, name, flags) File "/.../lib/python3.7/site-packages/cffi/api.py", line 828, in _make_ffi_library backendlib = _load_backend_lib(backend, libname, flags) File "/.../lib/python3.7/site-packages/cffi/api.py", line 823, in _load_backend_lib raise OSError(msg) OSError: ctypes.util.find_library() did not manage to locate a library called 'mongocrypt' Use the ``PYMONGOCRYPT_LIB`` environment variable to load a locally installed libmongocrypt build without relying on platform specific library path environment variables, like ``LD_LIBRARY_PATH``. For example:: $ export PYMONGOCRYPT_LIB='/path/to/libmongocrypt.so' $ python -c "import pymongocrypt; print(pymongocrypt.libmongocrypt_version())" 1.2.1 Testing ======= The easiest way to run the tests is to run **python setup.py test** in the root of the distribution. libmongocrypt-1.3.0/bindings/python/RELEASE.rst000066400000000000000000000062531414105245100213360ustar00rootroot00000000000000===================== PyMongoCrypt Releases ===================== Versioning ---------- PyMongoCrypt's version numbers follow `semantic versioning`_: each version number is structured "major.minor.patch". Patch releases fix bugs, minor releases add features (and may fix bugs), and major releases include API changes that break backwards compatibility (and may add features and fix bugs). In between releases we add .devN to the version number to denote the version under development. So if we just released 1.0.0, then the current dev version might be 1.0.1.dev0 or 1.1.0.dev0. PyMongoCrypt's version numbers do not necessarily correspond to the embedded libmongocrypt library's version number. For example, assume the current PyMongoCrypt version is 1.0 and libmongocrypt is 1.0. Let's say that libmongocrypt 2.0.0 is released which has breaking changes to its API. If those 2.0.0 changes do not require any breaking changes to PyMongoCrypt, then the next version can be 1.1. .. _semantic versioning: http://semver.org/ Release Process --------------- PyMongoCrypt ships wheels for macOS, Windows, and manylinux2010 that include an embedded libmongocrypt build. Releasing a new version requires macOS with Docker and a Windows machine. #. Edit the release.sh script to embed the most recent libmongocrypt tag into our wheels, for example:: # The libmongocrypt git revision release to embed in our wheels. -REVISION=$(git rev-list -n 1 1.0.0) +REVISION=$(git rev-list -n 1 1.0.1) #. Add a changlog entry for this release in CHANGELOG.rst. #. Bump "__version__" in pymongocrypt/version.py. Commit the change and tag the release. Immediately bump the "__version__" to "dev0" in a new commit:: $ # Bump to release version number $ git commit -a -m "pymongocrypt " $ git tag -a "pymongocrypt " $ # Bump to dev version number $ git commit -a -m "BUMP pymongocrypt " $ git push $ git push --tags #. Build the release packages for macOS and manylinux by running the release.sh script on macOS. Note that Docker must be running:: $ git clone git@github.com:mongodb/libmongocrypt.git $ cd libmongocrypt/bindings/python $ git checkout "pymongocrypt " $ ./release.sh This will create the following distributions:: $ ls dist pymongocrypt-.tar.gz pymongocrypt--py2.py3-none-manylinux2010_x86_64.whl pymongocrypt--py2.py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.whl pymongocrypt--py2.py3-none-macosx_10_9_x86_64.whl #. To build the release package for Windows, launch a windows-64-vsMulti-small Evergreen spawn host, clone the repro, checkout the release tag, and run the release script:: $ git clone git@github.com:mongodb/libmongocrypt.git $ cd libmongocrypt/bindings/python $ git checkout "pymongocrypt " $ ./release.sh This will create the following distributions:: $ ls dist pymongocrypt--py2.py3-none-win_amd64.whl #. Upload all the release packages to PyPI with twine:: $ python3 -m twine upload dist/* libmongocrypt-1.3.0/bindings/python/build-manylinux-wheel.sh000077500000000000000000000006051414105245100243010ustar00rootroot00000000000000#!/bin/bash -ex cd /python # Compile wheel # https://github.com/pypa/manylinux/issues/49 rm -rf build /opt/python/cp37-cp37m/bin/python setup.py bdist_wheel --universal # Audit wheels and write manylinux tag for whl in dist/*.whl; do # Skip already built manylinux wheels. if [[ "$whl" != *"manylinux"* ]]; then auditwheel repair $whl -w dist rm $whl fi done libmongocrypt-1.3.0/bindings/python/pymongocrypt/000077500000000000000000000000001414105245100222705ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/python/pymongocrypt/__init__.py000066400000000000000000000012571414105245100244060ustar00rootroot00000000000000# Copyright 2019-present MongoDB, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from pymongocrypt.binding import libmongocrypt_version, lib from pymongocrypt.version import __version__ libmongocrypt-1.3.0/bindings/python/pymongocrypt/auto_encrypter.py000066400000000000000000000040051414105245100257040ustar00rootroot00000000000000# Copyright 2019-present MongoDB, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from pymongocrypt.mongocrypt import MongoCrypt from pymongocrypt.state_machine import run_state_machine class AutoEncrypter(object): def __init__(self, callback, mongo_crypt_opts): """Encrypts and decrypts MongoDB commands. This class is used by a driver to support automatic encryption and decryption of MongoDB commands. :Parameters: - `callback`: A :class:`MongoCryptCallback`. - `mongo_crypt_opts`: A :class:`MongoCryptOptions`. """ self.callback = callback self.mongocrypt = MongoCrypt(mongo_crypt_opts, callback) def encrypt(self, database, cmd): """Encrypt a MongoDB command. :Parameters: - `database`: The database for this command. - `cmd`: A MongoDB command as BSON. :Returns: The encrypted command. """ with self.mongocrypt.encryption_context(database, cmd) as ctx: return run_state_machine(ctx, self.callback) def decrypt(self, response): """Decrypt a MongoDB command response. :Parameters: - `response`: A MongoDB command response as BSON. :Returns: The decrypted command response. """ with self.mongocrypt.decryption_context(response) as ctx: return run_state_machine(ctx, self.callback) def close(self): """Cleanup resources.""" self.mongocrypt.close() self.callback.close() libmongocrypt-1.3.0/bindings/python/pymongocrypt/binary.py000066400000000000000000000061241414105245100241310ustar00rootroot00000000000000# Copyright 2019-present MongoDB, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Internal helpers for dealing with mongocrypt_binary_t.""" from pymongocrypt.binding import ffi, lib from pymongocrypt.errors import MongoCryptError def _to_bytes(mongocrypt_binary): """Returns this mongocrypt_binary_t as bytes.""" data = lib.mongocrypt_binary_data(mongocrypt_binary) if data == ffi.NULL: raise MongoCryptError('mongocrypt_binary_data returned NULL') data_len = lib.mongocrypt_binary_len(mongocrypt_binary) return ffi.unpack(ffi.cast("char*", data), data_len) def _write_bytes(mongocrypt_binary, data): """Writes the given data to a mongocrypt_binary_t.""" buf = lib.mongocrypt_binary_data(mongocrypt_binary) if buf == ffi.NULL: raise MongoCryptError('mongocrypt_binary_data returned NULL') ffi.memmove(buf, data, len(data)) class _MongoCryptBinary(object): __slots__ = ("bin",) def __init__(self, binary): """Wraps a mongocrypt_binary_t.""" if binary == ffi.NULL: raise MongoCryptError( "unable to create new mongocrypt_binary object") self.bin = binary def _close(self): """Cleanup resources.""" if self.bin: lib.mongocrypt_binary_destroy(self.bin) self.bin = None def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): self._close() def to_bytes(self): """Returns this mongocrypt_binary_t as bytes.""" data = lib.mongocrypt_binary_data(self.bin) if data == ffi.NULL: return b'' data_len = lib.mongocrypt_binary_len(self.bin) return ffi.unpack(ffi.cast("char*", data), data_len) class MongoCryptBinaryOut(_MongoCryptBinary): __slots__ = () def __init__(self): """Wraps a mongocrypt_binary_t.""" super(MongoCryptBinaryOut, self).__init__(lib.mongocrypt_binary_new()) class MongoCryptBinaryIn(_MongoCryptBinary): __slots__ = ("cref",) def __init__(self, data): """Creates a mongocrypt_binary_t from binary data.""" # mongocrypt_binary_t does not own the data it is passed so we need to # create a separate reference to keep the data alive. self.cref = ffi.from_buffer("uint8_t[]", data) super(MongoCryptBinaryIn, self).__init__( lib.mongocrypt_binary_new_from_data(self.cref, len(data))) def _close(self): """Cleanup resources.""" super(MongoCryptBinaryIn, self)._close() if self.cref is not None: ffi.release(self.cref) self.cref = None libmongocrypt-1.3.0/bindings/python/pymongocrypt/binding.py000066400000000000000000001124151414105245100242600ustar00rootroot00000000000000# Copyright 2019-present MongoDB, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import os.path import sys import cffi from pymongocrypt.compat import PY3 from pymongocrypt.version import _MIN_LIBMONGOCRYPT_VERSION try: from pkg_resources import parse_version as _parse_version except ImportError: from distutils.version import LooseVersion as _LooseVersion def _parse_version(version): return _LooseVersion(version) ffi = cffi.FFI() # Generated with strip_header.py ffi.cdef(""" /* * Copyright 2019-present MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** @file mongocrypt.h The top-level handle to libmongocrypt. */ /** * @mainpage libmongocrypt * See all public API documentation in: @ref mongocrypt.h */ /** * @def MONGOCRYPT_VERSION * The version string describing libmongocrypt. * Has the form x.y.z-
++git.
 */

/**
 * Returns the version string for libmongocrypt.
 *
 * @param[out] len  An optional length of the returned string. May be NULL.
 * @returns a NULL terminated version string for libmongocrypt.
 */
const char *
mongocrypt_version (uint32_t *len);

/**
 * A non-owning view of a byte buffer.
 *
 * When constructing a mongocrypt_binary_t it is the responsibility of the
 * caller to maintain the lifetime of the viewed data. However, all public
 * functions that take a mongocrypt_binary_t as an argument will make a copy of
 * the viewed data. For example, the following is valid:
 *
 * @code{.c}
 * mongocrypt_binary_t bin = mongocrypt_binary_new_from_data(mydata, mylen);
 * assert (mongocrypt_setopt_kms_provider_local (crypt), bin);
 * // The viewed data of bin has been copied. Ok to free the view and the data.
 * mongocrypt_binary_destroy (bin);
 * my_free_fn (mydata);
 * @endcode
 *
 * Functions with a mongocrypt_binary_t* out guarantee the lifetime of the
 * viewed data to live as long as the parent object. For example, @ref
 * mongocrypt_ctx_mongo_op guarantees that the viewed data of
 * mongocrypt_binary_t is valid until the parent ctx is destroyed with @ref
 * mongocrypt_ctx_destroy.
 */
typedef struct _mongocrypt_binary_t mongocrypt_binary_t;

/**
 * Create a new non-owning view of a buffer (data + length).
 *
 * Use this to create a mongocrypt_binary_t used for output parameters.
 *
 * @returns A new mongocrypt_binary_t.
 */
mongocrypt_binary_t *
mongocrypt_binary_new (void);

/**
 * Create a new non-owning view of a buffer (data + length).
 *
 * @param[in] data A pointer to an array of bytes. This data is not copied. @p
 * data must outlive the binary object.
 * @param[in] len The length of the @p data byte array.
 *
 * @returns A new @ref mongocrypt_binary_t.
 */
mongocrypt_binary_t *
mongocrypt_binary_new_from_data (uint8_t *data, uint32_t len);

/**
 * Get a pointer to the viewed data.
 *
 * @param[in] binary The @ref mongocrypt_binary_t.
 *
 * @returns A pointer to the viewed data.
 */
uint8_t *
mongocrypt_binary_data (const mongocrypt_binary_t *binary);

/**
 * Get the length of the viewed data.
 *
 * @param[in] binary The @ref mongocrypt_binary_t.
 *
 * @returns The length of the viewed data.
 */
uint32_t
mongocrypt_binary_len (const mongocrypt_binary_t *binary);

/**
 * Free the @ref mongocrypt_binary_t.
 *
 * This does not free the viewed data.
 *
 * @param[in] binary The mongocrypt_binary_t destroy.
 */
void
mongocrypt_binary_destroy (mongocrypt_binary_t *binary);

/**
 * Indicates success or contains error information.
 *
 * Functions like @ref mongocrypt_ctx_encrypt_init follow a pattern to expose a
 * status. A boolean is returned. True indicates success, and false indicates
 * failure. On failure a status on the handle is set, and is accessible with a
 * corresponding (handle)_status function. E.g. @ref mongocrypt_ctx_status.
 */
typedef struct _mongocrypt_status_t mongocrypt_status_t;

/**
 * Indicates the type of error.
 */
typedef enum {
   MONGOCRYPT_STATUS_OK = 0,
   MONGOCRYPT_STATUS_ERROR_CLIENT = 1,
   MONGOCRYPT_STATUS_ERROR_KMS = 2
} mongocrypt_status_type_t;

/**
 * Create a new status object.
 *
 * Use a new status object to retrieve the status from a handle by passing
 * this as an out-parameter to functions like @ref mongocrypt_ctx_status.
 * When done, destroy it with @ref mongocrypt_status_destroy.
 *
 * @returns A new status object.
 */
mongocrypt_status_t *
mongocrypt_status_new (void);

/**
 * Set a status object with message, type, and code.
 *
 * Use this to set the @ref mongocrypt_status_t given in the crypto hooks.
 *
 * @param[in] type The status type.
 * @param[in] code The status code.
 * @param[in] message The message.
 * @param[in] message_len Due to historical behavior, pass 1 + the string length
 * of @p message (which differs from other functions accepting string
 * arguments).
 * Alternatively, if message is NULL terminated this may be -1 to tell
 * mongocrypt
 * to determine the string's length with strlen.
 *
 */
void
mongocrypt_status_set (mongocrypt_status_t *status,
                       mongocrypt_status_type_t type,
                       uint32_t code,
                       const char *message,
                       int32_t message_len);

/**
 * Indicates success or the type of error.
 *
 * @param[in] status The status object.
 *
 * @returns A @ref mongocrypt_status_type_t.
 */
mongocrypt_status_type_t
mongocrypt_status_type (mongocrypt_status_t *status);

/**
 * Get an error code or 0.
 *
 * @param[in] status The status object.
 *
 * @returns An error code.
 */
uint32_t
mongocrypt_status_code (mongocrypt_status_t *status);

/**
 * Get the error message associated with a status or NULL.
 *
 * @param[in] status The status object.
 * @param[out] len An optional length of the returned string (excluding the
 * trailing NULL byte). May be NULL.
 *
 * @returns A NULL terminated error message or NULL.
 */
const char *
mongocrypt_status_message (mongocrypt_status_t *status, uint32_t *len);

/**
 * Returns true if the status indicates success.
 *
 * @param[in] status The status to check.
 *
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_status_ok (mongocrypt_status_t *status);

/**
 * Free the memory for a status object.
 *
 * @param[in] status The status to destroy.
 */
void
mongocrypt_status_destroy (mongocrypt_status_t *status);

/**
 * Indicates the type of log message.
 */
typedef enum {
   MONGOCRYPT_LOG_LEVEL_FATAL = 0,
   MONGOCRYPT_LOG_LEVEL_ERROR = 1,
   MONGOCRYPT_LOG_LEVEL_WARNING = 2,
   MONGOCRYPT_LOG_LEVEL_INFO = 3,
   MONGOCRYPT_LOG_LEVEL_TRACE = 4
} mongocrypt_log_level_t;

/**
 * A log callback function. Set a custom log callback with @ref
 * mongocrypt_setopt_log_handler.
 *
 * @param[in] message A NULL terminated message.
 * @param[in] message_len The length of message.
 * @param[in] ctx A context provided by the caller of @ref
 * mongocrypt_setopt_log_handler.
 */
typedef void (*mongocrypt_log_fn_t) (mongocrypt_log_level_t level,
                                     const char *message,
                                     uint32_t message_len,
                                     void *ctx);

/**
 * The top-level handle to libmongocrypt.
 *
 * Create a mongocrypt_t handle to perform operations within libmongocrypt:
 * encryption, decryption, registering log callbacks, etc.
 *
 * Functions on a mongocrypt_t are thread safe, though functions on derived
 * handles (e.g. mongocrypt_ctx_t) are not and must be owned by a single
 * thread. See each handle's documentation for thread-safety considerations.
 *
 * Multiple mongocrypt_t handles may be created.
 */
typedef struct _mongocrypt_t mongocrypt_t;

/**
 * Allocate a new @ref mongocrypt_t object.
 *
 * Set options using mongocrypt_setopt_* functions, then initialize with @ref
 * mongocrypt_init. When done with the @ref mongocrypt_t, free with @ref
 * mongocrypt_destroy.
 *
 * @returns A new @ref mongocrypt_t object.
 */
mongocrypt_t *
mongocrypt_new (void);

/**
 * Set a handler on the @ref mongocrypt_t object to get called on every log
 * message.
 *
 * @param[in] crypt The @ref mongocrypt_t object.
 * @param[in] log_fn The log callback.
 * @param[in] log_ctx A context passed as an argument to the log callback every
 * invokation.
 * @pre @ref mongocrypt_init has not been called on @p crypt.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_setopt_log_handler (mongocrypt_t *crypt,
                               mongocrypt_log_fn_t log_fn,
                               void *log_ctx);

/**
 * Configure an AWS KMS provider on the @ref mongocrypt_t object.
 *
 * @param[in] crypt The @ref mongocrypt_t object.
 * @param[in] aws_access_key_id The AWS access key ID used to generate KMS
 * messages.
 * @param[in] aws_access_key_id_len The string length (in bytes) of @p
 * aws_access_key_id. Pass -1 to determine the string length with strlen (must
 * be NULL terminated).
 * @param[in] aws_secret_access_key The AWS secret access key used to generate
 * KMS messages.
 * @param[in] aws_secret_access_key_len The string length (in bytes) of @p
 * aws_secret_access_key. Pass -1 to determine the string length with strlen
 * (must be NULL terminated).
 * @pre @ref mongocrypt_init has not been called on @p crypt.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_setopt_kms_provider_aws (mongocrypt_t *crypt,
                                    const char *aws_access_key_id,
                                    int32_t aws_access_key_id_len,
                                    const char *aws_secret_access_key,
                                    int32_t aws_secret_access_key_len);

/**
 * Configure a local KMS provider on the @ref mongocrypt_t object.
 *
 * @param[in] crypt The @ref mongocrypt_t object.
 * @param[in] key A 96 byte master key used to encrypt and decrypt key vault
 * keys. The viewed data is copied. It is valid to destroy @p key with @ref
 * mongocrypt_binary_destroy immediately after.
 * @pre @ref mongocrypt_init has not been called on @p crypt.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_setopt_kms_provider_local (mongocrypt_t *crypt,
                                      mongocrypt_binary_t *key);

/**
 * Configure KMS providers with a BSON document.
 * Currently only applies to Azure.
 *
 * @param[in] crypt The @ref mongocrypt_t object.
 * @param[in] kms_providers A BSON document mapping the KMS provider names
 * to credentials.
 * @pre @ref mongocrypt_init has not been called on @p crypt.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_setopt_kms_providers (mongocrypt_t *crypt,
                                 mongocrypt_binary_t *kms_providers);

/**
 * Set a local schema map for encryption.
 *
 * @param[in] crypt The @ref mongocrypt_t object.
 * @param[in] schema_map A BSON document representing the schema map supplied by
 * the user. The keys are collection namespaces and values are JSON schemas. The
 * viewed data copied. It is valid to destroy @p schema_map with @ref
 * mongocrypt_binary_destroy immediately after.
 * @pre @p crypt has not been initialized.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_status
 */
bool
mongocrypt_setopt_schema_map (mongocrypt_t *crypt,
                              mongocrypt_binary_t *schema_map);

/**
 * Initialize new @ref mongocrypt_t object.
 *
 * Set options before using @ref mongocrypt_setopt_kms_provider_local, @ref
 * mongocrypt_setopt_kms_provider_aws, or @ref mongocrypt_setopt_log_handler.
 *
 * @param[in] crypt The @ref mongocrypt_t object.
 *
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status Failure may occur if previously
 * set
 * options are invalid.
 */
bool
mongocrypt_init (mongocrypt_t *crypt);

/**
 * Get the status associated with a @ref mongocrypt_t object.
 *
 * @param[in] crypt The @ref mongocrypt_t object.
 * @param[out] status Receives the status.
 *
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_status (mongocrypt_t *crypt, mongocrypt_status_t *status);

/**
 * Destroy the @ref mongocrypt_t object.
 *
 * @param[in] crypt The @ref mongocrypt_t object to destroy.
 */
void
mongocrypt_destroy (mongocrypt_t *crypt);

/**
 * Manages the state machine for encryption or decryption.
 */
typedef struct _mongocrypt_ctx_t mongocrypt_ctx_t;

/**
 * Create a new uninitialized @ref mongocrypt_ctx_t.
 *
 * Initialize the context with functions like @ref mongocrypt_ctx_encrypt_init.
 * When done, destroy it with @ref mongocrypt_ctx_destroy.
 *
 * @param[in] crypt The @ref mongocrypt_t object.
 * @returns A new context.
 */
mongocrypt_ctx_t *
mongocrypt_ctx_new (mongocrypt_t *crypt);

/**
 * Get the status associated with a @ref mongocrypt_ctx_t object.
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 * @param[out] status Receives the status.
 *
 * @returns True if the output is an ok status, false if it is an error
 * status.
 *
 * @see mongocrypt_status_ok
 */
bool
mongocrypt_ctx_status (mongocrypt_ctx_t *ctx, mongocrypt_status_t *status);

/**
 * Set the key id to use for explicit encryption.
 *
 * It is an error to set both this and the key alt name.
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 * @param[in] key_id The binary corresponding to the _id (a UUID) of the data
 * key to use from the key vault collection. Note, the UUID must be encoded with
 * RFC-4122 byte order. The viewed data is copied. It is valid to destroy
 * @p key_id with @ref mongocrypt_binary_destroy immediately after.
 * @pre @p ctx has not been initialized.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_ctx_setopt_key_id (mongocrypt_ctx_t *ctx,
                              mongocrypt_binary_t *key_id);

/**
 * Set the keyAltName to use for explicit encryption or
 * data key creation.
 *
 * Pass the binary encoding a BSON document like the following:
 *
 *   { "keyAltName" : (BSON UTF8 value) }
 *
 * For explicit encryption, it is an error to set both the keyAltName
 * and the key id.
 *
 * For creating data keys, call this function repeatedly to set
 * multiple keyAltNames.
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 * @param[in] key_alt_name The name to use. The viewed data is copied. It is
 * valid to destroy @p key_alt_name with @ref mongocrypt_binary_destroy
 * immediately after.
 * @pre @p ctx has not been initialized.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_ctx_setopt_key_alt_name (mongocrypt_ctx_t *ctx,
                                    mongocrypt_binary_t *key_alt_name);

/**
 * Set the algorithm used for encryption to either
 * deterministic or random encryption. This value
 * should only be set when using explicit encryption.
 *
 * If -1 is passed in for "len", then "algorithm" is
 * assumed to be a null-terminated string.
 *
 * Valid values for algorithm are:
 *   "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
 *   "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 * @param[in] algorithm A string specifying the algorithm to
 * use for encryption.
 * @param[in] len The length of the algorithm string.
 * @pre @p ctx has not been initialized.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_ctx_setopt_algorithm (mongocrypt_ctx_t *ctx,
                                 const char *algorithm,
                                 int len);

/**
 * Identify the AWS KMS master key to use for creating a data key.
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 * @param[in] region The AWS region.
 * @param[in] region_len The string length of @p region. Pass -1 to determine
 * the string length with strlen (must be NULL terminated).
 * @param[in] cmk The Amazon Resource Name (ARN) of the customer master key
 * (CMK).
 * @param[in] cmk_len The string length of @p cmk_len. Pass -1 to determine the
 * string length with strlen (must be NULL terminated).
 * @pre @p ctx has not been initialized.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_ctx_setopt_masterkey_aws (mongocrypt_ctx_t *ctx,
                                     const char *region,
                                     int32_t region_len,
                                     const char *cmk,
                                     int32_t cmk_len);

/**
 * Identify a custom AWS endpoint when creating a data key.
 * This is used internally to construct the correct HTTP request
 * (with the Host header set to this endpoint). This endpoint
 * is persisted in the new data key, and will be returned via
 * @ref mongocrypt_kms_ctx_endpoint.
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 * @param[in] endpoint The endpoint.
 * @param[in] endpoint_len The string length of @p endpoint. Pass -1 to
 * determine the string length with strlen (must be NULL terminated).
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_ctx_setopt_masterkey_aws_endpoint (mongocrypt_ctx_t *ctx,
                                              const char *endpoint,
                                              int32_t endpoint_len);

/**
 * Set the master key to "local" for creating a data key.
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 * @pre @p ctx has not been initialized.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_ctx_setopt_masterkey_local (mongocrypt_ctx_t *ctx);

/**
 * Set key encryption key document for creating a data key.
 * Currently only applies to Azure.
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 * @param[in] bin BSON representing the key encryption key document.
 * @pre @p ctx has not been initialized.
 * @returns A boolean indicating success. If false, and error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status.
 */
bool
mongocrypt_ctx_setopt_key_encryption_key (mongocrypt_ctx_t *ctx,
                                          mongocrypt_binary_t *bin);

/**
 * Initialize a context to create a data key.
 *
 * Associated options:
 * - @ref mongocrypt_ctx_setopt_masterkey_aws
 * - @ref mongocrypt_ctx_setopt_masterkey_aws_endpoint
 * - @ref mongocrypt_ctx_setopt_masterkey_local
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 * @pre A master key option has been set, and an associated KMS provider
 * has been set on the parent @ref mongocrypt_t.
 */
bool
mongocrypt_ctx_datakey_init (mongocrypt_ctx_t *ctx);

/**
 * Initialize a context for encryption.
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 * @param[in] db The database name.
 * @param[in] db_len The byte length of @p db. Pass -1 to determine the string
 * length with strlen (must
 * be NULL terminated).
 * @param[in] cmd The BSON command to be encrypted. The viewed data is copied.
 * It is valid to destroy @p cmd with @ref mongocrypt_binary_destroy immediately
 * after.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_ctx_encrypt_init (mongocrypt_ctx_t *ctx,
                             const char *db,
                             int32_t db_len,
                             mongocrypt_binary_t *cmd);

/**
 * Explicit helper method to encrypt a single BSON object. Contexts
 * created for explicit encryption will not go through mongocryptd.
 *
 * To specify a key_id, algorithm, or iv to use, please use the
 * corresponding mongocrypt_setopt methods before calling this.
 *
 * This method expects the passed-in BSON to be of the form:
 * { "v" : BSON value to encrypt }
 *
 * Associated options:
 * - @ref mongocrypt_ctx_setopt_key_id
 * - @ref mongocrypt_ctx_setopt_key_alt_name
 * - @ref mongocrypt_ctx_setopt_algorithm
 *
 * @param[in] ctx A @ref mongocrypt_ctx_t.
 * @param[in] msg A @ref mongocrypt_binary_t the plaintext BSON value. The
 * viewed data is copied. It is valid to destroy @p msg with @ref
 * mongocrypt_binary_destroy immediately after.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_ctx_explicit_encrypt_init (mongocrypt_ctx_t *ctx,
                                      mongocrypt_binary_t *msg);

/**
 * Initialize a context for decryption.
 *
 * This method expects the passed-in BSON to be of the form:
 * { "v" : BSON value to encrypt }
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 * @param[in] doc The document to be decrypted. The viewed data is copied. It is
 * valid to destroy @p doc with @ref mongocrypt_binary_destroy immediately
 * after.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_ctx_decrypt_init (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *doc);

/**
 * Explicit helper method to decrypt a single BSON object.
 *
 *
 * @param[in] ctx A @ref mongocrypt_ctx_t.
 * @param[in] msg A @ref mongocrypt_binary_t the encrypted BSON. The viewed data
 * is copied. It is valid to destroy @p msg with @ref mongocrypt_binary_destroy
 * immediately after.
 */
bool
mongocrypt_ctx_explicit_decrypt_init (mongocrypt_ctx_t *ctx,
                                      mongocrypt_binary_t *msg);

/**
 * Indicates the state of the @ref mongocrypt_ctx_t. Each state requires
 * different handling. See [the integration
 * guide](https://github.com/mongodb/libmongocrypt/blob/master/integrating.md#state-machine)
 * for information on what to do for each state.
 */
typedef enum {
   MONGOCRYPT_CTX_ERROR = 0,
   MONGOCRYPT_CTX_NEED_MONGO_COLLINFO = 1, /* run on main MongoClient */
   MONGOCRYPT_CTX_NEED_MONGO_MARKINGS = 2, /* run on mongocryptd. */
   MONGOCRYPT_CTX_NEED_MONGO_KEYS = 3,     /* run on key vault */
   MONGOCRYPT_CTX_NEED_KMS = 4,
   MONGOCRYPT_CTX_READY = 5, /* ready for encryption/decryption */
   MONGOCRYPT_CTX_DONE = 6
} mongocrypt_ctx_state_t;

/**
 * Get the current state of a context.
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 * @returns A @ref mongocrypt_ctx_state_t.
 */
mongocrypt_ctx_state_t
mongocrypt_ctx_state (mongocrypt_ctx_t *ctx);

/**
 * Get BSON necessary to run the mongo operation when mongocrypt_ctx_t
 * is in MONGOCRYPT_CTX_NEED_MONGO_* states.
 *
 * @p op_bson is a BSON document to be used for the operation.
 * - For MONGOCRYPT_CTX_NEED_MONGO_COLLINFO it is a listCollections filter.
 * - For MONGOCRYPT_CTX_NEED_MONGO_KEYS it is a find filter.
 * - For MONGOCRYPT_CTX_NEED_MONGO_MARKINGS it is a command to send to
 * mongocryptd.
 *
 * The lifetime of @p op_bson is tied to the lifetime of @p ctx. It is valid
 * until @ref mongocrypt_ctx_destroy is called.
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 * @param[out] op_bson A BSON document for the MongoDB operation. The data
 * viewed by @p op_bson is guaranteed to be valid until @p ctx is destroyed with
 * @ref mongocrypt_ctx_destroy.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_ctx_mongo_op (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *op_bson);

/**
 * Feed a BSON reply or result when mongocrypt_ctx_t is in
 * MONGOCRYPT_CTX_NEED_MONGO_* states. This may be called multiple times
 * depending on the operation.
 *
 * reply is a BSON document result being fed back for this operation.
 * - For MONGOCRYPT_CTX_NEED_MONGO_COLLINFO it is a doc from a listCollections
 * cursor. (Note, if listCollections returned no result, do not call this
 * function.)
 * - For MONGOCRYPT_CTX_NEED_MONGO_KEYS it is a doc from a find cursor.
 *   (Note, if find returned no results, do not call this function. reply must
 * not
 *   be NULL.)
 * - For MONGOCRYPT_CTX_NEED_MONGO_MARKINGS it is a reply from mongocryptd.
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 * @param[in] reply A BSON document for the MongoDB operation. The viewed data
 * is copied. It is valid to destroy @p reply with @ref
 * mongocrypt_binary_destroy immediately after.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_ctx_mongo_feed (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *reply);

/**
 * Call when done feeding the reply (or replies) back to the context.
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_ctx_mongo_done (mongocrypt_ctx_t *ctx);

/**
 * Manages a single KMS HTTP request/response.
 */
typedef struct _mongocrypt_kms_ctx_t mongocrypt_kms_ctx_t;

/**
 * Get the next KMS handle.
 *
 * Multiple KMS handles may be retrieved at once. Drivers may do this to fan
 * out multiple concurrent KMS HTTP requests. Feeding multiple KMS requests
 * is thread-safe.
 *
 * If KMS handles are being handled synchronously, the driver can reuse the same
 * TLS socket to send HTTP requests and receive responses.
 *
 * @param[in] ctx A @ref mongocrypt_ctx_t.
 * @returns a new @ref mongocrypt_kms_ctx_t or NULL.
 */
mongocrypt_kms_ctx_t *
mongocrypt_ctx_next_kms_ctx (mongocrypt_ctx_t *ctx);

/**
 * Get the HTTP request message for a KMS handle.
 *
 * The lifetime of @p msg is tied to the lifetime of @p kms. It is valid
 * until @ref mongocrypt_ctx_kms_done is called.
 *
 * @param[in] kms A @ref mongocrypt_kms_ctx_t.
 * @param[out] msg The HTTP request to send to KMS. The data viewed by @p msg is
 * guaranteed to be valid until the call of @ref mongocrypt_ctx_kms_done of the
 * parent @ref mongocrypt_ctx_t.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_kms_ctx_status
 */
bool
mongocrypt_kms_ctx_message (mongocrypt_kms_ctx_t *kms,
                            mongocrypt_binary_t *msg);

/**
 * Get the hostname from which to connect over TLS.
 *
 * The storage for @p endpoint is not owned by the caller, but
 * is valid until calling @ref mongocrypt_ctx_kms_done.
 *
 * @param[in] kms A @ref mongocrypt_kms_ctx_t.
 * @param[out] endpoint The output hostname as a NULL terminated string. This
 * may include a port (e.g. "example.com:123"). If it does not, default to port
 * 443.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_kms_ctx_status
 */
bool
mongocrypt_kms_ctx_endpoint (mongocrypt_kms_ctx_t *kms, const char **endpoint);

/**
 * Indicates how many bytes to feed into @ref mongocrypt_kms_ctx_feed.
 *
 * @param[in] kms The @ref mongocrypt_kms_ctx_t.
 * @returns The number of requested bytes.
 */
uint32_t
mongocrypt_kms_ctx_bytes_needed (mongocrypt_kms_ctx_t *kms);

/**
 * Feed bytes from the HTTP response.
 *
 * Feeding more bytes than what has been returned in @ref
 * mongocrypt_kms_ctx_bytes_needed is an error.
 *
 * @param[in] kms The @ref mongocrypt_kms_ctx_t.
 * @param[in] bytes The bytes to feed. The viewed data is copied. It is valid to
 * destroy @p bytes with @ref mongocrypt_binary_destroy immediately after.
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_kms_ctx_status
 */
bool
mongocrypt_kms_ctx_feed (mongocrypt_kms_ctx_t *kms, mongocrypt_binary_t *bytes);

/**
 * Get the status associated with a @ref mongocrypt_kms_ctx_t object.
 *
 * @param[in] kms The @ref mongocrypt_kms_ctx_t object.
 * @param[out] status Receives the status.
 *
 * @returns A boolean indicating success. If false, an error status is set.
 */
bool
mongocrypt_kms_ctx_status (mongocrypt_kms_ctx_t *kms,
                           mongocrypt_status_t *status);

/**
 * Call when done handling all KMS contexts.
 *
 * @param[in] ctx The @ref mongocrypt_ctx_t object.
 *
 * @returns A boolean indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_ctx_kms_done (mongocrypt_ctx_t *ctx);

/**
 * Perform the final encryption or decryption.
 *
 * @param[in] ctx A @ref mongocrypt_ctx_t.
 * @param[out] out The final BSON. The data viewed by @p out is guaranteed
 * to be valid until @p ctx is destroyed with @ref mongocrypt_ctx_destroy.
 * The meaning of this BSON depends on the type of @p ctx.
 *
 * If @p ctx was initialized with @ref mongocrypt_ctx_encrypt_init, then
 * this BSON is the (possibly) encrypted command to send to the server.
 *
 * If @p ctx was initialized with @ref mongocrypt_ctx_decrypt_init, then
 * this BSON is the decrypted result to return to the user.
 *
 * If @p ctx was initialized with @ref mongocrypt_ctx_explicit_encrypt_init,
 * then this BSON has the form { "v": (BSON binary) } where the BSON binary
 * is the resulting encrypted value.
 *
 * If @p ctx was initialized with @ref mongocrypt_ctx_explicit_decrypt_init,
 * then this BSON has the form { "v": (BSON value) } where the BSON value
 * is the resulting decrypted value.
 *
 * If @p ctx was initialized with @ref mongocrypt_ctx_datakey_init, then
 * this BSON is the document containing the new data key to be inserted into
 * the key vault collection.
 *
 * @returns a bool indicating success. If false, an error status is set.
 * Retrieve it with @ref mongocrypt_ctx_status
 */
bool
mongocrypt_ctx_finalize (mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out);

/**
 * Destroy and free all memory associated with a @ref mongocrypt_ctx_t.
 *
 * @param[in] ctx A @ref mongocrypt_ctx_t.
 */
void
mongocrypt_ctx_destroy (mongocrypt_ctx_t *ctx);

/**
 * An crypto AES-256-CBC encrypt or decrypt function.
 *
 * Note, @p in is already padded. Encrypt with padding disabled.
 * @param[in] ctx An optional context object that may have been set when hooks
 * were enabled.
 * @param[in] key An encryption key (32 bytes for AES_256).
 * @param[in] iv An initialization vector (16 bytes for AES_256);
 * @param[in] in The input.
 * @param[out] out A preallocated byte array for the output. See @ref
 * mongocrypt_binary_data.
 * @param[out] bytes_written Set this to the number of bytes written to @p out.
 * @param[out] status An optional status to pass error messages. See @ref
 * mongocrypt_status_set.
 * @returns A boolean indicating success. If returning false, set @p status
 * with a message indiciating the error using @ref mongocrypt_status_ste.
 */
typedef bool (*mongocrypt_crypto_fn) (void *ctx,
                                      mongocrypt_binary_t *key,
                                      mongocrypt_binary_t *iv,
                                      mongocrypt_binary_t *in,
                                      mongocrypt_binary_t *out,
                                      uint32_t *bytes_written,
                                      mongocrypt_status_t *status);

/**
 * A crypto signature or HMAC function.
 *
 * Currently used in callbacks for HMAC SHA-512, HMAC SHA-256, and RSA SHA-256
 * signature.
 *
 * @param[in] ctx An optional context object that may have been set when hooks
 * were enabled.
 * @param[in] key An encryption key (32 bytes for HMAC_SHA512).
 * @param[in] in The input.
 * @param[out] out A preallocated byte array for the output. See @ref
 * mongocrypt_binary_data.
 * @param[out] status An optional status to pass error messages. See @ref
 * mongocrypt_status_set.
 * @returns A boolean indicating success. If returning false, set @p status
 * with a message indiciating the error using @ref mongocrypt_status_ste.
 */
typedef bool (*mongocrypt_hmac_fn) (void *ctx,
                                    mongocrypt_binary_t *key,
                                    mongocrypt_binary_t *in,
                                    mongocrypt_binary_t *out,
                                    mongocrypt_status_t *status);

/**
 * A crypto hash (SHA-256) function.
 *
 * @param[in] ctx An optional context object that may have been set when hooks
 * were enabled.
 * @param[in] in The input.
 * @param[out] out A preallocated byte array for the output. See @ref
 * mongocrypt_binary_data.
 * @param[out] status An optional status to pass error messages. See @ref
 * mongocrypt_status_set.
 * @returns A boolean indicating success. If returning false, set @p status
 * with a message indiciating the error using @ref mongocrypt_status_ste.
 */
typedef bool (*mongocrypt_hash_fn) (void *ctx,
                                    mongocrypt_binary_t *in,
                                    mongocrypt_binary_t *out,
                                    mongocrypt_status_t *status);

/**
 * A crypto secure random function.
 *
 * @param[in] ctx An optional context object that may have been set when hooks
 * were enabled.
 * @param[out] out A preallocated byte array for the output. See @ref
 * mongocrypt_binary_data.
 * @param[in] count The number of random bytes requested.
 * @param[out] status An optional status to pass error messages. See @ref
 * mongocrypt_status_set.
 * @returns A boolean indicating success. If returning false, set @p status
 * with a message indiciating the error using @ref mongocrypt_status_ste.
 */
typedef bool (*mongocrypt_random_fn) (void *ctx,
                                      mongocrypt_binary_t *out,
                                      uint32_t count,
                                      mongocrypt_status_t *status);

bool
mongocrypt_setopt_crypto_hooks (mongocrypt_t *crypt,
                                mongocrypt_crypto_fn aes_256_cbc_encrypt,
                                mongocrypt_crypto_fn aes_256_cbc_decrypt,
                                mongocrypt_random_fn random,
                                mongocrypt_hmac_fn hmac_sha_512,
                                mongocrypt_hmac_fn hmac_sha_256,
                                mongocrypt_hash_fn sha_256,
                                void *ctx);

bool
mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5 (
   mongocrypt_t *crypt,
   mongocrypt_hmac_fn sign_rsaes_pkcs1_v1_5,
   void *sign_ctx);
""")


if PY3:
    def _to_string(cdata):
        """Decode a cdata c-string to a Python str."""
        return ffi.string(cdata).decode()
else:
    def _to_string(cdata):
        """Decode a cdata c-string to a Python str."""
        return ffi.string(cdata)


def libmongocrypt_version():
    """Returns the version of libmongocrypt."""
    return _to_string(lib.mongocrypt_version(ffi.NULL))


# Use the PYMONGOCRYPT_LIB environment variable to load a custom libmongocrypt
# build without relying on platform specific library path environment
# variables, like LD_LIBRARY_PATH. For example:
# export PYMONGOCRYPT_LIB='/path/to/libmongocrypt.so'
# If the PYMONGOCRYPT_LIB is not set then load the embedded library and
# fallback to the relying on a system installed library.
_base = os.path.dirname(os.path.realpath(__file__))
if sys.platform == 'win32':
    _path = os.path.join(_base, 'mongocrypt.dll')
elif sys.platform == 'darwin':
    _path = os.path.join(_base, 'libmongocrypt.dylib')
else:
    _path = os.path.join(_base, 'libmongocrypt.so')


class _Library(object):
    """Helper class for delaying errors that would usually be raised at
    import time until the library is actually used."""
    def __init__(self, error):
        self._error = error

    def __getattr__(self, name):
        raise self._error


_PYMONGOCRYPT_LIB = os.environ.get('PYMONGOCRYPT_LIB')
try:
    if _PYMONGOCRYPT_LIB:
        lib = ffi.dlopen(_PYMONGOCRYPT_LIB)
    else:
        try:
            lib = ffi.dlopen(_path)
        except OSError as exc:
            # Fallback to libmongocrypt installed on the system.
            lib = ffi.dlopen('mongocrypt')
except OSError as exc:
    # dlopen raises OSError when the library cannot be found.
    # Delay the error until the library is actually used.
    lib = _Library(exc)
else:
    # Check the libmongocrypt version when the library is found.
    _limongocrypt_version = _parse_version(libmongocrypt_version())
    if _limongocrypt_version < _parse_version(_MIN_LIBMONGOCRYPT_VERSION):
        exc = RuntimeError(
            "Expected libmongocrypt version %s or greater, found %s" % (
                _MIN_LIBMONGOCRYPT_VERSION, libmongocrypt_version()))
        lib = _Library(exc)
libmongocrypt-1.3.0/bindings/python/pymongocrypt/compat.py000066400000000000000000000040311414105245100241230ustar00rootroot00000000000000# Copyright 2019-present MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Utility functions and definitions for Python compatibility."""

import base64
import sys

PY3 = sys.version_info[0] == 3

if PY3:
    from abc import ABC
    unicode_type = str
else:
    from abc import ABCMeta as _ABCMeta
    ABC = _ABCMeta('ABC', (object,), {})
    unicode_type = unicode


def str_to_bytes(string):
    """Convert a str (or unicode) to bytes."""
    if isinstance(string, bytes):
        return string
    return string.encode('utf-8')


def safe_bytearray_or_base64(data):
    """Convert the given value to a type that, when BSON-encoded can be safely
    passed to libmongocrypt functions that expect a BSON document containing
    BSON Binary data or a base64-encoded string.

    pymongo.bson encodes bytes to BSON string in Python 2, while the
    libmongocrypt API expects BSON Binary or a base64 encoded string.
    To avoid needing to import bson.Binary, we return a base64 encoded string
    when using Python 2.
    """
    # On Python 3 byte-arrays are encoded as BSON Binary and
    # base64 encoded strings can be passed as-is.
    if PY3:
        return data

    # On Python 2 unicode literals are assumed to contain base64-encoded
    # strings that can be passed to libmongocrypt as-is.
    if isinstance(data, unicode_type):
        return data

    # On Python 2, all other types are assumed to contain raw bytes.
    # To avoid importing bson.binary.Binary, we convert these to
    # base64 strings.
    return unicode_type(base64.b64encode(data))
libmongocrypt-1.3.0/bindings/python/pymongocrypt/crypto.py000066400000000000000000000117631414105245100241720ustar00rootroot00000000000000# Copyright 2019-present MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Internal crypto callbacks for libmongocrypt."""

import os
import traceback

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives.hashes import Hash, SHA256, SHA512
from cryptography.hazmat.primitives.hmac import HMAC
from cryptography.hazmat.primitives.serialization import load_der_private_key

from pymongocrypt.binary import _to_bytes, _write_bytes
from pymongocrypt.binding import ffi, lib
from pymongocrypt.compat import str_to_bytes


def _callback_error_handler(exception, exc_value, tb):
    """Set the mongocrypt_status_t on error."""
    # From cffi docs: "First check if traceback is not None (it is None e.g.
    # if the whole function ran successfully but there was an error converting
    # the value returned: this occurs after the call)."
    if tb is not None:
        status = tb.tb_frame.f_locals['status']
        msg = str_to_bytes(''.join(traceback.format_exception(
            exception, exc_value, tb)))
        lib.mongocrypt_status_set(
            status, lib.MONGOCRYPT_STATUS_ERROR_CLIENT, 1, msg, -1)

    return False


@ffi.callback(
    "bool(void *, mongocrypt_binary_t *, mongocrypt_binary_t *,"
    "     mongocrypt_binary_t *, mongocrypt_binary_t *, uint32_t *,"
    "     mongocrypt_status_t *)",
    onerror=_callback_error_handler)
def aes_256_cbc_encrypt(ctx, key, iv, input, output, bytes_written, status):
    # Note that libmongocrypt pads the input before calling this method.
    cipher = Cipher(algorithms.AES(_to_bytes(key)), modes.CBC(_to_bytes(iv)),
                    backend=default_backend())
    encryptor = cipher.encryptor()
    data = encryptor.update(_to_bytes(input)) + encryptor.finalize()
    _write_bytes(output, data)
    bytes_written[0] = len(data)
    return True


@ffi.callback(
    "bool(void *, mongocrypt_binary_t *, mongocrypt_binary_t *,"
    "     mongocrypt_binary_t *, mongocrypt_binary_t *, uint32_t *,"
    "     mongocrypt_status_t *)",
    onerror=_callback_error_handler)
def aes_256_cbc_decrypt(ctx, key, iv, input, output, bytes_written, status):
    # Note that libmongocrypt pads the input before calling this method.
    cipher = Cipher(algorithms.AES(_to_bytes(key)), modes.CBC(_to_bytes(iv)),
                    backend=default_backend())
    decryptor = cipher.decryptor()
    data = decryptor.update(_to_bytes(input)) + decryptor.finalize()
    _write_bytes(output, data)
    bytes_written[0] = len(data)
    return True


@ffi.callback(
    "bool(void *, mongocrypt_binary_t *, mongocrypt_binary_t *, "
    "     mongocrypt_binary_t *, mongocrypt_status_t *)",
    onerror=_callback_error_handler)
def hmac_sha_256(ctx, key, input, output, status):
    h = HMAC(_to_bytes(key), SHA256(), backend=default_backend())
    h.update(_to_bytes(input))
    data = h.finalize()
    _write_bytes(output, data)
    return True


@ffi.callback(
    "bool(void *, mongocrypt_binary_t *, mongocrypt_binary_t *, "
    "     mongocrypt_binary_t *, mongocrypt_status_t *)",
    onerror=_callback_error_handler)
def hmac_sha_512(ctx, key, input, output, status):
    h = HMAC(_to_bytes(key), SHA512(), backend=default_backend())
    h.update(_to_bytes(input))
    data = h.finalize()
    _write_bytes(output, data)
    return True


@ffi.callback(
    "bool(void *, mongocrypt_binary_t *, mongocrypt_binary_t *, "
    "     mongocrypt_status_t *)",
    onerror=_callback_error_handler)
def sha_256(ctx, input, output, status):
    digest = Hash(SHA256(), backend=default_backend())
    digest.update(_to_bytes(input))
    data = digest.finalize()
    _write_bytes(output, data)
    return True


@ffi.callback(
    "bool(void *, mongocrypt_binary_t *, uint32_t, mongocrypt_status_t *)",
    onerror=_callback_error_handler)
def secure_random(ctx, output, count, status):
    data = os.urandom(int(count))
    _write_bytes(output, data)
    return True


@ffi.callback(
    "bool(void *, mongocrypt_binary_t *, mongocrypt_binary_t *, "
    "     mongocrypt_binary_t *, mongocrypt_status_t *)",
    onerror=_callback_error_handler)
def sign_rsaes_pkcs1_v1_5(ctx, key, input, output, status):
    rsa_private_key = load_der_private_key(
        _to_bytes(key), password=None, backend=default_backend())
    signature = rsa_private_key.sign(
        _to_bytes(input), padding=padding.PKCS1v15(), algorithm=SHA256())
    _write_bytes(output, signature)
    return True
libmongocrypt-1.3.0/bindings/python/pymongocrypt/errors.py000066400000000000000000000025611414105245100241620ustar00rootroot00000000000000# Copyright 2019-present MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from pymongocrypt.binding import ffi, lib, _to_string


class MongoCryptError(Exception):
    def __init__(self, msg, code=-1):
        """Top level Exception for all MongoCrypt errors.

        :Parameters:
          - `msg`: An error message.
          - `code`: The mongocrypt_status_t code.
        """
        super(MongoCryptError, self).__init__(msg)
        self.code = code

    @classmethod
    def from_status(cls, status):
        """Constructs an error from a mongocrypt_status_t.

        :Parameters:
          - `status`: A CFFI mongocrypt_status_t.
        """
        if lib.mongocrypt_status_ok(status):
            raise ValueError("status must not be ok")
        msg = _to_string(lib.mongocrypt_status_message(status, ffi.NULL))
        return cls(msg, lib.mongocrypt_status_code(status))
libmongocrypt-1.3.0/bindings/python/pymongocrypt/explicit_encrypter.py000066400000000000000000000166251414105245100265700ustar00rootroot00000000000000# Copyright 2019-present MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from pymongocrypt.mongocrypt import MongoCrypt
from pymongocrypt.state_machine import run_state_machine


class ExplicitEncryptOpts(object):
    def __init__(self, algorithm, key_id=None, key_alt_name=None):
        """Options for explicit encryption.

        :Parameters:
          - `algorithm`: The algorithm to use.
          - `key_id`: The data key _id.
          - `key_alt_name` (bytes): Identifies a key vault document by
            'keyAltName'. Must be BSON encoded document in the form:
            { "keyAltName" : (BSON UTF8 value) }
        """
        self.algorithm = algorithm
        self.key_id = key_id
        self.key_alt_name = key_alt_name


class DataKeyOpts(object):
    def __init__(self, master_key=None, key_alt_names=None):
        """Options for creating encryption keys.

        :Parameters:
          - `master_key`: Identifies a KMS-specific key used to encrypt the
            new data key. If the kmsProvider is "local" the `master_key` is
            not applicable and may be omitted.

            If the `kms_provider` is "aws" it is required and has the
            following fields::

              - `region` (string): Required. The AWS region, e.g. "us-east-1".
              - `key` (string): Required. The Amazon Resource Name (ARN) to
                 the AWS customer.
              - `endpoint` (string): Optional. An alternate host to send KMS
                requests to. May include port number, e.g.
                "kms.us-east-1.amazonaws.com:443".

            If the `kms_provider` is "azure" it is required and has the
            following fields::

              - `keyVaultEndpoint` (string): Required. Host with optional
                 port, e.g. "example.vault.azure.net".
              - `keyName` (string): Required. Key name in the key vault.
              - `keyVersion` (string): Optional. Version of the key to use.

            If the `kms_provider` is "gcp" it is required and has the
            following fields::

              - `projectId` (string): Required. The Google cloud project ID.
              - `location` (string): Required. The GCP location, e.g. "us-east1".
              - `keyRing` (string): Required. Name of the key ring that contains
                the key to use.
              - `keyName` (string): Required. Name of the key to use.
              - `keyVersion` (string): Optional. Version of the key to use.
              - `endpoint` (string): Optional. Host with optional port.
                Defaults to "cloudkms.googleapis.com".

          - `key_alt_names`: An optional list of bytes suitable to be passed to
            mongocrypt_ctx_setopt_key_alt_name. Each element must be BSON
            encoded document in the form: { "keyAltName" : (BSON UTF8 value) }
        """
        self.master_key = master_key
        self.key_alt_names = key_alt_names


class ExplicitEncrypter(object):
    def __init__(self, callback, mongo_crypt_opts):
        """Encrypts and decrypts BSON values.

        This class is used by a driver to support explicit encryption and
        decryption of individual fields in a BSON document.

        :Parameters:
          - `callback`: A :class:`MongoCryptCallback`.
          - `mongo_crypt_opts`: A :class:`MongoCryptOptions`.
        """
        self.callback = callback
        if mongo_crypt_opts.schema_map is not None:
            raise ValueError("mongo_crypt_opts.schema_map must be None")
        self.mongocrypt = MongoCrypt(mongo_crypt_opts, callback)

    def create_data_key(self, kms_provider, master_key=None,
                        key_alt_names=None):
        """Creates a data key used for explicit encryption.

        :Parameters:
          - `kms_provider`: The KMS provider to use. Supported values are
            "aws" and "local".
          - `master_key`: Identifies a KMS-specific key used to encrypt the
            new data key. If the kmsProvider is "local" the `master_key` is
            not applicable and may be omitted. If the `kms_provider` is "aws"
            it is required and has the following fields::

              - `region` (string): Required. The AWS region, e.g. "us-east-1".
              - `key` (string): Required. The Amazon Resource Name (ARN) to
                 the AWS customer.
              - `endpoint` (string): Optional. An alternate host to send KMS
                requests to. May include port number, e.g.
                "kms.us-east-1.amazonaws.com:443".

          - `key_alt_names` (optional): An optional list of string alternate
            names used to reference a key. If a key is created with alternate
            names, then encryption may refer to the key by the unique
            alternate name instead of by ``_id``.

        :Returns:
          The _id of the created data key document.
        """
        # CDRIVER-3275 each key_alt_name needs to be wrapped in a bson
        # document.
        encoded_names = []
        if key_alt_names is not None:
            for name in key_alt_names:
                encoded_names.append(
                    self.callback.bson_encode({'keyAltName': name}))

        opts = DataKeyOpts(master_key, encoded_names)
        with self.mongocrypt.data_key_context(kms_provider, opts) as ctx:
            key = run_state_machine(ctx, self.callback)
        return self.callback.insert_data_key(key)

    def encrypt(self, value, algorithm, key_id=None, key_alt_name=None):
        """Encrypts a BSON value.

        Note that exactly one of ``key_id`` or  ``key_alt_name`` must be
        provided.

        :Parameters:
          - `value` (bytes): The BSON value to encrypt.
          - `algorithm` (string): The encryption algorithm to use. See
            :class:`Algorithm` for some valid options.
          - `key_id` (bytes): The bytes of the binary subtype 4 ``_id`` data
            key. For example, ``uuid.bytes`` or ``bytes(bson_binary)``.
          - `key_alt_name` (string): Identifies a key vault document by
            'keyAltName'.

        :Returns:
          The encrypted BSON value.
        """
        # CDRIVER-3275 key_alt_name needs to be wrapped in a bson document.
        if key_alt_name is not None:
            key_alt_name = self.callback.bson_encode(
                {'keyAltName': key_alt_name})
        opts = ExplicitEncryptOpts(algorithm, key_id, key_alt_name)
        with self.mongocrypt.explicit_encryption_context(value, opts) as ctx:
            return run_state_machine(ctx, self.callback)

    def decrypt(self, value):
        """Decrypts a BSON value.

        :Parameters:
          - `value`: The encoded document to decrypt, which must be in the
            form { "v" : encrypted BSON value }}.

        :Returns:
          The decrypted BSON value.
        """
        with self.mongocrypt.explicit_decryption_context(value) as ctx:
            return run_state_machine(ctx, self.callback)

    def close(self):
        """Cleanup resources."""
        self.mongocrypt.close()
libmongocrypt-1.3.0/bindings/python/pymongocrypt/mongocrypt.py000066400000000000000000000556111414105245100250530ustar00rootroot00000000000000# Copyright 2019-present MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import base64
import copy

from pymongocrypt.binary import (MongoCryptBinaryIn,
                                 MongoCryptBinaryOut)
from pymongocrypt.binding import ffi, lib, _to_string
from pymongocrypt.compat import (safe_bytearray_or_base64, str_to_bytes,
                                 unicode_type)
from pymongocrypt.errors import MongoCryptError
from pymongocrypt.state_machine import MongoCryptCallback

from pymongocrypt.crypto import (aes_256_cbc_encrypt,
                                 aes_256_cbc_decrypt,
                                 hmac_sha_256,
                                 hmac_sha_512,
                                 sha_256,
                                 secure_random,
                                 sign_rsaes_pkcs1_v1_5)


class MongoCryptOptions(object):
    def __init__(self, kms_providers, schema_map=None):
        """Options for :class:`MongoCrypt`.

        :Parameters:
          - `kms_providers`: Map of KMS provider options. Two KMS providers
            are supported: "aws" and "local". The kms_providers map values
            differ by provider:
              - `aws`: Map with "accessKeyId" and "secretAccessKey" as strings,
                 and optionally a "sessionToken" for temporary credentials.
              - `azure`: Map with "clientId" and "clientSecret" as strings.
              - `gcp`: Map with "email" as a string and "privateKey" as
                a byte array or a base64-encoded string. On Python 2,
                base64-encoded strings must be passed as unicode literals.
              - `local`: Map with "key" as a 96-byte array or the equivalent
                base64-encoded string. On Python 2, base64-encoded strings
                must be passed as unicode literals.
          - `schema_map`: Optional map of collection namespace ("db.coll") to
            JSON Schema.  By default, a collection's JSONSchema is periodically
            polled with the listCollections command. But a JSONSchema may be
            specified locally with the schemaMap option.

            Supplying a `schema_map` provides more security than relying on
            JSON Schemas obtained from the server. It protects against a
            malicious server advertising a false JSON Schema, which could trick
            the client into sending unencrypted data that should be encrypted.

            Schemas supplied in the schemaMap only apply to configuring
            automatic encryption for client side encryption. Other validation
            rules in the JSON schema will not be enforced by the driver and
            will result in an error.

        .. versionadded:: 1.1
           Support for "azure" and "gcp" kms_providers.
           Support for temporary AWS credentials via "sessionToken".

        .. versionchanged:: 1.1
           For kmsProvider "local", the "key" field can now be specified
           as either a 96-byte array or the equivalent base64-encoded string.
        """
        if not isinstance(kms_providers, dict):
            raise ValueError('kms_providers must be a dict')
        if not kms_providers:
            raise ValueError('at least one KMS provider must be configured')

        if 'aws' in kms_providers:
            aws = kms_providers["aws"]
            if not isinstance(aws, dict):
                raise ValueError("kms_providers['aws'] must be a dict")
            if "accessKeyId" not in aws or "secretAccessKey" not in aws:
                raise ValueError("kms_providers['aws'] must contain "
                                 "'accessKeyId' and 'secretAccessKey'")

        if 'azure' in kms_providers:
            azure = kms_providers["azure"]
            if not isinstance(azure, dict):
                raise ValueError("kms_providers['azure'] must be a dict")
            if 'clientId' not in azure or 'clientSecret' not in azure:
                raise ValueError("kms_providers['azure'] must contain "
                                 "'clientId' and 'clientSecret'")

        if 'gcp' in kms_providers:
            gcp = kms_providers['gcp']
            if not isinstance(gcp, dict):
                raise ValueError("kms_providers['gcp'] must be a dict")
            if 'email' not in gcp or 'privateKey' not in gcp:
                raise ValueError("kms_providers['gcp'] must contain "
                                 "'email' and 'privateKey'")
            if not isinstance(kms_providers['gcp']['privateKey'],
                              (bytes, unicode_type)):
                raise TypeError("kms_providers['gcp']['privateKey'] must "
                                "be an instance of bytes or str "
                                "(unicode in Python 2)")

        if 'local' in kms_providers:
            local = kms_providers['local']
            if not isinstance(local, dict):
                raise ValueError("kms_providers['local'] must be a dict")
            if 'key' not in local:
                raise ValueError("kms_providers['local'] must contain 'key'")
            if not isinstance(kms_providers['local']['key'],
                              (bytes, unicode_type)):
                raise TypeError("kms_providers['local']['key'] must be an "
                                "instance of bytes or str (unicode in "
                                "Python 2)")

        if schema_map is not None and not isinstance(schema_map, bytes):
            raise TypeError("schema_map must be bytes or None")

        self.kms_providers = kms_providers
        self.schema_map = schema_map


class MongoCrypt(object):
    def __init__(self, options, callback):
        """Abstracts libmongocrypt's mongocrypt_t type.

        :Parameters:
          - `options`: A :class:`MongoCryptOptions`.
          - `callback`: A :class:`MongoCryptCallback`.
        """
        self.__opts = options
        self.__callback = callback
        self.__crypt = None

        if not isinstance(options, MongoCryptOptions):
            raise TypeError("options must be a MongoCryptOptions")

        if not isinstance(callback, MongoCryptCallback):
            raise TypeError("callback must be a MongoCryptCallback")

        self.__crypt = lib.mongocrypt_new()
        if self.__crypt == ffi.NULL:
            raise MongoCryptError("unable to create new mongocrypt object")

        try:
            self.__init()
        except Exception:
            # Destroy the mongocrypt object on error.
            self.close()
            raise

    def __init(self):
        """Internal init helper."""
        kms_providers = self.__opts.kms_providers

        # Make fields that can be passed as binary or string safe to
        # encode to BSON.
        base64_or_bytes_fields = [("local", "key"), ("gcp", "privateKey")]
        for f1, f2 in base64_or_bytes_fields:
            value = kms_providers.get(f1, {}).get(f2, None)
            if value is not None:
                safe_value = safe_bytearray_or_base64(value)
                if value != safe_value:
                    kms_providers = copy.deepcopy(kms_providers)
                    kms_providers[f1][f2] = safe_value
        with MongoCryptBinaryIn(
                self.__callback.bson_encode(kms_providers)) as kmsopt:
            if not lib.mongocrypt_setopt_kms_providers(
                    self.__crypt, kmsopt.bin):
                self.__raise_from_status()

        schema_map = self.__opts.schema_map
        if schema_map is not None:
            with MongoCryptBinaryIn(schema_map) as binary_schema_map:
                if not lib.mongocrypt_setopt_schema_map(
                        self.__crypt, binary_schema_map.bin):
                    self.__raise_from_status()

        if not lib.mongocrypt_setopt_crypto_hooks(
                self.__crypt, aes_256_cbc_encrypt, aes_256_cbc_decrypt,
                secure_random, hmac_sha_512, hmac_sha_256, sha_256, ffi.NULL):
            self.__raise_from_status()

        if not lib.mongocrypt_setopt_crypto_hook_sign_rsaes_pkcs1_v1_5(
                self.__crypt, sign_rsaes_pkcs1_v1_5, ffi.NULL):
            self.__raise_from_status()

        if not lib.mongocrypt_init(self.__crypt):
            self.__raise_from_status()

    def __raise_from_status(self):
        status = lib.mongocrypt_status_new()
        try:
            lib.mongocrypt_status(self.__crypt, status)
            exc = MongoCryptError.from_status(status)
        finally:
            lib.mongocrypt_status_destroy(status)
        raise exc

    def close(self):
        """Cleanup resources."""
        if self.__crypt is None:
            return
        lib.mongocrypt_destroy(self.__crypt)
        self.__crypt = None

    def __del__(self):
        self.close()

    def _create_context(self):
        """Returns a new mongocrypt_ctx_t"""
        ctx = lib.mongocrypt_ctx_new(self.__crypt)
        if ctx == ffi.NULL:
            self.__raise_from_status()
        return ctx

    def encryption_context(self, database, command):
        """Creates a context to use for encryption.

        :Parameters:
          - `database`: The database name.
          - `command`: The encoded BSON command to encrypt.

        :Returns:
          A :class:`EncryptionContext`.
        """
        return EncryptionContext(self._create_context(), database, command)

    def decryption_context(self, command):
        """Creates a context to use for decryption.

        :Parameters:
          - `command`: The encoded BSON command to decrypt.

        :Returns:
          A :class:`DecryptionContext`.
        """
        return DecryptionContext(self._create_context(), command)

    def explicit_encryption_context(self, value, opts):
        """Creates a context to use for explicit encryption.

        :Parameters:
          - `value`: The encoded document to encrypt, which must be in the
            form { "v" : BSON value to encrypt }}.
          - `opts`: A :class:`ExplicitEncryptOpts`.

        :Returns:
          A :class:`ExplicitEncryptionContext`.
        """
        return ExplicitEncryptionContext(self._create_context(), value, opts)

    def explicit_decryption_context(self, value):
        """Creates a context to use for explicit decryption.

        :Parameters:
          - `value`: The encoded document to decrypt, which must be in the
            form { "v" : encrypted BSON value }}.

        :Returns:
          A :class:`ExplicitDecryptionContext`.
        """
        return ExplicitDecryptionContext(self._create_context(), value)

    def data_key_context(self, kms_provider, opts=None):
        """Creates a context to use for key generation.

        :Parameters:
          - `kms_provider`: The KMS provider.
          - `opts`: An optional class:`DataKeyOpts`.

        :Returns:
          A :class:`DataKeyContext`.
        """
        return DataKeyContext(self._create_context(), kms_provider, opts,
                              self.__callback)


class MongoCryptContext(object):
    __slots__ = ("__ctx",)

    def __init__(self, ctx):
        """Abstracts libmongocrypt's mongocrypt_ctx_t type.

        :Parameters:
          - `ctx`: A mongocrypt_ctx_t. This MongoCryptContext takes ownership
            of the underlying mongocrypt_ctx_t.
          - `database`: Optional, the name of the database.
        """
        self.__ctx = ctx

    def _close(self):
        """Cleanup resources."""
        if self.__ctx is None:
            return
        lib.mongocrypt_ctx_destroy(self.__ctx)
        self.__ctx = None

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._close()

    @property
    def state(self):
        """The current state of the mongocrypt_ctx_t."""
        return lib.mongocrypt_ctx_state(self.__ctx)

    def _raise_from_status(self):
        status = lib.mongocrypt_status_new()
        try:
            lib.mongocrypt_ctx_status(self.__ctx, status)
            exc = MongoCryptError.from_status(status)
        finally:
            lib.mongocrypt_status_destroy(status)
        raise exc

    def mongo_operation(self):
        """Returns the mongo operation to execute as bson bytes."""
        with MongoCryptBinaryOut() as binary:
            if not lib.mongocrypt_ctx_mongo_op(self.__ctx, binary.bin):
                self._raise_from_status()
            return binary.to_bytes()

    def add_mongo_operation_result(self, document):
        """Adds the mongo operation's command response.

        :Parameters:
          - `document`: A raw BSON command response document.
        """
        with MongoCryptBinaryIn(document) as binary:
            if not lib.mongocrypt_ctx_mongo_feed(self.__ctx, binary.bin):
                self._raise_from_status()

    def complete_mongo_operation(self):
        """Completes the mongo operation."""
        if not lib.mongocrypt_ctx_mongo_done(self.__ctx):
            self._raise_from_status()

    def kms_contexts(self):
        """Yields the MongoCryptKmsContexts."""
        ctx = lib.mongocrypt_ctx_next_kms_ctx(self.__ctx)
        while ctx != ffi.NULL:
            yield MongoCryptKmsContext(ctx)
            ctx = lib.mongocrypt_ctx_next_kms_ctx(self.__ctx)

    def complete_kms(self):
        """Indicates that all MongoCryptKmsContexts have been completed"""
        if not lib.mongocrypt_ctx_kms_done(self.__ctx):
            self._raise_from_status()

    def finish(self):
        """Returns the finished mongo operation as bson bytes."""
        with MongoCryptBinaryOut() as binary:
            if not lib.mongocrypt_ctx_finalize(self.__ctx, binary.bin):
                self._raise_from_status()
            return binary.to_bytes()


class EncryptionContext(MongoCryptContext):
    __slots__ = ("database",)

    def __init__(self, ctx, database, command):
        """Abstracts libmongocrypt's mongocrypt_ctx_t type.

        :Parameters:
          - `ctx`: A mongocrypt_ctx_t. This MongoCryptContext takes ownership
            of the underlying mongocrypt_ctx_t.
          - `database`: Optional, the name of the database.
          - `command`: The BSON command to encrypt.
        """
        super(EncryptionContext, self).__init__(ctx)
        self.database = database
        try:
            with MongoCryptBinaryIn(command) as binary:
                database = str_to_bytes(database)
                if not lib.mongocrypt_ctx_encrypt_init(
                       ctx, database, len(database), binary.bin):
                    self._raise_from_status()
        except Exception:
            # Destroy the context on error.
            self._close()
            raise


class DecryptionContext(MongoCryptContext):
    __slots__ = ()

    def __init__(self, ctx, command):
        """Abstracts libmongocrypt's mongocrypt_ctx_t type.

        :Parameters:
          - `ctx`: A mongocrypt_ctx_t. This MongoCryptContext takes ownership
            of the underlying mongocrypt_ctx_t.
          - `command`: The encoded BSON command to decrypt.
        """
        super(DecryptionContext, self).__init__(ctx)
        try:
            with MongoCryptBinaryIn(command) as binary:
                if not lib.mongocrypt_ctx_decrypt_init(ctx, binary.bin):
                    self._raise_from_status()
        except Exception:
            # Destroy the context on error.
            self._close()
            raise


class ExplicitEncryptionContext(MongoCryptContext):
    __slots__ = ()

    def __init__(self, ctx, value, opts):
        """Abstracts libmongocrypt's mongocrypt_ctx_t type.

        :Parameters:
          - `ctx`: A mongocrypt_ctx_t. This MongoCryptContext takes ownership
            of the underlying mongocrypt_ctx_t.
          - `value`:  The encoded document to encrypt, which must be in the
            form { "v" : BSON value to encrypt }}.
          - `opts`: A :class:`ExplicitEncryptOpts`.
        """
        super(ExplicitEncryptionContext, self).__init__(ctx)
        try:
            algorithm = str_to_bytes(opts.algorithm)
            if not lib.mongocrypt_ctx_setopt_algorithm(ctx, algorithm, -1):
                self._raise_from_status()

            if opts.key_id is not None:
                with MongoCryptBinaryIn(opts.key_id) as binary:
                    if not lib.mongocrypt_ctx_setopt_key_id(ctx, binary.bin):
                        self._raise_from_status()

            if opts.key_alt_name is not None:
                with MongoCryptBinaryIn(opts.key_alt_name) as binary:
                    if not lib.mongocrypt_ctx_setopt_key_alt_name(ctx,
                                                                  binary.bin):
                        self._raise_from_status()

            with MongoCryptBinaryIn(value) as binary:
                if not lib.mongocrypt_ctx_explicit_encrypt_init(ctx,
                                                                binary.bin):
                    self._raise_from_status()
        except Exception:
            # Destroy the context on error.
            self._close()
            raise


class ExplicitDecryptionContext(MongoCryptContext):
    __slots__ = ()

    def __init__(self, ctx, value):
        """Abstracts libmongocrypt's mongocrypt_ctx_t type.

        :Parameters:
          - `ctx`: A mongocrypt_ctx_t. This MongoCryptContext takes ownership
            of the underlying mongocrypt_ctx_t.
          - `value`: The encoded BSON value to decrypt.
        """
        super(ExplicitDecryptionContext, self).__init__(ctx)

        try:
            with MongoCryptBinaryIn(value) as binary:
                if not lib.mongocrypt_ctx_explicit_decrypt_init(ctx,
                                                                binary.bin):
                    self._raise_from_status()
        except Exception:
            # Destroy the context on error.
            self._close()
            raise


class DataKeyContext(MongoCryptContext):
    __slots__ = ()

    def __init__(self, ctx, kms_provider, opts, callback):
        """Abstracts libmongocrypt's mongocrypt_ctx_t type.

        :Parameters:
          - `ctx`: A mongocrypt_ctx_t. This MongoCryptContext takes ownership
            of the underlying mongocrypt_ctx_t.
          - `kms_provider`: The KMS provider.
          - `opts`: An optional class:`DataKeyOpts`.
          - `callback`: A :class:`MongoCryptCallback`.
        """
        super(DataKeyContext, self).__init__(ctx)
        try:
            if kms_provider not in ['aws', 'gcp', 'azure', 'local']:
                raise ValueError('unknown kms_provider: %s' % (kms_provider,))

            if opts is None or opts.master_key is None:
                if kms_provider == 'local':
                    master_key = {}
                else:
                    raise ValueError(
                        'master_key is required for kms_provider: "%s"' % (
                            kms_provider,))
            else:
                master_key = opts.master_key.copy()

            if kms_provider == 'aws':
                if ('region' not in opts.master_key or
                        'key' not in opts.master_key):
                    raise ValueError(
                        'master_key must include "region" and "key" for '
                        'kms_provider: "aws"')
            elif kms_provider == 'azure':
                if ('keyName' not in opts.master_key or
                        'keyVaultEndpoint' not in opts.master_key):
                    raise ValueError(
                        'master key must include "keyName" and '
                        '"keyVaultEndpoint" for kms_provider: "azure"')
            elif kms_provider == 'gcp':
                if ('projectId' not in opts.master_key or
                        'location' not in opts.master_key or
                        'keyRing' not in opts.master_key or
                        'keyName' not in opts.master_key):
                    raise ValueError(
                        'master key must include "projectId", "location",'
                        '"keyRing", and "keyName" for kms_provider: "gcp"')

            master_key['provider'] = kms_provider
            with MongoCryptBinaryIn(
                    callback.bson_encode(master_key)) as mkey:
                if not lib.mongocrypt_ctx_setopt_key_encryption_key(
                        ctx, mkey.bin):
                    self._raise_from_status()

            if opts.key_alt_names:
                for key_alt_name in opts.key_alt_names:
                    with MongoCryptBinaryIn(key_alt_name) as binary:
                        if not lib.mongocrypt_ctx_setopt_key_alt_name(
                                ctx, binary.bin):
                            self._raise_from_status()

            if not lib.mongocrypt_ctx_datakey_init(ctx):
                self._raise_from_status()
        except Exception:
            # Destroy the context on error.
            self._close()
            raise


class MongoCryptKmsContext(object):
    __slots__ = ("__ctx",)

    def __init__(self, ctx):
        """Abstracts libmongocrypt's mongocrypt_kms_ctx_t type.

        :Parameters:
          - `ctx`: A mongocrypt_kms_ctx_t.
        """
        self.__ctx = ctx

    def _close(self):
        """Clear the mongocrypt_kms_ctx_t."""
        self.__ctx = None

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self._close()

    @property
    def endpoint(self):
        """The kms hostname to connect over TLS."""
        p = ffi.new("char *[]", 1)
        try:
            if not lib.mongocrypt_kms_ctx_endpoint(self.__ctx, p):
                self.__raise_from_status()
            return _to_string(p[0])
        finally:
            ffi.release(p)

    @property
    def message(self):
        """The HTTP request message to send to the given endpoint."""
        with MongoCryptBinaryOut() as binary:
            if not lib.mongocrypt_kms_ctx_message(self.__ctx, binary.bin):
                self.__raise_from_status()
            return binary.to_bytes()

    @property
    def bytes_needed(self):
        """Indicates how many bytes to send to :meth:`feed`."""
        return lib.mongocrypt_kms_ctx_bytes_needed(self.__ctx)

    def feed(self, data):
        """Feed bytes from the HTTP response.

        :Parameters:
          - `data`: The bytes of the HTTP response. Must not exceed
            :attr:`bytes_needed`.
        """
        with MongoCryptBinaryIn(data) as binary:
            if not lib.mongocrypt_kms_ctx_feed(self.__ctx, binary.bin):
                self.__raise_from_status()

    def __raise_from_status(self):
        status = lib.mongocrypt_status_new()
        try:
            lib.mongocrypt_kms_ctx_status(self.__ctx, status)
            exc = MongoCryptError.from_status(status)
        finally:
            lib.mongocrypt_status_destroy(status)
        raise exc
libmongocrypt-1.3.0/bindings/python/pymongocrypt/state_machine.py000066400000000000000000000110761414105245100254530ustar00rootroot00000000000000# Copyright 2019-present MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from abc import abstractmethod

from pymongocrypt.binding import lib
from pymongocrypt.compat import ABC
from pymongocrypt.errors import MongoCryptError


class MongoCryptCallback(ABC):
    """Callback ABC to perform I/O on behalf of libbmongocrypt."""

    @abstractmethod
    def kms_request(self, kms_context):
        """Complete a KMS request.

        :Parameters:
          - `kms_context`: A :class:`MongoCryptKmsContext`.

        :Returns:
          None
        """
        pass

    @abstractmethod
    def collection_info(self, database, filter):
        """Get the collection info for a namespace.

        The returned collection info is passed to libmongocrypt which reads
        the JSON schema.

        :Parameters:
          - `database`: The database on which to run listCollections.
          - `filter`: The filter to pass to listCollections.

        :Returns:
          The first document from the listCollections command response as BSON.
        """
        pass

    @abstractmethod
    def mark_command(self, database, cmd):
        """Mark a command for encryption.

        :Parameters:
          - `database`: The database on which to run this command.
          - `cmd`: The BSON command to run.

        :Returns:
          The marked command response from mongocryptd.
        """
        pass

    @abstractmethod
    def fetch_keys(self, filter):
        """Yields one or more keys from the key vault.

        :Parameters:
          - `filter`: The filter to pass to find.

        :Returns:
          A generator which yields the requested keys from the key vault.
        """
        pass

    @abstractmethod
    def insert_data_key(self, data_key):
        """Insert a data key into the key vault.

        :Parameters:
          - `data_key`: The data key document to insert.

        :Returns:
          The _id of the inserted data key document.
        """
        pass

    @abstractmethod
    def bson_encode(self, doc):
        """Encode a document to BSON.

        A document can be any mapping type (like :class:`dict`).

        :Parameters:
          - `doc`: mapping type representing a document

        :Returns:
          The encoded BSON bytes.
        """
        pass

    @abstractmethod
    def close(self):
        """Release resources."""
        pass


def run_state_machine(ctx, callback):
    """Run the libmongocrypt state machine until completion.

    :Parameters:
      - `ctx`: A :class:`MongoCryptContext`.
      - `callback`: A :class:`MongoCryptCallback`.

    :Returns:
      The completed libmongocrypt operation.
    """
    while True:
        state = ctx.state
        # Check for terminal states first.
        if state == lib.MONGOCRYPT_CTX_ERROR:
            ctx._raise_from_status()
        elif state == lib.MONGOCRYPT_CTX_READY:
            return ctx.finish()
        elif state == lib.MONGOCRYPT_CTX_DONE:
            return None

        if state == lib.MONGOCRYPT_CTX_NEED_MONGO_COLLINFO:
            list_colls_filter = ctx.mongo_operation()
            coll_info = callback.collection_info(
                ctx.database, list_colls_filter)
            if coll_info:
                ctx.add_mongo_operation_result(coll_info)
            ctx.complete_mongo_operation()
        elif state == lib.MONGOCRYPT_CTX_NEED_MONGO_MARKINGS:
            mongocryptd_cmd = ctx.mongo_operation()
            result = callback.mark_command(ctx.database, mongocryptd_cmd)
            ctx.add_mongo_operation_result(result)
            ctx.complete_mongo_operation()
        elif state == lib.MONGOCRYPT_CTX_NEED_MONGO_KEYS:
            key_filter = ctx.mongo_operation()
            for key in callback.fetch_keys(key_filter):
                ctx.add_mongo_operation_result(key)
            ctx.complete_mongo_operation()
        elif state == lib.MONGOCRYPT_CTX_NEED_KMS:
            for kms_ctx in ctx.kms_contexts():
                with kms_ctx:
                    callback.kms_request(kms_ctx)
            ctx.complete_kms()
        else:
            raise MongoCryptError('unknown state: %r' % (state,))
libmongocrypt-1.3.0/bindings/python/pymongocrypt/version.py000066400000000000000000000012071414105245100243270ustar00rootroot00000000000000# Copyright 2019-present MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

__version__ = '1.1.2.dev0'

_MIN_LIBMONGOCRYPT_VERSION = '1.2.0'
libmongocrypt-1.3.0/bindings/python/release.sh000077500000000000000000000065071414105245100215050ustar00rootroot00000000000000#!/bin/bash -ex

# This script should be run on macOS and Cygwin on Windows.
# On macOS it will create the following distributions:
# pymongocrypt-.tar.gz
# pymongocrypt--py2.py3-none-manylinux2010_x86_64.whl
# pymongocrypt--py2.py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.whl
# pymongocrypt--py2.py3-none-macosx_10_9_x86_64.whl
#
# On Windows it will create the following distribution:
# pymongocrypt--py2.py3-none-win_amd64.whl

set -o xtrace   # Write all commands first to stderr
set -o errexit  # Exit the script with error if any of the commands fail

# The libmongocrypt git revision release to embed in our wheels.
REVISION=$(git rev-list -n 1 1.2.1)

if [ "Windows_NT" = "$OS" ]; then # Magic variable in cygwin
    rm -rf venv37
    virtualenv -p C:\\python\\Python37\\python.exe venv37 && . ./venv37/Scripts/activate

    # Build the Windows wheel
    rm -rf build libmongocrypt pymongocrypt/*.so pymongocrypt/*.dll pymongocrypt/*.dylib
    curl -O https://s3.amazonaws.com/mciuploads/libmongocrypt/windows-test/master/${REVISION}/libmongocrypt.tar.gz
    mkdir libmongocrypt
    tar xzf libmongocrypt.tar.gz -C ./libmongocrypt
    NOCRYPTO_SO=libmongocrypt/nocrypto/bin/mongocrypt.dll
    chmod +x ${NOCRYPTO_SO}
    cp ${NOCRYPTO_SO} pymongocrypt/
    rm -rf ./libmongocrypt libmongocrypt.tar.gz

    python setup.py bdist_wheel
    rm -rf build libmongocrypt pymongocrypt/*.so pymongocrypt/*.dll pymongocrypt/*.dylib
    ls dist
elif [ "Darwin" = "$(uname -s)" ]; then
    # Build the source dist first
    rm -rf build pymongocrypt/*.so pymongocrypt/*.dll pymongocrypt/*.dylib
    python3.7 setup.py sdist

    # Build the manylinux2010 wheels
    rm -rf build libmongocrypt pymongocrypt/*.so pymongocrypt/*.dll pymongocrypt/*.dylib
    curl -O https://s3.amazonaws.com/mciuploads/libmongocrypt/rhel-62-64-bit/master/${REVISION}/libmongocrypt.tar.gz
    mkdir libmongocrypt
    tar xzf libmongocrypt.tar.gz -C ./libmongocrypt
    NOCRYPTO_SO=libmongocrypt/nocrypto/lib64/libmongocrypt.so
    chmod +x ${NOCRYPTO_SO}
    cp ${NOCRYPTO_SO} pymongocrypt/
    rm -rf ./libmongocrypt libmongocrypt.tar.gz

    # 2021-05-05-1ac6ef3 was the last release to generate pip < 20.3 compatible
    # wheels. After that auditwheel was upgraded to v4 which produces PEP 600
    # manylinux_x_y wheels which requires pip >= 20.3. We use the older docker
    # image to support older pip versions.
    images=(quay.io/pypa/manylinux2010_x86_64:2021-05-05-1ac6ef3 \
            quay.io/pypa/manylinux2010_x86_64)
    for image in "${images[@]}"; do
        docker pull $image
        docker run --rm -v `pwd`:/python $image /python/build-manylinux-wheel.sh
    done

    # Build the mac wheel
    rm -rf build libmongocrypt pymongocrypt/*.so pymongocrypt/*.dll pymongocrypt/*.dylib
    curl -O https://s3.amazonaws.com/mciuploads/libmongocrypt/macos/master/${REVISION}/libmongocrypt.tar.gz
    mkdir libmongocrypt
    tar xzf libmongocrypt.tar.gz -C ./libmongocrypt
    NOCRYPTO_SO=libmongocrypt/nocrypto/lib/libmongocrypt.dylib
    chmod +x ${NOCRYPTO_SO}
    cp ${NOCRYPTO_SO} pymongocrypt/
    rm -rf ./libmongocrypt libmongocrypt.tar.gz

    python3.7 setup.py bdist_wheel
    rm -rf build libmongocrypt pymongocrypt/*.so pymongocrypt/*.dll pymongocrypt/*.dylib
    ls dist
else
   echo "ERROR: Run this script on macOS or Windows"
   exit 1
fi
libmongocrypt-1.3.0/bindings/python/setup.py000066400000000000000000000063211414105245100212320ustar00rootroot00000000000000import os
import sys

from setuptools import setup, find_packages

# Make our Windows and macOS wheels platform specific because we embed
# libmongocrypt. On Linux we ship manylinux2010 wheels which cannot do this or
# else auditwheel raises the following error:
# RuntimeError: Invalid binary wheel, found the following shared
# library/libraries in purelib folder:
# 	libmongocrypt.so
# The wheel has to be platlib compliant in order to be repaired by auditwheel.
cmdclass = {}
if sys.platform in ('win32', 'darwin'):
    try:
        from wheel.bdist_wheel import bdist_wheel as _bdist_wheel
        class bdist_wheel(_bdist_wheel):

            def finalize_options(self):
                _bdist_wheel.finalize_options(self)
                self.root_is_pure = False

            def get_tag(self):
                python, abi, plat = _bdist_wheel.get_tag(self)
                # Our python source is py2/3 compatible.
                python, abi = 'py2.py3', 'none'
                return python, abi, plat

        cmdclass['bdist_wheel'] = bdist_wheel
    except ImportError:
        # Version of wheel is too old, use None to fail a bdist_wheel attempt.
        cmdclass['bdist_wheel'] = None

with open('README.rst', 'rb') as f:
    LONG_DESCRIPTION = f.read().decode('utf8')

# Single source the version.
version_file = os.path.realpath(os.path.join(
    os.path.dirname(__file__), 'pymongocrypt', 'version.py'))
version = {}
with open(version_file) as fp:
    exec(fp.read(), version)

setup(
    name="pymongocrypt",
    version=version['__version__'],
    description="Python bindings for libmongocrypt",
    long_description=LONG_DESCRIPTION,
    packages=find_packages(exclude=['test']),
    package_data={'pymongocrypt': ['*.dll', '*.so', '*.dylib']},
    zip_safe=False,
    # Note cryptography is uncapped because it does not follow semver.
    install_requires=["cffi>=1.12.0,<2", "cryptography>=2.0"],
    author="Shane Harvey",
    author_email="mongodb-user@googlegroups.com",
    url="https://github.com/mongodb/libmongocrypt/tree/master/bindings/python",
    keywords=["mongo", "mongodb", "pymongocrypt", "pymongo", "mongocrypt",
              "bson"],
    test_suite="test",
    tests_require=["pymongo"],
    license="Apache License, Version 2.0",
    python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*",
    classifiers=[
        "Development Status :: 5 - Production/Stable",
        "Intended Audience :: Developers",
        "License :: OSI Approved :: Apache Software License",
        "Operating System :: MacOS :: MacOS X",
        "Operating System :: Microsoft :: Windows",
        "Operating System :: POSIX",
        "Programming Language :: Python :: 2",
        "Programming Language :: Python :: 2.7",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.4",
        "Programming Language :: Python :: 3.5",
        "Programming Language :: Python :: 3.6",
        "Programming Language :: Python :: 3.7",
        "Programming Language :: Python :: 3.8",
        "Programming Language :: Python :: 3.9",
        "Programming Language :: Python :: Implementation :: CPython",
        "Programming Language :: Python :: Implementation :: PyPy",
        "Topic :: Database"],
    cmdclass=cmdclass,
)
libmongocrypt-1.3.0/bindings/python/strip_header.py000066400000000000000000000027071414105245100225470ustar00rootroot00000000000000# Copyright 2019-present MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Generate a CFFI.cdef() string from a C header file

Usage (on macOS):: python strip_header.py ../../src/mongocrypt.h.in | pbcopy
"""

import re
import sys

HEADER_RE = re.compile(r'^(#|MONGOCRYPT_EXPORT)')
BLANK_RE = re.compile(r'^\s*$')


def strip_file(fp, out):
    for line in fp:
        if not HEADER_RE.match(line):
            out.append(line)


def strip(hdr):
    out = []
    with open(hdr) as fp:
        strip_file(fp, out)

    # Strip consecutive blank lines
    last_blank = True
    new = []
    for line in out:
        if BLANK_RE.match(line):
            if last_blank:
                continue
            last_blank = True
        else:
            last_blank = False
        new.append(line)

    if new:
        print(''.join(new))


if __name__ == "__main__":
    if len(sys.argv) != 2:
        raise Exception("Usage: strip_header.py header.h")
    strip(sys.argv[1])
libmongocrypt-1.3.0/bindings/python/test-requirements.txt000066400000000000000000000006621414105245100237630ustar00rootroot00000000000000pymongo
# cffi==1.14.3 was the last installable release on RHEL 6.3 with Python 3.4
cffi==1.14.3;python_version=="3.4"
cffi>=1.12.0,<2;python_version!="3.4"
# We test PyPy on RHEL 6.2 which has OpenSSL 1.0.1e
# Pin to cryptography 2.8.* until we figure our how to
# install cryptography with PyPy with a newer OpenSSL.
cryptography>=2,<2.9;platform_python_implementation=='PyPy'
cryptography>=2;platform_python_implementation!='PyPy'
libmongocrypt-1.3.0/bindings/python/test/000077500000000000000000000000001414105245100204755ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/python/test/__init__.py000066400000000000000000000020461414105245100226100ustar00rootroot00000000000000# Copyright 2019-present MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import sys
import unittest

sys.path[0:0] = [""]

try:
    # Enable the fault handler to dump the traceback of each running thread
    # after a segfault.
    import faulthandler
    faulthandler.enable()
except ImportError:
    pass

# Use assertRaisesRegex if available, otherwise use Python 2.7's
# deprecated assertRaisesRegexp, with a 'p'.
if not hasattr(unittest.TestCase, 'assertRaisesRegex'):
    unittest.TestCase.assertRaisesRegex = unittest.TestCase.assertRaisesRegexp
libmongocrypt-1.3.0/bindings/python/test/data/000077500000000000000000000000001414105245100214065ustar00rootroot00000000000000libmongocrypt-1.3.0/bindings/python/test/data/collection-info.json000066400000000000000000000017241414105245100253710ustar00rootroot00000000000000{
    "type": "collection",
    "name": "test",
    "idIndex": {
        "ns": "test.test",
        "name": "_id_",
        "key": {
            "_id": {
                "$numberInt": "1"
            }
        },
        "v": {
            "$numberInt": "2"
        }
    },
    "options": {
        "validator": {
            "$jsonSchema": {
                "properties": {
                    "ssn": {
                        "encrypt": {
                            "keyId": {
                                "$binary": {
                                    "base64": "YWFhYWFhYWFhYWFhYWFhYQ==",
                                    "subType": "04"
                                }
                            },
                            "type": "string",
                            "algorithm": "AEAD_AES_CBC_HMAC_SHA512-Deterministic"
                        }
                    }
                },
                "bsonType": "object"
            }
        }
    }
}libmongocrypt-1.3.0/bindings/python/test/data/command-reply.json000066400000000000000000000002361414105245100250510ustar00rootroot00000000000000{
  "cursor": {
    "firstBatch": [
      {
        "_id": 1,
        "ssn": "457-55-5462"
      }
    ],
    "id": 0,
    "ns": "test.test"
  },
  "ok": 1
}
libmongocrypt-1.3.0/bindings/python/test/data/command.json000066400000000000000000000001121414105245100237110ustar00rootroot00000000000000{
    "find": "test",
    "filter": {
        "ssn": "457-55-5462"
    }
}libmongocrypt-1.3.0/bindings/python/test/data/encrypted-command-reply.json000066400000000000000000000005251414105245100270450ustar00rootroot00000000000000{
  "cursor" : {
    "firstBatch" : [
      {
        "_id": 1,
        "ssn": {
          "$binary": "AWFhYWFhYWFhYWFhYWFhYWECRTOW9yZzNDn5dGwuqsrJQNLtgMEKaujhs9aRWRp+7Yo3JK8N8jC8P0Xjll6C1CwLsE/iP5wjOMhVv1KMMyOCSCrHorXRsb2IKPtzl2lKTqQ=",
          "$type": "06"
        }
      }
    ],
    "id" : 0,
    "ns" : "test.test"
  },
  "ok" : 1
}libmongocrypt-1.3.0/bindings/python/test/data/encrypted-command.json000066400000000000000000000004101414105245100257050ustar00rootroot00000000000000{
  "filter": {
    "ssn": {
      "$binary": {
        "base64": "AWFhYWFhYWFhYWFhYWFhYWECRTOW9yZzNDn5dGwuqsrJQNLtgMEKaujhs9aRWRp+7Yo3JK8N8jC8P0Xjll6C1CwLsE/iP5wjOMhVv1KMMyOCSCrHorXRsb2IKPtzl2lKTqQ=",
        "subType": "06"
      }
    }
  },
  "find": "test"
}
libmongocrypt-1.3.0/bindings/python/test/data/encrypted-value.json000066400000000000000000000002461414105245100254120ustar00rootroot00000000000000{
  "v": {
    "$binary": "AWFhYWFhYWFhYWFhYWFhYWECW+zDjR/69eS6VtuMD5+O2lZw6JyiWOw3avI7mnUkdpKzPfvy8F/nlZrgZa2cGmQsb0TmLZuk5trldosnGKD91w==",
    "$type": "06"
  }
}
libmongocrypt-1.3.0/bindings/python/test/data/key-document.json000066400000000000000000000020251414105245100247040ustar00rootroot00000000000000{
    "status": {
        "$numberInt": "1"
    },
    "_id": {
        "$binary": {
            "base64": "YWFhYWFhYWFhYWFhYWFhYQ==",
            "subType": "04"
        }
    },
    "masterKey": {
        "region": "us-east-1",
        "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
        "provider": "aws"
    },
    "updateDate": {
        "$date": {
            "$numberLong": "1557827033449"
        }
    },
    "keyMaterial": {
        "$binary": {
            "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO",
            "subType": "00"
        }
    },
    "creationDate": {
        "$date": {
            "$numberLong": "1557827033449"
        }
    },
    "keyAltNames": ["name1", "name2"]
}libmongocrypt-1.3.0/bindings/python/test/data/key-filter.json000066400000000000000000000003631414105245100243560ustar00rootroot00000000000000{
  "$or": [
    {
      "_id": {
        "$in": [
          {
            "$binary": "YWFhYWFhYWFhYWFhYWFhYQ==",
            "$type": "04"
          }
        ]
      }
    },
    {
      "keyAltNames": {
        "$in": []
      }
    }
  ]
}libmongocrypt-1.3.0/bindings/python/test/data/kms-encrypt-reply.txt000066400000000000000000000011251414105245100255530ustar00rootroot00000000000000HTTP/1.1 200 OK
x-amzn-RequestId: deeb35e5-4ecb-4bf1-9af5-84a54ff0af0e
Content-Type: application/x-amz-json-1.1
Content-Length: 446
Connection: close

{"KeyId": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", "CiphertextBlob": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gHCPOT4UQIpMTvAVABLqnXlAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDLxAm0nO3rccdoWA6AIBEIB7HUe6+aPvgNu/4sLEXBQVDIJVBueI3q7zdOMBSkRKkgZWqEuQgA6iDuEZbhHhOVCUXPBaLX6QWRwyMmjvIy/2Bg5q+TmwnfRo6QKdw2vee1W32/FdPWIoQy1yKOoIhNy6XMWldS3JuWK8ffQOYkssEqx0V4LW6PKuFv7D"}libmongocrypt-1.3.0/bindings/python/test/data/kms-reply.txt000066400000000000000000000005561414105245100241000ustar00rootroot00000000000000HTTP/1.1 200 OK
x-amzn-RequestId: deeb35e5-4ecb-4bf1-9af5-84a54ff0af0e
Content-Type: application/x-amz-json-1.1
Content-Length: 233

{"KeyId": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", "Plaintext": "TqhXy3tKckECjy4/ZNykMWG8amBF46isVPzeOgeusKrwheBmYaU8TMG5AHR/NeUDKukqo8hBGgogiQOVpLPkqBQHD8YkLsNbDmHoGOill5QAHnniF/Lz405bGucB5TfR"}libmongocrypt-1.3.0/bindings/python/test/data/list-collections-filter.json000066400000000000000000000000241414105245100270470ustar00rootroot00000000000000{
  "name": "test"
}libmongocrypt-1.3.0/bindings/python/test/data/mongocryptd-command.json000066400000000000000000000006461414105245100262700ustar00rootroot00000000000000{
  "find": "test",
  "filter": {
    "ssn": "457-55-5462"
  },
  "jsonSchema": {
    "properties": {
      "ssn": {
        "encrypt": {
          "keyId": {
            "$binary": "YWFhYWFhYWFhYWFhYWFhYQ==",
            "$type": "04"
          },
          "type": "string",
          "algorithm": "AEAD_AES_CBC_HMAC_SHA512-Deterministic"
        }
      }
    },
    "bsonType": "object"
  },
  "isRemoteSchema": true
}libmongocrypt-1.3.0/bindings/python/test/data/mongocryptd-reply.json000066400000000000000000000006541414105245100260040ustar00rootroot00000000000000{
    "schemaRequiresEncryption": true,
    "ok": {
        "$numberInt": "1"
    },
    "result": {
        "filter": {
            "ssn": {
                "$binary": {
                    "base64": "ADgAAAAQYQABAAAABWtpABAAAAAEYWFhYWFhYWFhYWFhYWFhYQJ2AAwAAAA0NTctNTUtNTQ2MgAA",
                    "subType": "06"
                }
            }
        },
        "find": "test"
    },
    "hasEncryptedPlaceholders": true
}libmongocrypt-1.3.0/bindings/python/test/data/schema-map.json000066400000000000000000000013521414105245100243150ustar00rootroot00000000000000{
  "test.test": {
    "properties": {
      "ssn": {
        "encrypt": {
          "keyId": {
            "$binary": {
              "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
              "subType": "04"
            }
          },
          "type": "string",
          "algorithm": "AEAD_AES_CBC_HMAC_SHA512-Deterministic"
        }
      }
    },
    "bsonType": "object"
  },
  "test.test2": {
    "properties": {
      "ssn": {
        "encrypt": {
          "keyId": {
            "$binary": {
              "base64": "AAAAAAAAAAAAAAAAAAAAAA==",
              "subType": "04"
            }
          },
          "type": "string",
          "algorithm": "AEAD_AES_CBC_HMAC_SHA512-Random"
        }
      }
    },
    "bsonType": "object"
  }
}libmongocrypt-1.3.0/bindings/python/test/test_binding.py000066400000000000000000000045361414105245100235300ustar00rootroot00000000000000# Copyright 2019-present MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Test the binding module."""

import sys

sys.path[0:0] = [""]

import pymongocrypt
from pymongocrypt.binding import ffi, lib, _parse_version

from test import unittest


class TestBinding(unittest.TestCase):

    def assertVersionLike(self, version):
        self.assertTrue(isinstance(version, str), msg=version)
        # There should be at least one dot: "1.0" or "1.0.0" not "1".
        self.assertGreaterEqual(len(version.split('.')), 2, msg=version)

    def test_pymongocrypt_version(self):
        self.assertVersionLike(pymongocrypt.__version__)

    def test_libmongocrypt_version(self):
        self.assertVersionLike(pymongocrypt.libmongocrypt_version())

    def test_mongocrypt_new(self):
        data = lib.mongocrypt_new()
        self.assertNotEqual(data, ffi.NULL)
        lib.mongocrypt_destroy(data)

    def test_mongocrypt_binary_new(self):
        data = lib.mongocrypt_binary_new()
        self.assertNotEqual(data, ffi.NULL)
        lib.mongocrypt_binary_destroy(data)

    def test_mongocrypt_status_new(self):
        data = lib.mongocrypt_status_new()
        self.assertNotEqual(data, ffi.NULL)
        lib.mongocrypt_status_destroy(data)

    def test_parse_version(self):
        # Dev versions, betas, RCs should be less than stable releases.
        for v in ('1.1.0-beta1', '1.1.0-b2', '1.1.0-rc1',
                  '1.1.0-beta1', '1.1.0-pre1'):
            self.assertLess(_parse_version(v),
                            _parse_version('1.1.0'))

        # Dev versions should parse correctly.
        _parse_version('1.1.0-beta1+20201102git80202647fc')

        # Hyphenation in patch version should be disregarded.
        self.assertEqual(_parse_version('1.1.0-beta1'),
                         _parse_version('1.1.0beta1'))


if __name__ == "__main__":
    unittest.main()
libmongocrypt-1.3.0/bindings/python/test/test_crypto.py000066400000000000000000000066271414105245100234410ustar00rootroot00000000000000# Copyright 2020-present MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Test the crypto module."""

import sys

sys.path[0:0] = [""]

import base64

from pymongocrypt.binary import MongoCryptBinaryIn
from pymongocrypt.binding import ffi, lib
from pymongocrypt.crypto import sign_rsaes_pkcs1_v1_5

from test import unittest


class TestCrypto(unittest.TestCase):
    def test_sign_rsaes_pkcs1_v1_5(self):
        key_b64 = 'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC4JOyv5z05cL18ztpknRC7CFY2gYol4DAKerdVUoDJxCTmFMf39dVUEqD0WDiw/qcRtSO1/FRut08PlSPmvbyKetsLoxlpS8lukSzEFpFK7+L+R4miFOl6HvECyg7lbC1H/WGAhIz9yZRlXhRo9qmO/fB6PV9IeYtU+1xYuXicjCDPp36uuxBAnCz7JfvxJ3mdVc0vpSkbSb141nWuKNYR1mgyvvL6KzxO6mYsCo4hRAdhuizD9C4jDHk0V2gDCFBk0h8SLEdzStX8L0jG90/Og4y7J1b/cPo/kbYokkYisxe8cPlsvGBf+rZex7XPxc1yWaP080qeABJb+S88O//LAgMBAAECggEBAKVxP1m3FzHBUe2NZ3fYCc0Qa2zjK7xl1KPFp2u4CU+9sy0oZJUqQHUdm5CMprqWwIHPTftWboFenmCwrSXFOFzujljBO7Z3yc1WD3NJl1ZNepLcsRJ3WWFH5V+NLJ8Bdxlj1DMEZCwr7PC5+vpnCuYWzvT0qOPTl9RNVaW9VVjHouJ9Fg+s2DrShXDegFabl1iZEDdI4xScHoYBob06A5lw0WOCTayzw0Naf37lM8Y4psRAmI46XLiF/Vbuorna4hcChxDePlNLEfMipICcuxTcei1RBSlBa2t1tcnvoTy6cuYDqqImRYjp1KnMKlKQBnQ1NjS2TsRGm+F0FbreVCECgYEA4IDJlm8q/hVyNcPe4OzIcL1rsdYN3bNm2Y2O/YtRPIkQ446ItyxD06d9VuXsQpFp9jNACAPfCMSyHpPApqlxdc8z/xATlgHkcGezEOd1r4E7NdTpGg8y6Rj9b8kVlED6v4grbRhKcU6moyKUQT3+1B6ENZTOKyxuyDEgTwZHtFECgYEA0fqdv9h9s77d6eWmIioP7FSymq93pC4umxf6TVicpjpMErdD2ZfJGulN37dq8FOsOFnSmFYJdICj/PbJm6p1i8O21lsFCltEqVoVabJ7/0alPfdG2U76OeBqI8ZubL4BMnWXAB/VVEYbyWCNpQSDTjHQYs54qa2I0dJB7OgJt1sCgYEArctFQ02/7H5Rscl1yo3DBXO94SeiCFSPdC8f2Kt3MfOxvVdkAtkjkMACSbkoUsgbTVqTYSEOEc2jTgR3iQ13JgpHaFbbsq64V0QP3TAxbLIQUjYGVgQaF1UfLOBv8hrzgj45z/ST/G80lOl595+0nCUbmBcgG1AEWrmdF0/3RmECgYAKvIzKXXB3+19vcT2ga5Qq2l3TiPtOGsppRb2XrNs9qKdxIYvHmXo/9QP1V3SRW0XoD7ez8FpFabp42cmPOxUNk3FK3paQZABLxH5pzCWI9PzIAVfPDrm+sdnbgG7vAnwfL2IMMJSA3aDYGCbF9EgefG+STcpfqq7fQ6f5TBgLFwKBgCd7gn1xYL696SaKVSm7VngpXlczHVEpz3kStWR5gfzriPBxXgMVcWmcbajRser7ARpCEfbxM1UJyv6oAYZWVSNErNzNVb4POqLYcCNySuC6xKhs9FrEQnyKjyk8wI4VnrEMGrQ8e+qYSwYk9Gh6dKGoRMAPYVXQAO0fIsHF/T0a'
        ciphertext_b64 = "VocBRhpMmQ2XCzVehWSqheQLnU889gf3dhU4AnVnQTJjsKx/CM23qKDPkZDd2A/BnQsp99SN7ksIX5Raj0TPwyN5OCN/YrNFNGoOFlTsGhgP/hyE8X3Duiq6sNO0SMvRYNPFFGlJFsp1Fw3Z94eYMg4/Wpw5s4+Jo5Zm/qY7aTJIqDKDQ3CNHLeJgcMUOc9sz01/GzoUYKDVODHSxrYEk5ireFJFz9vP8P7Ha+VDUZuQIQdXer9NBbGFtYmWprY3nn4D3Dw93Sn0V0dIqYeIo91oKyslvMebmUM95S2PyIJdEpPb2DJDxjvX/0LLwSWlSXRWy9gapWoBkb4ynqZBsg=="
        value = b'data to sign'

        with MongoCryptBinaryIn(b'1' * 256) as output, \
                MongoCryptBinaryIn(base64.b64decode(key_b64)) as key,\
                MongoCryptBinaryIn(value) as value:
            retval = sign_rsaes_pkcs1_v1_5(
                ffi.NULL, key.bin, value.bin, output.bin,
                lib.mongocrypt_status_new())

            self.assertTrue(retval)
            self.assertEqual(
                output.to_bytes(), base64.b64decode(ciphertext_b64))


if __name__ == "__main__":
    unittest.main()
libmongocrypt-1.3.0/bindings/python/test/test_mongocrypt.py000066400000000000000000000434241414105245100243160ustar00rootroot00000000000000# Copyright 2019-present MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Test the mongocrypt module."""

import base64
import copy
import os
import sys
import uuid

from bson import json_util, BSON
from bson.binary import Binary, STANDARD
from bson.codec_options import CodecOptions
from bson.json_util import JSONOptions
from bson.son import SON

sys.path[0:0] = [""]

from pymongocrypt.auto_encrypter import AutoEncrypter
from pymongocrypt.binding import lib
from pymongocrypt.compat import unicode_type, PY3
from pymongocrypt.errors import MongoCryptError
from pymongocrypt.explicit_encrypter import ExplicitEncrypter
from pymongocrypt.mongocrypt import (MongoCrypt,
                                     MongoCryptBinaryIn,
                                     MongoCryptBinaryOut,
                                     MongoCryptOptions)
from pymongocrypt.state_machine import MongoCryptCallback

from test import unittest

# Data for testing libbmongocrypt binding.
DATA_DIR = os.path.realpath(os.path.join(os.path.dirname(__file__), 'data'))


def to_base64(data):
    b64 = base64.b64encode(data)
    if not PY3:
        return unicode_type(b64)
    return b64.decode('utf-8')


class TestMongoCryptBinary(unittest.TestCase):

    def test_mongocrypt_binary_in(self):
        with MongoCryptBinaryIn(b'1\x0023') as binary:
            self.assertIsNotNone(binary.bin)
            self.assertEqual(binary.to_bytes(), b'1\x0023')
        self.assertIsNone(binary.bin)

        with MongoCryptBinaryIn(b'') as binary:
            self.assertIsNotNone(binary.bin)
            self.assertEqual(binary.to_bytes(), b'')
        self.assertIsNone(binary.bin)

        # Memoryview
        with MongoCryptBinaryIn(memoryview(b'1\x0023')) as binary:
            self.assertIsNotNone(binary.bin)
            self.assertEqual(binary.to_bytes(), b'1\x0023')
        self.assertIsNone(binary.bin)

    def test_mongocrypt_binary_out(self):
        with MongoCryptBinaryOut() as binary:
            self.assertIsNotNone(binary.bin)
            self.assertEqual(binary.to_bytes(), b'')
        self.assertIsNone(binary.bin)


class TestMongoCryptOptions(unittest.TestCase):

    def test_mongocrypt_options(self):
        schema_map = bson_data('schema-map.json')
        valid = [
            ({'local': {'key': b'1' * 96}}, None),
            ({'aws': {'accessKeyId': '', 'secretAccessKey': ''}}, schema_map),
            ({'aws': {'accessKeyId': 'foo', 'secretAccessKey': 'foo'}}, None),
            ({'aws': {'accessKeyId': 'foo', 'secretAccessKey': 'foo',
                      'sessionToken': 'token'}}, None),
            ({'aws': {'accessKeyId': 'foo', 'secretAccessKey': 'foo'},
              'local': {'key': b'1' * 96}}, None),
            ({'local': {'key': to_base64(b'1' * 96)}}, None),
            ({'local': {'key': Binary(b'1' * 96)}}, None),
            ({'gcp': {'email': 'foo@bar.baz',
                      'privateKey': b'1'}}, None),
            ({'gcp': {'email': 'foo@bar.baz',
                      'privateKey': to_base64(b'1')}}, None),
            ({'gcp': {'email': 'foo@bar.baz',
                      'privateKey': Binary(b'1')}}, None)
        ]
        for kms_providers, schema_map in valid:
            opts = MongoCryptOptions(kms_providers, schema_map)
            self.assertEqual(opts.kms_providers, kms_providers, msg=kms_providers)
            self.assertEqual(opts.schema_map, schema_map)

    def test_mongocrypt_options_validation(self):
        with self.assertRaisesRegex(
                ValueError, 'at least one KMS provider must be configured'):
            MongoCryptOptions({})
        for invalid_kms_providers in [
                {'aws': {}},
                {'aws': {'accessKeyId': 'foo'}},
                {'aws': {'secretAccessKey': 'foo'}}]:
            with self.assertRaisesRegex(
                    ValueError, "kms_providers\['aws'\] must contain "
                                "'accessKeyId' and 'secretAccessKey'"):
                MongoCryptOptions(invalid_kms_providers)
        with self.assertRaisesRegex(
                TypeError, "kms_providers\['local'\]\['key'\] must be an "
                           "instance of bytes or str \(unicode in Python 2\)"):
            MongoCryptOptions({'local': {'key': None}})
        with self.assertRaisesRegex(
                TypeError, "kms_providers\['gcp'\]\['privateKey'\] must be an "
                           "instance of bytes or str \(unicode in Python 2\)"):
            MongoCryptOptions({'gcp': {'email': "foo@bar.baz",
                                       "privateKey": None}})

        valid_kms = {'aws': {'accessKeyId': '', 'secretAccessKey': ''}}
        with self.assertRaisesRegex(
                TypeError, "schema_map must be bytes or None"):
            MongoCryptOptions(valid_kms, schema_map={})


class TestMongoCrypt(unittest.TestCase):

    def test_mongocrypt(self):
        kms_providers = {
            'aws': {'accessKeyId': 'foo', 'secretAccessKey': 'foo'}}
        opts = MongoCryptOptions(kms_providers)
        mc = MongoCrypt(opts, MockCallback())
        mc.close()
        mc.close()

    def test_mongocrypt_aws_session_token(self):
        kms_providers = {
            'aws': {'accessKeyId': 'foo', 'secretAccessKey': 'foo',
                    'sessionToken': 'token'}}
        opts = MongoCryptOptions(kms_providers)
        mc = MongoCrypt(opts, MockCallback())
        mc.close()

    def test_mongocrypt_validation(self):
        callback = MockCallback()
        options = MongoCryptOptions({'local': {'key': b'\x00' * 96}})

        with self.assertRaisesRegex(
                TypeError, 'options must be a MongoCryptOptions'):
            MongoCrypt({}, callback)
        with self.assertRaisesRegex(
                TypeError, 'options must be a MongoCryptOptions'):
            MongoCrypt(None, callback)

        with self.assertRaisesRegex(
                TypeError, 'callback must be a MongoCryptCallback'):
            MongoCrypt(options, {})
        with self.assertRaisesRegex(
                TypeError, 'callback must be a MongoCryptCallback'):
            MongoCrypt(options, None)

        invalid_key_len_opts = MongoCryptOptions({'local': {'key': b'1'}})
        with self.assertRaisesRegex(
                MongoCryptError, "local key must be 96 bytes"):
            MongoCrypt(invalid_key_len_opts, callback)

    def test_setopt_kms_provider_base64_or_bytes(self):
        test_fields = [("local", "key"), ("gcp", "privateKey")]
        callback = MockCallback()
        base_kms_dict = {'local': {'key': b'\x00' * 96},
                         'gcp': {'email': 'foo@bar.baz',
                                 'privateKey': b'\x00'}}

        for f1, f2 in test_fields:
            kms_dict = copy.deepcopy(base_kms_dict)

            # Case 1: pass key as string containing bytes (valid)
            kms_dict[f1][f2] = b'\x00' * 96
            options = MongoCryptOptions(kms_dict)
            mc = MongoCrypt(options, callback)
            mc.close()

            # Case 2: pass key as base64-encoded unicode literal (valid)
            kms_dict[f1][f2] = to_base64(b'\x00' * 96)
            options = MongoCryptOptions(kms_dict)
            mc = MongoCrypt(options, callback)
            mc.close()

            # Case 3: pass key as unicode string containing bytes (invalid)
            kms_dict[f1][f2] = unicode_type(b'\x00' * 96)
            options = MongoCryptOptions(kms_dict)
            with self.assertRaisesRegex(
                    MongoCryptError,
                    "unable to parse base64 from UTF-8 field %s.%s" % (
                            f1, f2)):
                MongoCrypt(options, callback)

        # Case 4: pass key as base64-encoded string (invalid)
        # Only applicable to "local" as key length is not validated for gcp.
        kms_dict = copy.deepcopy(base_kms_dict)
        kms_dict['local']['key'] = base64.b64encode(b'\x00' * 96)
        options = MongoCryptOptions(kms_dict)
        with self.assertRaisesRegex(
                MongoCryptError, "local key must be 96 bytes"):
            MongoCrypt(options, callback)

    @staticmethod
    def create_mongocrypt():
        return MongoCrypt(MongoCryptOptions({
            'aws': {'accessKeyId': 'example', 'secretAccessKey': 'example'},
            'local': {'key': b'\x00'*96}}), MockCallback())

    def _test_kms_context(self, ctx):
        key_filter = ctx.mongo_operation()
        self.assertEqual(key_filter, bson_data('key-filter.json'))
        ctx.add_mongo_operation_result(bson_data('key-document.json'))
        ctx.complete_mongo_operation()
        self.assertEqual(ctx.state, lib.MONGOCRYPT_CTX_NEED_KMS)

        km_contexts = list(ctx.kms_contexts())
        self.assertEqual(len(km_contexts), 1)
        with km_contexts[0] as kms_ctx:
            self.assertEqual(kms_ctx.endpoint, "kms.us-east-1.amazonaws.com:443")
            self.assertEqual(len(kms_ctx.message), 781)
            self.assertEqual(kms_ctx.bytes_needed, 1024)

            kms_ctx.feed(http_data('kms-reply.txt'))
            self.assertEqual(kms_ctx.bytes_needed, 0)

        ctx.complete_kms()

    def test_encrypt(self):
        mc = self.create_mongocrypt()
        self.addCleanup(mc.close)
        with mc.encryption_context('text', bson_data('command.json')) as ctx:
            self.assertEqual(ctx.state, lib.MONGOCRYPT_CTX_NEED_MONGO_COLLINFO)

            list_colls_filter = ctx.mongo_operation()
            self.assertEqual(list_colls_filter,
                             bson_data('list-collections-filter.json'))

            ctx.add_mongo_operation_result(bson_data('collection-info.json'))
            ctx.complete_mongo_operation()
            self.assertEqual(ctx.state, lib.MONGOCRYPT_CTX_NEED_MONGO_MARKINGS)

            mongocryptd_cmd = ctx.mongo_operation()
            self.assertEqual(mongocryptd_cmd,
                             bson_data('mongocryptd-command.json'))

            ctx.add_mongo_operation_result(bson_data('mongocryptd-reply.json'))
            ctx.complete_mongo_operation()
            self.assertEqual(ctx.state, lib.MONGOCRYPT_CTX_NEED_MONGO_KEYS)

            self._test_kms_context(ctx)

            self.assertEqual(ctx.state, lib.MONGOCRYPT_CTX_READY)

            encrypted = ctx.finish()
            self.assertEqual(
                BSON(encrypted).decode(), json_data('encrypted-command.json'))
            self.assertEqual(encrypted, bson_data('encrypted-command.json'))
            self.assertEqual(ctx.state, lib.MONGOCRYPT_CTX_DONE)

    def test_decrypt(self):
        mc = self.create_mongocrypt()
        self.addCleanup(mc.close)
        with mc.decryption_context(
                bson_data('encrypted-command-reply.json')) as ctx:
            self.assertEqual(ctx.state, lib.MONGOCRYPT_CTX_NEED_MONGO_KEYS)

            self._test_kms_context(ctx)

            self.assertEqual(ctx.state, lib.MONGOCRYPT_CTX_READY)

            encrypted = ctx.finish()
            self.assertEqual(
                BSON(encrypted).decode(), json_data('command-reply.json'))
            self.assertEqual(encrypted, bson_data('command-reply.json'))
            self.assertEqual(ctx.state, lib.MONGOCRYPT_CTX_DONE)


class MockCallback(MongoCryptCallback):
    def __init__(self,
                 list_colls_result=None,
                 mongocryptd_reply=None,
                 key_docs=None,
                 kms_reply=None):
        self.list_colls_result = list_colls_result
        self.mongocryptd_reply = mongocryptd_reply
        self.key_docs = key_docs
        self.kms_reply = kms_reply
        self.kms_endpoint = None

    def kms_request(self, kms_context):
        self.kms_endpoint = kms_context.endpoint
        kms_context.feed(self.kms_reply)

    def collection_info(self, ns, filter):
        return self.list_colls_result

    def mark_command(self, ns, cmd):
        return self.mongocryptd_reply

    def fetch_keys(self, filter):
        return self.key_docs

    def insert_data_key(self, data_key):
        raise NotImplementedError

    def bson_encode(self, doc):
        return BSON.encode(doc)

    def close(self):
        pass


class TestMongoCryptCallback(unittest.TestCase):

    @staticmethod
    def mongo_crypt_opts():
        return MongoCryptOptions({
            'aws': {'accessKeyId': 'example', 'secretAccessKey': 'example'},
            'local': {'key': b'\x00'*96}})

    def test_encrypt(self):
        encrypter = AutoEncrypter(MockCallback(
            list_colls_result=bson_data('collection-info.json'),
            mongocryptd_reply=bson_data('mongocryptd-reply.json'),
            key_docs=[bson_data('key-document.json')],
            kms_reply=http_data('kms-reply.txt')), self.mongo_crypt_opts())
        self.addCleanup(encrypter.close)
        encrypted = encrypter.encrypt('text', bson_data('command.json'))
        self.assertEqual(
            BSON(encrypted).decode(), json_data('encrypted-command.json'))
        self.assertEqual(encrypted, bson_data('encrypted-command.json'))

    def test_decrypt(self):
        encrypter = AutoEncrypter(MockCallback(
            list_colls_result=bson_data('collection-info.json'),
            mongocryptd_reply=bson_data('mongocryptd-reply.json'),
            key_docs=[bson_data('key-document.json')],
            kms_reply=http_data('kms-reply.txt')), self.mongo_crypt_opts())
        self.addCleanup(encrypter.close)
        decrypted = encrypter.decrypt(
            bson_data('encrypted-command-reply.json'))
        self.assertEqual(
            BSON(decrypted).decode(), json_data('command-reply.json'))
        self.assertEqual(decrypted, bson_data('command-reply.json'))


class KeyVaultCallback(MockCallback):
    def __init__(self, kms_reply=None):
        super(KeyVaultCallback, self).__init__(kms_reply=kms_reply)
        self.data_key = None

    def fetch_keys(self, filter):
        return self.data_key

    def insert_data_key(self, data_key):
        self.data_key = data_key
        return BSON(data_key).decode()['_id']


class TestExplicitEncryption(unittest.TestCase):

    @staticmethod
    def mongo_crypt_opts():
        return MongoCryptOptions({
            'aws': {'accessKeyId': 'example', 'secretAccessKey': 'example'},
            'local': {'key': b'\x00'*96}})

    def _test_encrypt_decrypt(self, key_id=None, key_alt_name=None):
        encrypter = ExplicitEncrypter(MockCallback(
            key_docs=[bson_data('key-document.json')],
            kms_reply=http_data('kms-reply.txt')), self.mongo_crypt_opts())
        self.addCleanup(encrypter.close)

        val = {'v': 'hello'}
        encoded_val = BSON.encode(val)
        algo = "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
        encrypted = encrypter.encrypt(
            encoded_val, algo, key_id=key_id, key_alt_name=key_alt_name)
        self.assertEqual(
            BSON(encrypted).decode(), json_data('encrypted-value.json'))
        self.assertEqual(encrypted, bson_data('encrypted-value.json'))

        decrypted = encrypter.decrypt(encrypted)
        self.assertEqual(BSON(decrypted).decode(), val)
        self.assertEqual(encoded_val, decrypted)

    def test_encrypt_decrypt(self):
        key_id = json_data('key-document.json')['_id']
        self._test_encrypt_decrypt(key_id=key_id.bytes)

    def test_encrypt_decrypt_key_alt_name(self):
        key_alt_name = json_data('key-document.json')['keyAltNames'][0]
        self._test_encrypt_decrypt(key_alt_name=key_alt_name)

    def test_data_key_creation(self):
        mock_key_vault = KeyVaultCallback(
            kms_reply=http_data('kms-encrypt-reply.txt'))
        encrypter = ExplicitEncrypter(mock_key_vault, self.mongo_crypt_opts())
        self.addCleanup(encrypter.close)

        valid_args = [
            ('local', None, ['first', 'second']),
            ('aws', {'region': 'region', 'key': 'cmk'}, ['third', 'forth']),
            # Unicode region and key
            ('aws', {'region': u'region-unicode', 'key': u'cmk-unicode'}, []),
            # Endpoint
            ('aws', {'region': 'region', 'key': 'cmk',
                     'endpoint': 'kms.us-east-1.amazonaws.com:443'}, []),
        ]
        for kms_provider, master_key, key_alt_names in valid_args:
            key_id = encrypter.create_data_key(
                kms_provider, master_key=master_key,
                key_alt_names=key_alt_names)
            self.assertIsInstance(key_id, uuid.UUID)
            data_key = BSON(mock_key_vault.data_key).decode()
            # CDRIVER-3277 The order of key_alt_names is not maintained.
            for name in key_alt_names:
                self.assertIn(name, data_key['keyAltNames'])

        # Assert that the custom endpoint is passed to libmongocrypt.
        master_key = {
            "region": "region",
            "key": "key",
            "endpoint": "example.com"
        }
        encrypter.create_data_key("aws", master_key=master_key)
        self.assertEqual("example.com:443", mock_key_vault.kms_endpoint)


def read(filename, **kwargs):
    with open(os.path.join(DATA_DIR, filename), **kwargs) as fp:
        return fp.read()


OPTS = CodecOptions(uuid_representation=STANDARD)

# Use SON to preserve the order of fields while parsing json.
JSON_OPTS = JSONOptions(document_class=SON, uuid_representation=STANDARD)


def json_data(filename):
    return json_util.loads(read(filename), json_options=JSON_OPTS)


def bson_data(filename):
    return BSON.encode(json_data(filename), codec_options=OPTS)


def http_data(filename):
    data = read(filename, mode='rb')
    return data.replace(b'\n', b'\r\n')


if __name__ == "__main__":
    unittest.main()
libmongocrypt-1.3.0/cmake/000077500000000000000000000000001414105245100154605ustar00rootroot00000000000000libmongocrypt-1.3.0/cmake/GetVersion.cmake000066400000000000000000000103341414105245100205500ustar00rootroot00000000000000# Defines a function to get the version (possibly suffixed with prerelease info)
# from git history.
#
# This may be run as an independent script, like so:
# cmake -P ./cmake/GetVersion.cmake
# And the computed version is printed to stderr (since printing to stdout with
# cmake's "message" function would prefix with "-- ")
#
# The general approach of this function is to produce a sequence of versions
# which distinguish between development versions, release candidates, prerelease
# builds which fall between release candidates, and actual releases.  This
# sequence might look approximately like:
#
# tag:1.0.0 [commit with release tag]
# 1.0.1-dev+20191107git12345 [subsequent untagged commits after release tag]
# tag:1.0.1-rc0 [first candidate for next release]
# 1.0.1-pre1+20191108git23456 [subsequent untagged commits after RC]
# tag:1.0.1-rc1 [second candidate for next release]
# 1.0.1-pre2+20191109git34567 [subsequent untagged commits after RC]
# tag:1.0.1-rc2 [third candidate for next release]
# tag:1.0.1 [commit with release tag]
#
# Note that some of these may be skipped along the way, depending on what ends
# up being included in a particular release cycle.
#
function (GetVersion OUTVAR)
    execute_process (
        COMMAND git describe --tags --match "1.*"
        OUTPUT_VARIABLE VERSION_WITH_SUFFIX
        RESULT_VARIABLE GIT_STATUS
        ERROR_VARIABLE GIT_ERROR
        OUTPUT_STRIP_TRAILING_WHITESPACE
    )

    if (NOT GIT_STATUS STREQUAL 0)
        message (FATAL_ERROR "Unable to determine version: 'git describe' failed: '${GIT_ERROR}'")
    endif ()

    execute_process (
        COMMAND git describe --tags --abbrev=0 --match "1.*"
        OUTPUT_VARIABLE VERSION
        RESULT_VARIABLE GIT_STATUS
        ERROR_VARIABLE GIT_ERROR
        OUTPUT_STRIP_TRAILING_WHITESPACE
    )

    if (NOT GIT_STATUS STREQUAL 0)
        message (FATAL_ERROR "Unable to determine version: 'git describe' failed: '${GIT_ERROR}'")
    endif ()

    # If "git describe --abbrev=0" has the same result as "git describe", then the current commit
    # is tagged, so return that.
    if (VERSION STREQUAL VERSION_WITH_SUFFIX)
        set (${OUTVAR} ${VERSION} PARENT_SCOPE)
        return ()
    endif ()

    # Otherwise, construct a version based on the next release version

    # A list of version components separated by dots and dashes: "1.0.0-[prerelease-marker]"
    string (REGEX MATCHALL "[^.-]+" VERSION_PARTS ${VERSION})

    list (LENGTH VERSION_PARTS VERSION_LENGTH)
    list (GET VERSION_PARTS 0 MAJOR_VERSION)
    list (GET VERSION_PARTS 1 MINOR_VERSION)
    list (GET VERSION_PARTS 2 PATCH_VERSION)
    set (PRERELEASE_VERSION "")
    if (VERSION_LENGTH GREATER 3)
        # The version we are starting with is already a pre-release of the next
        list (GET VERSION_PARTS 3 PRERELEASE_VERSION)
        string (REGEX MATCHALL "(beta|rc|[0-9]+)" PRERELEASE_PARTS ${PRERELEASE_VERSION})
        list (LENGTH PRERELEASE_PARTS PRERELEASE_LENGTH)
        if (PRERELEASE_LENGTH EQUAL 2)
            list (GET PRERELEASE_PARTS 0 PRE_PT_ONE)
            list (GET PRERELEASE_PARTS 1 PRE_PT_TWO)
            math (EXPR PRE_PT_TWO "${PRE_PT_TWO} + 1")
            set (PRERELEASE_VERSION "-pre${PRE_PT_TWO}")
        else ()
        endif ()
    else ()
        # The version we are starting with is the last release, so we increment
        # the patch component to get the next version
        math (EXPR PATCH_VERSION "${PATCH_VERSION} + 1")
        set (PRERELEASE_VERSION "-dev")
    endif ()
    set (VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}${PRERELEASE_VERSION}")

    # Append our custom suffix +git
    execute_process (
        COMMAND git rev-parse --revs-only --short=10 HEAD
        OUTPUT_VARIABLE SUFFIX_SHA
        RESULT_VARIABLE GIT_STATUS
        ERROR_VARIABLE GIT_ERROR
        OUTPUT_STRIP_TRAILING_WHITESPACE
    )

    if (NOT GIT_STATUS STREQUAL 0)
        message (FATAL_ERROR "Unable to determine version: 'git rev-parse' failed: '${GIT_ERROR}'")
    endif ()

    string (TIMESTAMP SUFFIX_DATE "%Y%m%d")

    set (${OUTVAR} "${VERSION}+${SUFFIX_DATE}git${SUFFIX_SHA}" PARENT_SCOPE)

endfunction (GetVersion)

if (CMAKE_SCRIPT_MODE_FILE)
    GetVersion (MONGOCRYPT_VERSION)
    message (${MONGOCRYPT_VERSION})
endif ()
libmongocrypt-1.3.0/cmake/libmongocrypt-hidden-symbols.map000066400000000000000000000001431414105245100237640ustar00rootroot00000000000000mongocrypt {
    local:
        bson*;
        bcon*;
        jsonsl*;
        _*;
        kms*;
};libmongocrypt-1.3.0/cmake/libmongocrypt-hidden-symbols.txt000066400000000000000000000000401414105245100240220ustar00rootroot00000000000000_bson*
_bcon*
_jsonsl*
__*
_kms*libmongocrypt-1.3.0/cmake/libmongocrypt-static.pc.in000066400000000000000000000004411414105245100225650ustar00rootroot00000000000000Name: ${PROJECT_NAME}
Description: ${PROJECT_DESCRIPTION}
Version: ${PROJECT_VERSION}
Requires: ${PKG_CONFIG_STATIC_REQUIRES}
prefix=${CMAKE_INSTALL_PREFIX}
includedir=${PKG_CONFIG_INCLUDEDIR}
libdir=${PKG_CONFIG_LIBDIR}
Libs: ${PKG_CONFIG_STATIC_LIBS}
Cflags: ${PKG_CONFIG_STATIC_CFLAGS}
libmongocrypt-1.3.0/cmake/libmongocrypt.pc.in000066400000000000000000000004751414105245100213070ustar00rootroot00000000000000Name: ${PROJECT_NAME}
Description: ${PROJECT_DESCRIPTION}
Version: ${PROJECT_VERSION}
Requires: ${PKG_CONFIG_REQUIRES}
Requires.private: ${PKG_CONFIG_REQUIRES_PRIVATE}
prefix=${CMAKE_INSTALL_PREFIX}
includedir=${PKG_CONFIG_INCLUDEDIR}
libdir=${PKG_CONFIG_LIBDIR}
Libs: ${PKG_CONFIG_LIBS}
Cflags: ${PKG_CONFIG_CFLAGS}
libmongocrypt-1.3.0/cmake/mongocrypt-config.cmake000066400000000000000000000002031414105245100221210ustar00rootroot00000000000000include(CMakeFindDependencyMacro)
find_dependency(kms_message 0.0.1)
include("${CMAKE_CURRENT_LIST_DIR}/mongocrypt_targets.cmake")
libmongocrypt-1.3.0/doc/000077500000000000000000000000001414105245100151455ustar00rootroot00000000000000libmongocrypt-1.3.0/doc/Doxygen000066400000000000000000003217451414105245100165210ustar00rootroot00000000000000# Doxyfile 1.8.13

# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
#
# All text after a double hash (##) is considered a comment and is placed in
# front of the TAG it is preceding.
#
# All text after a single hash (#) is considered a comment and will be ignored.
# The format is:
# TAG = value [value, ...]
# For lists, items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (\" \").

#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------

# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all text
# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
# for the list of possible encodings.
# The default value is: UTF-8.

DOXYFILE_ENCODING      = UTF-8

# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
# double-quotes, unless you are using Doxywizard) that should identify the
# project for which the documentation is generated. This name is used in the
# title of most generated pages and in a few other places.
# The default value is: My Project.

PROJECT_NAME           = "libmongocrypt"

# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version
# control system is used.

PROJECT_NUMBER         =

# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.

PROJECT_BRIEF          =

# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
# in the documentation. The maximum height of the logo should not exceed 55
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.

PROJECT_LOGO           =

# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.

OUTPUT_DIRECTORY       = ./doc

# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
# will distribute the generated files over these directories. Enabling this
# option can be useful when feeding doxygen a huge amount of source files, where
# putting all generated files in the same directory would otherwise causes
# performance problems for the file system.
# The default value is: NO.

CREATE_SUBDIRS         = NO

# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
# characters to appear in the names of generated files. If set to NO, non-ASCII
# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
# U+3044.
# The default value is: NO.

ALLOW_UNICODE_NAMES    = NO

# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
# Ukrainian and Vietnamese.
# The default value is: English.

OUTPUT_LANGUAGE        = English

# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
# descriptions after the members that are listed in the file and class
# documentation (similar to Javadoc). Set to NO to disable this.
# The default value is: YES.

BRIEF_MEMBER_DESC      = YES

# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
# description of a member or function before the detailed description
#
# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
# The default value is: YES.

REPEAT_BRIEF           = YES

# This tag implements a quasi-intelligent brief description abbreviator that is
# used to form the text in various listings. Each string in this list, if found
# as the leading text of the brief description, will be stripped from the text
# and the result, after processing the whole list, is used as the annotated
# text. Otherwise, the brief description is used as-is. If left blank, the
# following values are used ($name is automatically replaced with the name of
# the entity):The $name class, The $name widget, The $name file, is, provides,
# specifies, contains, represents, a, an and the.

ABBREVIATE_BRIEF       = "The $name class" \
                         "The $name widget" \
                         "The $name file" \
                         is \
                         provides \
                         specifies \
                         contains \
                         represents \
                         a \
                         an \
                         the

# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# doxygen will generate a detailed section even if there is only a brief
# description.
# The default value is: NO.

ALWAYS_DETAILED_SEC    = NO

# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
# inherited members of a class in the documentation of that class as if those
# members were ordinary class members. Constructors, destructors and assignment
# operators of the base classes will not be shown.
# The default value is: NO.

INLINE_INHERITED_MEMB  = NO

# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
# before files name in the file list and in the header files. If set to NO the
# shortest path that makes the file name unique will be used
# The default value is: YES.

FULL_PATH_NAMES        = YES

# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
# Stripping is only done if one of the specified strings matches the left-hand
# part of the path. The tag can be used to show relative paths in the file list.
# If left blank the directory from which doxygen is run is used as the path to
# strip.
#
# Note that you can specify absolute paths here, but also relative paths, which
# will be relative from the directory where doxygen is started.
# This tag requires that the tag FULL_PATH_NAMES is set to YES.

STRIP_FROM_PATH        =

# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
# path mentioned in the documentation of a class, which tells the reader which
# header file to include in order to use a class. If left blank only the name of
# the header file containing the class definition is used. Otherwise one should
# specify the list of include paths that are normally passed to the compiler
# using the -I flag.

STRIP_FROM_INC_PATH    =

# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
# less readable) file names. This can be useful is your file systems doesn't
# support long names like on DOS, Mac, or CD-ROM.
# The default value is: NO.

SHORT_NAMES            = NO

# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
# first line (until the first dot) of a Javadoc-style comment as the brief
# description. If set to NO, the Javadoc-style will behave just like regular Qt-
# style comments (thus requiring an explicit @brief command for a brief
# description.)
# The default value is: NO.

JAVADOC_AUTOBRIEF      = NO

# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
# line (until the first dot) of a Qt-style comment as the brief description. If
# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
# requiring an explicit \brief command for a brief description.)
# The default value is: NO.

QT_AUTOBRIEF           = NO

# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
# a brief description. This used to be the default behavior. The new default is
# to treat a multi-line C++ comment block as a detailed description. Set this
# tag to YES if you prefer the old behavior instead.
#
# Note that setting this tag to YES also means that rational rose comments are
# not recognized any more.
# The default value is: NO.

MULTILINE_CPP_IS_BRIEF = NO

# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
# documentation from any documented member that it re-implements.
# The default value is: YES.

INHERIT_DOCS           = YES

# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
# page for each member. If set to NO, the documentation of a member will be part
# of the file/class/namespace that contains it.
# The default value is: NO.

SEPARATE_MEMBER_PAGES  = NO

# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
# uses this value to replace tabs by spaces in code fragments.
# Minimum value: 1, maximum value: 16, default value: 4.

TAB_SIZE               = 4

# This tag can be used to specify a number of aliases that act as commands in
# the documentation. An alias has the form:
# name=value
# For example adding
# "sideeffect=@par Side Effects:\n"
# will allow you to put the command \sideeffect (or @sideeffect) in the
# documentation, which will result in a user-defined paragraph with heading
# "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines.

ALIASES                =

# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"
# will allow you to use the command class in the itcl::class meaning.

TCL_SUBST              =

# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C. For
# instance, some of the names that are used will be different. The list of all
# members will be omitted, etc.
# The default value is: NO.

OPTIMIZE_OUTPUT_FOR_C  = YES

# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
# Python sources only. Doxygen will then generate output that is more tailored
# for that language. For instance, namespaces will be presented as packages,
# qualified scopes will look different, etc.
# The default value is: NO.

OPTIMIZE_OUTPUT_JAVA   = NO

# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
# sources. Doxygen will then generate output that is tailored for Fortran.
# The default value is: NO.

OPTIMIZE_FOR_FORTRAN   = NO

# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
# sources. Doxygen will then generate output that is tailored for VHDL.
# The default value is: NO.

OPTIMIZE_OUTPUT_VHDL   = NO

# Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
# Fortran. In the later case the parser tries to guess whether the code is fixed
# or free formatted code, this is the default for Fortran type files), VHDL. For
# instance to make doxygen treat .inc files as Fortran files (default is PHP),
# and .f files as C (default is Fortran), use: inc=Fortran f=C.
#
# Note: For files without extension you can use no_extension as a placeholder.
#
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
# the files are not read by doxygen.

EXTENSION_MAPPING      =

# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
# according to the Markdown format, which allows for more readable
# documentation. See http://daringfireball.net/projects/markdown/ for details.
# The output of markdown processing is further processed by doxygen, so you can
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
# case of backward compatibilities issues.
# The default value is: YES.

MARKDOWN_SUPPORT       = YES

# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
# to that level are automatically included in the table of contents, even if
# they do not have an id attribute.
# Note: This feature currently applies only to Markdown headings.
# Minimum value: 0, maximum value: 99, default value: 0.
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.

TOC_INCLUDE_HEADINGS   = 0

# When enabled doxygen tries to link words that correspond to documented
# classes, or namespaces to their corresponding documentation. Such a link can
# be prevented in individual cases by putting a % sign in front of the word or
# globally by setting AUTOLINK_SUPPORT to NO.
# The default value is: YES.

AUTOLINK_SUPPORT       = YES

# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
# to include (a tag file for) the STL sources as input, then you should set this
# tag to YES in order to let doxygen match functions declarations and
# definitions whose arguments contain STL classes (e.g. func(std::string);
# versus func(std::string) {}). This also make the inheritance and collaboration
# diagrams that involve STL classes more complete and accurate.
# The default value is: NO.

BUILTIN_STL_SUPPORT    = NO

# If you use Microsoft's C++/CLI language, you should set this option to YES to
# enable parsing support.
# The default value is: NO.

CPP_CLI_SUPPORT        = NO

# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
# will parse them like normal C++ but will assume all classes use public instead
# of private inheritance when no explicit protection keyword is present.
# The default value is: NO.

SIP_SUPPORT            = NO

# For Microsoft's IDL there are propget and propput attributes to indicate
# getter and setter methods for a property. Setting this option to YES will make
# doxygen to replace the get and set methods by a property in the documentation.
# This will only work if the methods are indeed getting or setting a simple
# type. If this is not the case, or you want to show the methods anyway, you
# should set this option to NO.
# The default value is: YES.

IDL_PROPERTY_SUPPORT   = YES

# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
# The default value is: NO.

DISTRIBUTE_GROUP_DOC   = NO

# If one adds a struct or class to a group and this option is enabled, then also
# any nested class or struct is added to the same group. By default this option
# is disabled and one has to add nested compounds explicitly via \ingroup.
# The default value is: NO.

GROUP_NESTED_COMPOUNDS = NO

# Set the SUBGROUPING tag to YES to allow class member groups of the same type
# (for instance a group of public functions) to be put as a subgroup of that
# type (e.g. under the Public Functions section). Set it to NO to prevent
# subgrouping. Alternatively, this can be done per class using the
# \nosubgrouping command.
# The default value is: YES.

SUBGROUPING            = YES

# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
# are shown inside the group in which they are included (e.g. using \ingroup)
# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
# and RTF).
#
# Note that this feature does not work in combination with
# SEPARATE_MEMBER_PAGES.
# The default value is: NO.

INLINE_GROUPED_CLASSES = NO

# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
# with only public data fields or simple typedef fields will be shown inline in
# the documentation of the scope in which they are defined (i.e. file,
# namespace, or group documentation), provided this scope is documented. If set
# to NO, structs, classes, and unions are shown on a separate page (for HTML and
# Man pages) or section (for LaTeX and RTF).
# The default value is: NO.

INLINE_SIMPLE_STRUCTS  = NO

# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
# enum is documented as struct, union, or enum with the name of the typedef. So
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
# with name TypeT. When disabled the typedef will appear as a member of a file,
# namespace, or class. And the struct will be named TypeS. This can typically be
# useful for C code in case the coding convention dictates that all compound
# types are typedef'ed and only the typedef is referenced, never the tag name.
# The default value is: NO.

TYPEDEF_HIDES_STRUCT   = NO

# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
# cache is used to resolve symbols given their name and scope. Since this can be
# an expensive process and often the same symbol appears multiple times in the
# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
# doxygen will become slower. If the cache is too large, memory is wasted. The
# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
# symbols. At the end of a run doxygen will report the cache usage and suggest
# the optimal cache size from a speed point of view.
# Minimum value: 0, maximum value: 9, default value: 0.

LOOKUP_CACHE_SIZE      = 0

#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------

# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
# documentation are documented, even if no documentation was available. Private
# class members and static file members will be hidden unless the
# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
# Note: This will also disable the warnings about undocumented members that are
# normally produced when WARNINGS is set to YES.
# The default value is: NO.

EXTRACT_ALL            = NO

# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
# be included in the documentation.
# The default value is: NO.

EXTRACT_PRIVATE        = NO

# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
# scope will be included in the documentation.
# The default value is: NO.

EXTRACT_PACKAGE        = NO

# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
# included in the documentation.
# The default value is: NO.

EXTRACT_STATIC         = NO

# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
# locally in source files will be included in the documentation. If set to NO,
# only classes defined in header files are included. Does not have any effect
# for Java sources.
# The default value is: YES.

EXTRACT_LOCAL_CLASSES  = YES

# This flag is only useful for Objective-C code. If set to YES, local methods,
# which are defined in the implementation section but not in the interface are
# included in the documentation. If set to NO, only methods in the interface are
# included.
# The default value is: NO.

EXTRACT_LOCAL_METHODS  = NO

# If this flag is set to YES, the members of anonymous namespaces will be
# extracted and appear in the documentation as a namespace called
# 'anonymous_namespace{file}', where file will be replaced with the base name of
# the file that contains the anonymous namespace. By default anonymous namespace
# are hidden.
# The default value is: NO.

EXTRACT_ANON_NSPACES   = NO

# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
# undocumented members inside documented classes or files. If set to NO these
# members will be included in the various overviews, but no documentation
# section is generated. This option has no effect if EXTRACT_ALL is enabled.
# The default value is: NO.

HIDE_UNDOC_MEMBERS     = NO

# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy. If set
# to NO, these classes will be included in the various overviews. This option
# has no effect if EXTRACT_ALL is enabled.
# The default value is: NO.

HIDE_UNDOC_CLASSES     = NO

# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
# (class|struct|union) declarations. If set to NO, these declarations will be
# included in the documentation.
# The default value is: NO.

HIDE_FRIEND_COMPOUNDS  = NO

# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
# documentation blocks found inside the body of a function. If set to NO, these
# blocks will be appended to the function's detailed documentation block.
# The default value is: NO.

HIDE_IN_BODY_DOCS      = NO

# The INTERNAL_DOCS tag determines if documentation that is typed after a
# \internal command is included. If the tag is set to NO then the documentation
# will be excluded. Set it to YES to include the internal documentation.
# The default value is: NO.

INTERNAL_DOCS          = NO

# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
# names in lower-case letters. If set to YES, upper-case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# and Mac users are advised to set this option to NO.
# The default value is: system dependent.

CASE_SENSE_NAMES       = NO

# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
# their full class and namespace scopes in the documentation. If set to YES, the
# scope will be hidden.
# The default value is: NO.

HIDE_SCOPE_NAMES       = NO

# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
# append additional text to a page's title, such as Class Reference. If set to
# YES the compound reference will be hidden.
# The default value is: NO.

HIDE_COMPOUND_REFERENCE= NO

# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
# the files that are included by a file in the documentation of that file.
# The default value is: YES.

SHOW_INCLUDE_FILES     = YES

# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
# grouped member an include statement to the documentation, telling the reader
# which file to include in order to use the member.
# The default value is: NO.

SHOW_GROUPED_MEMB_INC  = NO

# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
# files with double quotes in the documentation rather than with sharp brackets.
# The default value is: NO.

FORCE_LOCAL_INCLUDES   = NO

# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
# documentation for inline members.
# The default value is: YES.

INLINE_INFO            = YES

# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
# (detailed) documentation of file and class members alphabetically by member
# name. If set to NO, the members will appear in declaration order.
# The default value is: YES.

SORT_MEMBER_DOCS       = YES

# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
# descriptions of file, namespace and class members alphabetically by member
# name. If set to NO, the members will appear in declaration order. Note that
# this will also influence the order of the classes in the class list.
# The default value is: NO.

SORT_BRIEF_DOCS        = NO

# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
# (brief and detailed) documentation of class members so that constructors and
# destructors are listed first. If set to NO the constructors will appear in the
# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
# member documentation.
# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
# detailed member documentation.
# The default value is: NO.

SORT_MEMBERS_CTORS_1ST = NO

# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
# of group names into alphabetical order. If set to NO the group names will
# appear in their defined order.
# The default value is: NO.

SORT_GROUP_NAMES       = NO

# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
# fully-qualified names, including namespaces. If set to NO, the class list will
# be sorted only by class name, not including the namespace part.
# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
# Note: This option applies only to the class list, not to the alphabetical
# list.
# The default value is: NO.

SORT_BY_SCOPE_NAME     = NO

# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
# type resolution of all parameters of a function it will reject a match between
# the prototype and the implementation of a member function even if there is
# only one candidate or it is obvious which candidate to choose by doing a
# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
# accept a match between prototype and implementation in such cases.
# The default value is: NO.

STRICT_PROTO_MATCHING  = NO

# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
# list. This list is created by putting \todo commands in the documentation.
# The default value is: YES.

GENERATE_TODOLIST      = YES

# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
# list. This list is created by putting \test commands in the documentation.
# The default value is: YES.

GENERATE_TESTLIST      = YES

# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
# list. This list is created by putting \bug commands in the documentation.
# The default value is: YES.

GENERATE_BUGLIST       = YES

# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
# the deprecated list. This list is created by putting \deprecated commands in
# the documentation.
# The default value is: YES.

GENERATE_DEPRECATEDLIST= YES

# The ENABLED_SECTIONS tag can be used to enable conditional documentation
# sections, marked by \if  ... \endif and \cond 
# ... \endcond blocks.

ENABLED_SECTIONS       =

# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
# initial value of a variable or macro / define can have for it to appear in the
# documentation. If the initializer consists of more lines than specified here
# it will be hidden. Use a value of 0 to hide initializers completely. The
# appearance of the value of individual variables and macros / defines can be
# controlled using \showinitializer or \hideinitializer command in the
# documentation regardless of this setting.
# Minimum value: 0, maximum value: 10000, default value: 30.

MAX_INITIALIZER_LINES  = 30

# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
# the bottom of the documentation of classes and structs. If set to YES, the
# list will mention the files that were used to generate the documentation.
# The default value is: YES.

SHOW_USED_FILES        = YES

# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
# will remove the Files entry from the Quick Index and from the Folder Tree View
# (if specified).
# The default value is: YES.

SHOW_FILES             = YES

# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
# page. This will remove the Namespaces entry from the Quick Index and from the
# Folder Tree View (if specified).
# The default value is: YES.

SHOW_NAMESPACES        = YES

# The FILE_VERSION_FILTER tag can be used to specify a program or script that
# doxygen should invoke to get the current version for each file (typically from
# the version control system). Doxygen will invoke the program by executing (via
# popen()) the command command input-file, where command is the value of the
# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
# by doxygen. Whatever the program writes to standard output is used as the file
# version. For an example see the documentation.

FILE_VERSION_FILTER    =

# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
# by doxygen. The layout file controls the global structure of the generated
# output files in an output format independent way. To create the layout file
# that represents doxygen's defaults, run doxygen with the -l option. You can
# optionally specify a file name after the option, if omitted DoxygenLayout.xml
# will be used as the name of the layout file.
#
# Note that if you run doxygen from a directory containing a file called
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
# tag is left empty.

LAYOUT_FILE            =

# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
# the reference definitions. This must be a list of .bib files. The .bib
# extension is automatically appended if omitted. This requires the bibtex tool
# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
# For LaTeX the style of the bibliography can be controlled using
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
# search path. See also \cite for info how to create references.

CITE_BIB_FILES         =

#---------------------------------------------------------------------------
# Configuration options related to warning and progress messages
#---------------------------------------------------------------------------

# The QUIET tag can be used to turn on/off the messages that are generated to
# standard output by doxygen. If QUIET is set to YES this implies that the
# messages are off.
# The default value is: NO.

QUIET                  = NO

# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
# this implies that the warnings are on.
#
# Tip: Turn warnings on while writing the documentation.
# The default value is: YES.

WARNINGS               = YES

# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
# will automatically be disabled.
# The default value is: YES.

WARN_IF_UNDOCUMENTED   = YES

# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
# potential errors in the documentation, such as not documenting some parameters
# in a documented function, or documenting parameters that don't exist or using
# markup commands wrongly.
# The default value is: YES.

WARN_IF_DOC_ERROR      = YES

# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
# are documented, but have no documentation for their parameters or return
# value. If set to NO, doxygen will only warn about wrong or incomplete
# parameter documentation, but not about the absence of documentation.
# The default value is: NO.

WARN_NO_PARAMDOC       = NO

# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
# a warning is encountered.
# The default value is: NO.

WARN_AS_ERROR          = NO

# The WARN_FORMAT tag determines the format of the warning messages that doxygen
# can produce. The string should contain the $file, $line, and $text tags, which
# will be replaced by the file and line number from which the warning originated
# and the warning text. Optionally the format may contain $version, which will
# be replaced by the version of the file (if it could be obtained via
# FILE_VERSION_FILTER)
# The default value is: $file:$line: $text.

WARN_FORMAT            = "$file:$line: $text"

# The WARN_LOGFILE tag can be used to specify a file to which warning and error
# messages should be written. If left blank the output is written to standard
# error (stderr).

WARN_LOGFILE           =

#---------------------------------------------------------------------------
# Configuration options related to the input files
#---------------------------------------------------------------------------

# The INPUT tag is used to specify the files and/or directories that contain
# documented source files. You may enter file names like myfile.cpp or
# directories like /usr/src/myproject. Separate the files or directories with
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.

INPUT                  = src

# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
# documentation (see: http://www.gnu.org/software/libiconv) for the list of
# possible encodings.
# The default value is: UTF-8.

INPUT_ENCODING         = UTF-8

# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
# *.h) to filter out the source-files in the directories.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# read by doxygen.
#
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.

FILE_PATTERNS          = *.c \
                         *.cc \
                         *.cxx \
                         *.cpp \
                         *.c++ \
                         *.java \
                         *.ii \
                         *.ixx \
                         *.ipp \
                         *.i++ \
                         *.inl \
                         *.idl \
                         *.ddl \
                         *.odl \
                         *.h \
                         *.hh \
                         *.hxx \
                         *.hpp \
                         *.h++ \
                         *.cs \
                         *.d \
                         *.php \
                         *.php4 \
                         *.php5 \
                         *.phtml \
                         *.inc \
                         *.m \
                         *.markdown \
                         *.md \
                         *.mm \
                         *.dox \
                         *.py \
                         *.pyw \
                         *.f90 \
                         *.f95 \
                         *.f03 \
                         *.f08 \
                         *.f \
                         *.for \
                         *.tcl \
                         *.vhd \
                         *.vhdl \
                         *.ucf \
                         *.qsf

# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
# The default value is: NO.

RECURSIVE              = NO

# The EXCLUDE tag can be used to specify files and/or directories that should be
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
#
# Note that relative paths are relative to the directory from which doxygen is
# run.

EXCLUDE                =

# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
# from the input.
# The default value is: NO.

EXCLUDE_SYMLINKS       = NO

# If the value of the INPUT tag contains directories, you can use the
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories.
#
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories for example use the pattern */test/*

EXCLUDE_PATTERNS       = *-private.h \
*.c

# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
# output. The symbol name can be a fully qualified name, a word, or if the
# wildcard * is used, a substring. Examples: ANamespace, AClass,
# AClass::ANamespace, ANamespace::*Test
#
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories use the pattern */test/*

EXCLUDE_SYMBOLS        =

# The EXAMPLE_PATH tag can be used to specify one or more files or directories
# that contain example code fragments that are included (see the \include
# command).

EXAMPLE_PATH           =

# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
# *.h) to filter out the source-files in the directories. If left blank all
# files are included.

EXAMPLE_PATTERNS       = *

# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
# searched for input files to be used with the \include or \dontinclude commands
# irrespective of the value of the RECURSIVE tag.
# The default value is: NO.

EXAMPLE_RECURSIVE      = NO

# The IMAGE_PATH tag can be used to specify one or more files or directories
# that contain images that are to be included in the documentation (see the
# \image command).

IMAGE_PATH             =

# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
# by executing (via popen()) the command:
#
#  
#
# where  is the value of the INPUT_FILTER tag, and  is the
# name of an input file. Doxygen will then use the output that the filter
# program writes to standard output. If FILTER_PATTERNS is specified, this tag
# will be ignored.
#
# Note that the filter must not add or remove lines; it is applied before the
# code is scanned, but not when the output code is generated. If lines are added
# or removed, the anchors will not be placed correctly.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.

INPUT_FILTER           =

# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
# basis. Doxygen will compare the file name with each pattern and apply the
# filter if there is a match. The filters are a list of the form: pattern=filter
# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
# patterns match the file name, INPUT_FILTER is applied.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.

FILTER_PATTERNS        =

# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will also be used to filter the input files that are used for
# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
# The default value is: NO.

FILTER_SOURCE_FILES    = NO

# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
# it is also possible to disable source filtering for a specific pattern using
# *.ext= (so without naming a filter).
# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.

FILTER_SOURCE_PATTERNS =

# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
# is part of the input, its contents will be placed on the main page
# (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output.

USE_MDFILE_AS_MAINPAGE =

#---------------------------------------------------------------------------
# Configuration options related to source browsing
#---------------------------------------------------------------------------

# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
# generated. Documented entities will be cross-referenced with these sources.
#
# Note: To get rid of all source code in the generated output, make sure that
# also VERBATIM_HEADERS is set to NO.
# The default value is: NO.

SOURCE_BROWSER         = NO

# Setting the INLINE_SOURCES tag to YES will include the body of functions,
# classes and enums directly into the documentation.
# The default value is: NO.

INLINE_SOURCES         = NO

# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
# special comment blocks from generated source code fragments. Normal C, C++ and
# Fortran comments will always remain visible.
# The default value is: YES.

STRIP_CODE_COMMENTS    = YES

# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
# function all documented functions referencing it will be listed.
# The default value is: NO.

REFERENCED_BY_RELATION = NO

# If the REFERENCES_RELATION tag is set to YES then for each documented function
# all documented entities called/used by that function will be listed.
# The default value is: NO.

REFERENCES_RELATION    = NO

# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
# to YES then the hyperlinks from functions in REFERENCES_RELATION and
# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
# link to the documentation.
# The default value is: YES.

REFERENCES_LINK_SOURCE = YES

# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
# source code will show a tooltip with additional information such as prototype,
# brief description and links to the definition and documentation. Since this
# will make the HTML file larger and loading of large files a bit slower, you
# can opt to disable this feature.
# The default value is: YES.
# This tag requires that the tag SOURCE_BROWSER is set to YES.

SOURCE_TOOLTIPS        = YES

# If the USE_HTAGS tag is set to YES then the references to source code will
# point to the HTML generated by the htags(1) tool instead of doxygen built-in
# source browser. The htags tool is part of GNU's global source tagging system
# (see http://www.gnu.org/software/global/global.html). You will need version
# 4.8.6 or higher.
#
# To use it do the following:
# - Install the latest version of global
# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
# - Make sure the INPUT points to the root of the source tree
# - Run doxygen as normal
#
# Doxygen will invoke htags (and that will in turn invoke gtags), so these
# tools must be available from the command line (i.e. in the search path).
#
# The result: instead of the source browser generated by doxygen, the links to
# source code will now point to the output of htags.
# The default value is: NO.
# This tag requires that the tag SOURCE_BROWSER is set to YES.

USE_HTAGS              = NO

# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
# verbatim copy of the header file for each class for which an include is
# specified. Set to NO to disable this.
# See also: Section \class.
# The default value is: YES.

VERBATIM_HEADERS       = YES

#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------

# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
# compounds will be generated. Enable this if the project contains a lot of
# classes, structs, unions or interfaces.
# The default value is: YES.

ALPHABETICAL_INDEX     = YES

# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
# which the alphabetical index list will be split.
# Minimum value: 1, maximum value: 20, default value: 5.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.

COLS_IN_ALPHA_INDEX    = 5

# In case all classes in a project start with a common prefix, all classes will
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
# can be used to specify a prefix (or a list of prefixes) that should be ignored
# while generating the index headers.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.

IGNORE_PREFIX          =

#---------------------------------------------------------------------------
# Configuration options related to the HTML output
#---------------------------------------------------------------------------

# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
# The default value is: YES.

GENERATE_HTML          = YES

# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
# it.
# The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_OUTPUT            = html

# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
# generated HTML page (for example: .htm, .php, .asp).
# The default value is: .html.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_FILE_EXTENSION    = .html

# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
# each generated HTML page. If the tag is left blank doxygen will generate a
# standard header.
#
# To get valid HTML the header file that includes any scripts and style sheets
# that doxygen needs, which is dependent on the configuration options used (e.g.
# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
# default header using
# doxygen -w html new_header.html new_footer.html new_stylesheet.css
# YourConfigFile
# and then modify the file new_header.html. See also section "Doxygen usage"
# for information on how to generate the default header that doxygen normally
# uses.
# Note: The header is subject to change so you typically have to regenerate the
# default header when upgrading to a newer version of doxygen. For a description
# of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_HEADER            =

# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
# generated HTML page. If the tag is left blank doxygen will generate a standard
# footer. See HTML_HEADER for more information on how to generate a default
# footer and what special commands can be used inside the footer. See also
# section "Doxygen usage" for information on how to generate the default footer
# that doxygen normally uses.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_FOOTER            =

# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
# sheet that is used by each HTML page. It can be used to fine-tune the look of
# the HTML output. If left blank doxygen will generate a default style sheet.
# See also section "Doxygen usage" for information on how to generate the style
# sheet that doxygen normally uses.
# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
# it is more robust and this tag (HTML_STYLESHEET) will in the future become
# obsolete.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_STYLESHEET        =

# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
# cascading style sheets that are included after the standard style sheets
# created by doxygen. Using this option one can overrule certain style aspects.
# This is preferred over using HTML_STYLESHEET since it does not replace the
# standard style sheet and is therefore more robust against future updates.
# Doxygen will copy the style sheet files to the output directory.
# Note: The order of the extra style sheet files is of importance (e.g. the last
# style sheet in the list overrules the setting of the previous ones in the
# list). For an example see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_EXTRA_STYLESHEET  =

# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note
# that these files will be copied to the base HTML output directory. Use the
# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
# files will be copied as-is; there are no commands or markers available.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_EXTRA_FILES       =

# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
# this color. Hue is specified as an angle on a colorwheel, see
# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
# purple, and 360 is red again.
# Minimum value: 0, maximum value: 359, default value: 220.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_COLORSTYLE_HUE    = 220

# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
# in the HTML output. For a value of 0 the output will use grayscales only. A
# value of 255 will produce the most vivid colors.
# Minimum value: 0, maximum value: 255, default value: 100.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_COLORSTYLE_SAT    = 100

# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
# luminance component of the colors in the HTML output. Values below 100
# gradually make the output lighter, whereas values above 100 make the output
# darker. The value divided by 100 is the actual gamma applied, so 80 represents
# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
# change the gamma.
# Minimum value: 40, maximum value: 240, default value: 80.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_COLORSTYLE_GAMMA  = 80

# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting this
# to YES can help to show when doxygen was last run and thus if the
# documentation is up to date.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_TIMESTAMP         = NO

# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
# page has loaded.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_DYNAMIC_SECTIONS  = NO

# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
# shown in the various tree structured indices initially; the user can expand
# and collapse entries dynamically later on. Doxygen will expand the tree to
# such a level that at most the specified number of entries are visible (unless
# a fully collapsed tree already exceeds this amount). So setting the number of
# entries 1 will produce a full collapsed tree by default. 0 is a special value
# representing an infinite number of entries and will result in a full expanded
# tree by default.
# Minimum value: 0, maximum value: 9999, default value: 100.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_INDEX_NUM_ENTRIES = 100

# If the GENERATE_DOCSET tag is set to YES, additional index files will be
# generated that can be used as input for Apple's Xcode 3 integrated development
# environment (see: http://developer.apple.com/tools/xcode/), introduced with
# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
# Makefile in the HTML output directory. Running make will produce the docset in
# that directory and running make install will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
# for more information.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.

GENERATE_DOCSET        = NO

# This tag determines the name of the docset feed. A documentation feed provides
# an umbrella under which multiple documentation sets from a single provider
# (such as a company or product suite) can be grouped.
# The default value is: Doxygen generated docs.
# This tag requires that the tag GENERATE_DOCSET is set to YES.

DOCSET_FEEDNAME        = "Doxygen generated docs"

# This tag specifies a string that should uniquely identify the documentation
# set bundle. This should be a reverse domain-name style string, e.g.
# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_DOCSET is set to YES.

DOCSET_BUNDLE_ID       = org.doxygen.Project

# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
# the documentation publisher. This should be a reverse domain-name style
# string, e.g. com.mycompany.MyDocSet.documentation.
# The default value is: org.doxygen.Publisher.
# This tag requires that the tag GENERATE_DOCSET is set to YES.

DOCSET_PUBLISHER_ID    = org.doxygen.Publisher

# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
# The default value is: Publisher.
# This tag requires that the tag GENERATE_DOCSET is set to YES.

DOCSET_PUBLISHER_NAME  = Publisher

# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
# Windows.
#
# The HTML Help Workshop contains a compiler that can convert all HTML output
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
# files are now used as the Windows 98 help format, and will replace the old
# Windows help format (.hlp) on all Windows platforms in the future. Compressed
# HTML files also contain an index, a table of contents, and you can search for
# words in the documentation. The HTML workshop also contains a viewer for
# compressed HTML files.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.

GENERATE_HTMLHELP      = NO

# The CHM_FILE tag can be used to specify the file name of the resulting .chm
# file. You can add a path in front of the file if the result should not be
# written to the html output directory.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.

CHM_FILE               =

# The HHC_LOCATION tag can be used to specify the location (absolute path
# including file name) of the HTML help compiler (hhc.exe). If non-empty,
# doxygen will try to run the HTML help compiler on the generated index.hhp.
# The file has to be specified with full path.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.

HHC_LOCATION           =

# The GENERATE_CHI flag controls if a separate .chi index file is generated
# (YES) or that it should be included in the master .chm file (NO).
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.

GENERATE_CHI           = NO

# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
# and project file content.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.

CHM_INDEX_ENCODING     =

# The BINARY_TOC flag controls whether a binary table of contents is generated
# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
# enables the Previous and Next buttons.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.

BINARY_TOC             = NO

# The TOC_EXPAND flag can be set to YES to add extra items for group members to
# the table of contents of the HTML help documentation and to the tree view.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.

TOC_EXPAND             = NO

# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
# (.qch) of the generated HTML documentation.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.

GENERATE_QHP           = NO

# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
# the file name of the resulting .qch file. The path specified is relative to
# the HTML output folder.
# This tag requires that the tag GENERATE_QHP is set to YES.

QCH_FILE               =

# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
# Project output. For more information please see Qt Help Project / Namespace
# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_QHP is set to YES.

QHP_NAMESPACE          = org.doxygen.Project

# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
# Help Project output. For more information please see Qt Help Project / Virtual
# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
# folders).
# The default value is: doc.
# This tag requires that the tag GENERATE_QHP is set to YES.

QHP_VIRTUAL_FOLDER     = doc

# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
# filter to add. For more information please see Qt Help Project / Custom
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.

QHP_CUST_FILTER_NAME   =

# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see Qt Help Project / Custom
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.

QHP_CUST_FILTER_ATTRS  =

# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's filter section matches. Qt Help Project / Filter Attributes (see:
# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
# This tag requires that the tag GENERATE_QHP is set to YES.

QHP_SECT_FILTER_ATTRS  =

# The QHG_LOCATION tag can be used to specify the location of Qt's
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
# generated .qhp file.
# This tag requires that the tag GENERATE_QHP is set to YES.

QHG_LOCATION           =

# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
# generated, together with the HTML files, they form an Eclipse help plugin. To
# install this plugin and make it available under the help contents menu in
# Eclipse, the contents of the directory containing the HTML and XML files needs
# to be copied into the plugins directory of eclipse. The name of the directory
# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
# After copying Eclipse needs to be restarted before the help appears.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.

GENERATE_ECLIPSEHELP   = NO

# A unique identifier for the Eclipse help plugin. When installing the plugin
# the directory name containing the HTML and XML files should also have this
# name. Each documentation set should have its own identifier.
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.

ECLIPSE_DOC_ID         = org.doxygen.Project

# If you want full control over the layout of the generated HTML pages it might
# be necessary to disable the index and replace it with your own. The
# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
# of each HTML page. A value of NO enables the index and the value YES disables
# it. Since the tabs in the index contain the same information as the navigation
# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.

DISABLE_INDEX          = NO

# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
# structure should be generated to display hierarchical information. If the tag
# value is set to YES, a side panel will be generated containing a tree-like
# index structure (just like the one that is generated for HTML Help). For this
# to work a browser that supports JavaScript, DHTML, CSS and frames is required
# (i.e. any modern browser). Windows users are probably better off using the
# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
# further fine-tune the look of the index. As an example, the default style
# sheet generated by doxygen has an example that shows how to put an image at
# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
# the same information as the tab index, you could consider setting
# DISABLE_INDEX to YES when enabling this option.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.

GENERATE_TREEVIEW      = NO

# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
# doxygen will group on one line in the generated HTML documentation.
#
# Note that a value of 0 will completely suppress the enum values from appearing
# in the overview section.
# Minimum value: 0, maximum value: 20, default value: 4.
# This tag requires that the tag GENERATE_HTML is set to YES.

ENUM_VALUES_PER_LINE   = 4

# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
# to set the initial width (in pixels) of the frame in which the tree is shown.
# Minimum value: 0, maximum value: 1500, default value: 250.
# This tag requires that the tag GENERATE_HTML is set to YES.

TREEVIEW_WIDTH         = 250

# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
# external symbols imported via tag files in a separate window.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.

EXT_LINKS_IN_WINDOW    = NO

# Use this tag to change the font size of LaTeX formulas included as images in
# the HTML documentation. When you change the font size after a successful
# doxygen run you need to manually remove any form_*.png images from the HTML
# output directory to force them to be regenerated.
# Minimum value: 8, maximum value: 50, default value: 10.
# This tag requires that the tag GENERATE_HTML is set to YES.

FORMULA_FONTSIZE       = 10

# Use the FORMULA_TRANPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are not
# supported properly for IE 6.0, but are supported on all modern browsers.
#
# Note that when changing this option you need to delete any form_*.png files in
# the HTML output directory before the changes have effect.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.

FORMULA_TRANSPARENT    = YES

# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
# http://www.mathjax.org) which uses client side Javascript for the rendering
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
# installed or if you want to formulas look prettier in the HTML output. When
# enabled you may also need to install MathJax separately and configure the path
# to it using the MATHJAX_RELPATH option.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.

USE_MATHJAX            = NO

# When MathJax is enabled you can set the default output format to be used for
# the MathJax output. See the MathJax site (see:
# http://docs.mathjax.org/en/latest/output.html) for more details.
# Possible values are: HTML-CSS (which is slower, but has the best
# compatibility), NativeMML (i.e. MathML) and SVG.
# The default value is: HTML-CSS.
# This tag requires that the tag USE_MATHJAX is set to YES.

MATHJAX_FORMAT         = HTML-CSS

# When MathJax is enabled you need to specify the location relative to the HTML
# output directory using the MATHJAX_RELPATH option. The destination directory
# should contain the MathJax.js script. For instance, if the mathjax directory
# is located at the same level as the HTML output directory, then
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
# MathJax from http://www.mathjax.org before deployment.
# The default value is: http://cdn.mathjax.org/mathjax/latest.
# This tag requires that the tag USE_MATHJAX is set to YES.

MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest

# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
# extension names that should be enabled during MathJax rendering. For example
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
# This tag requires that the tag USE_MATHJAX is set to YES.

MATHJAX_EXTENSIONS     =

# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
# of code that will be used on startup of the MathJax code. See the MathJax site
# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
# example see the documentation.
# This tag requires that the tag USE_MATHJAX is set to YES.

MATHJAX_CODEFILE       =

# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
# the HTML output. The underlying search engine uses javascript and DHTML and
# should work on any modern browser. Note that when using HTML help
# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
# there is already a search function so this one should typically be disabled.
# For large projects the javascript based search engine can be slow, then
# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
# search using the keyboard; to jump to the search box use  + S
# (what the  is depends on the OS and browser, but it is typically
# , /