mirror of
https://github.com/bitwarden/directory-connector
synced 2025-12-26 05:03:23 +00:00
Compare commits
16 Commits
ac/pm-2489
...
v2025.10.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57a3ef04cc | ||
|
|
4e21b28276 | ||
|
|
1c2a0c677b | ||
|
|
5666f09e89 | ||
|
|
b13895bdd6 | ||
|
|
29fc4ad61e | ||
|
|
f722196149 | ||
|
|
a4ec6df118 | ||
|
|
01e60bf090 | ||
|
|
7c27202dab | ||
|
|
77ea7a395d | ||
|
|
a259de8b26 | ||
|
|
06dbc14136 | ||
|
|
e74546e8c3 | ||
|
|
5ac0cc408e | ||
|
|
9044f94f43 |
6
.github/CODEOWNERS
vendored
6
.github/CODEOWNERS
vendored
@@ -6,3 +6,9 @@
|
|||||||
|
|
||||||
# Default file owners.
|
# Default file owners.
|
||||||
* @bitwarden/team-admin-console-dev
|
* @bitwarden/team-admin-console-dev
|
||||||
|
|
||||||
|
# Docker-related files
|
||||||
|
**/Dockerfile @bitwarden/team-appsec @bitwarden/dept-bre
|
||||||
|
**/*.dockerignore @bitwarden/team-appsec @bitwarden/dept-bre
|
||||||
|
**/entrypoint.sh @bitwarden/team-appsec @bitwarden/dept-bre
|
||||||
|
**/docker-compose.yml @bitwarden/team-appsec @bitwarden/dept-bre
|
||||||
|
|||||||
11
.github/renovate.json5
vendored
11
.github/renovate.json5
vendored
@@ -8,12 +8,6 @@
|
|||||||
matchManagers: ["github-actions"],
|
matchManagers: ["github-actions"],
|
||||||
matchUpdateTypes: ["minor", "patch"],
|
matchUpdateTypes: ["minor", "patch"],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
groupName: "Google Libraries",
|
|
||||||
matchPackagePatterns: ["google-auth-library", "googleapis"],
|
|
||||||
matchManagers: ["npm"],
|
|
||||||
groupSlug: "google-libraries",
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
ignoreDeps: [
|
ignoreDeps: [
|
||||||
// yao-pkg is used to create a single executable application bundle for the CLI.
|
// yao-pkg is used to create a single executable application bundle for the CLI.
|
||||||
@@ -21,5 +15,10 @@
|
|||||||
// This must be manually vetted by our appsec team before upgrading.
|
// This must be manually vetted by our appsec team before upgrading.
|
||||||
// It is excluded from renovate to avoid accidentally upgrading to a non-vetted version.
|
// It is excluded from renovate to avoid accidentally upgrading to a non-vetted version.
|
||||||
"@yao-pkg/pkg",
|
"@yao-pkg/pkg",
|
||||||
|
// googleapis uses ESM after 149.0.0 so we are not upgrading it until we have ESM support.
|
||||||
|
// They release new versions every couple of weeks so ignoring it at the dependency dashboard
|
||||||
|
// level is not sufficient.
|
||||||
|
// FIXME: remove and upgrade when we have ESM support.
|
||||||
|
"googleapis",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
84
.github/workflows/build.yml
vendored
84
.github/workflows/build.yml
vendored
@@ -23,20 +23,22 @@ jobs:
|
|||||||
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
|
node_version: ${{ steps.retrieve-node-version.outputs.node_version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Get Package Version
|
- name: Get Package Version
|
||||||
id: retrieve-version
|
id: retrieve-version
|
||||||
run: |
|
run: |
|
||||||
PKG_VERSION=$(jq -r .version package.json)
|
PKG_VERSION=$(jq -r .version package.json)
|
||||||
echo "package_version=$PKG_VERSION" >> $GITHUB_OUTPUT
|
echo "package_version=$PKG_VERSION" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- name: Get Node Version
|
- name: Get Node Version
|
||||||
id: retrieve-node-version
|
id: retrieve-node-version
|
||||||
run: |
|
run: |
|
||||||
NODE_NVMRC=$(cat .nvmrc)
|
NODE_NVMRC=$(cat .nvmrc)
|
||||||
NODE_VERSION=${NODE_NVMRC/v/''}
|
NODE_VERSION=${NODE_NVMRC/v/''}
|
||||||
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
|
echo "node_version=$NODE_VERSION" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
linux-cli:
|
linux-cli:
|
||||||
name: Build Linux CLI
|
name: Build Linux CLI
|
||||||
@@ -49,7 +51,9 @@ jobs:
|
|||||||
contents: read
|
contents: read
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||||
@@ -61,7 +65,7 @@ jobs:
|
|||||||
- name: Update NPM
|
- name: Update NPM
|
||||||
run: |
|
run: |
|
||||||
npm install -g node-gyp
|
npm install -g node-gyp
|
||||||
node-gyp install $(node -v)
|
node-gyp install "$(node -v)"
|
||||||
|
|
||||||
- name: Keytar
|
- name: Keytar
|
||||||
run: |
|
run: |
|
||||||
@@ -72,8 +76,8 @@ jobs:
|
|||||||
keytarUrl="https://github.com/atom/node-keytar/releases/download/v$keytarVersion/$keytarTarGz"
|
keytarUrl="https://github.com/atom/node-keytar/releases/download/v$keytarVersion/$keytarTarGz"
|
||||||
|
|
||||||
mkdir -p ./keytar/linux
|
mkdir -p ./keytar/linux
|
||||||
wget $keytarUrl -O ./keytar/linux/$keytarTarGz
|
wget "$keytarUrl" -O "./keytar/linux/$keytarTarGz"
|
||||||
tar -xvf ./keytar/linux/$keytarTarGz -C ./keytar/linux
|
tar -xvf "./keytar/linux/$keytarTarGz" -C ./keytar/linux
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
run: npm install
|
run: npm install
|
||||||
@@ -82,19 +86,19 @@ jobs:
|
|||||||
run: npm run dist:cli:lin
|
run: npm run dist:cli:lin
|
||||||
|
|
||||||
- name: Zip
|
- name: Zip
|
||||||
run: zip -j dist-cli/bwdc-linux-$_PACKAGE_VERSION.zip dist-cli/linux/bwdc keytar/linux/build/Release/keytar.node
|
run: zip -j "dist-cli/bwdc-linux-$_PACKAGE_VERSION.zip" "dist-cli/linux/bwdc" "keytar/linux/build/Release/keytar.node"
|
||||||
|
|
||||||
- name: Version Test
|
- name: Version Test
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt install libsecret-1-0 dbus-x11 gnome-keyring
|
sudo apt install libsecret-1-0 dbus-x11 gnome-keyring
|
||||||
eval $(dbus-launch --sh-syntax)
|
eval "$(dbus-launch --sh-syntax)"
|
||||||
|
|
||||||
eval $(echo -n "" | /usr/bin/gnome-keyring-daemon --login)
|
eval "$(echo -n "" | /usr/bin/gnome-keyring-daemon --login)"
|
||||||
eval $(/usr/bin/gnome-keyring-daemon --components=secrets --start)
|
eval "$(/usr/bin/gnome-keyring-daemon --components=secrets --start)"
|
||||||
|
|
||||||
mkdir -p test/linux
|
mkdir -p test/linux
|
||||||
unzip ./dist-cli/bwdc-linux-$_PACKAGE_VERSION.zip -d ./test/linux
|
unzip "./dist-cli/bwdc-linux-$_PACKAGE_VERSION.zip" -d ./test/linux
|
||||||
|
|
||||||
testVersion=$(./test/linux/bwdc -v)
|
testVersion=$(./test/linux/bwdc -v)
|
||||||
|
|
||||||
@@ -125,7 +129,9 @@ jobs:
|
|||||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||||
@@ -137,7 +143,7 @@ jobs:
|
|||||||
- name: Update NPM
|
- name: Update NPM
|
||||||
run: |
|
run: |
|
||||||
npm install -g node-gyp
|
npm install -g node-gyp
|
||||||
node-gyp install $(node -v)
|
node-gyp install "$(node -v)"
|
||||||
|
|
||||||
- name: Keytar
|
- name: Keytar
|
||||||
run: |
|
run: |
|
||||||
@@ -148,8 +154,8 @@ jobs:
|
|||||||
keytarUrl="https://github.com/atom/node-keytar/releases/download/v$keytarVersion/$keytarTarGz"
|
keytarUrl="https://github.com/atom/node-keytar/releases/download/v$keytarVersion/$keytarTarGz"
|
||||||
|
|
||||||
mkdir -p ./keytar/macos
|
mkdir -p ./keytar/macos
|
||||||
wget $keytarUrl -O ./keytar/macos/$keytarTarGz
|
wget "$keytarUrl" -O "./keytar/macos/$keytarTarGz"
|
||||||
tar -xvf ./keytar/macos/$keytarTarGz -C ./keytar/macos
|
tar -xvf "./keytar/macos/$keytarTarGz" -C ./keytar/macos
|
||||||
|
|
||||||
- name: Install
|
- name: Install
|
||||||
run: npm install
|
run: npm install
|
||||||
@@ -158,12 +164,12 @@ jobs:
|
|||||||
run: npm run dist:cli:mac
|
run: npm run dist:cli:mac
|
||||||
|
|
||||||
- name: Zip
|
- name: Zip
|
||||||
run: zip -j dist-cli/bwdc-macos-$_PACKAGE_VERSION.zip dist-cli/macos/bwdc keytar/macos/build/Release/keytar.node
|
run: zip -j "dist-cli/bwdc-macos-$_PACKAGE_VERSION.zip" "dist-cli/macos/bwdc" "keytar/macos/build/Release/keytar.node"
|
||||||
|
|
||||||
- name: Version Test
|
- name: Version Test
|
||||||
run: |
|
run: |
|
||||||
mkdir -p test/macos
|
mkdir -p test/macos
|
||||||
unzip ./dist-cli/bwdc-macos-$_PACKAGE_VERSION.zip -d ./test/macos
|
unzip "./dist-cli/bwdc-macos-$_PACKAGE_VERSION.zip" -d ./test/macos
|
||||||
|
|
||||||
testVersion=$(./test/macos/bwdc -v)
|
testVersion=$(./test/macos/bwdc -v)
|
||||||
|
|
||||||
@@ -194,7 +200,9 @@ jobs:
|
|||||||
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
_NODE_VERSION: ${{ needs.setup.outputs.node_version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Setup Windows builder
|
- name: Setup Windows builder
|
||||||
run: |
|
run: |
|
||||||
@@ -241,7 +249,7 @@ jobs:
|
|||||||
- name: Version Test
|
- name: Version Test
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
Expand-Archive -Path "dist-cli\bwdc-windows-${{ env._PACKAGE_VERSION }}.zip" -DestinationPath "test\windows"
|
Expand-Archive -Path "dist-cli\bwdc-windows-$env:_PACKAGE_VERSION.zip" -DestinationPath "test\windows"
|
||||||
$testVersion = Invoke-Expression '& .\test\windows\bwdc.exe -v'
|
$testVersion = Invoke-Expression '& .\test\windows\bwdc.exe -v'
|
||||||
echo "version: ${env:_PACKAGE_VERSION}"
|
echo "version: ${env:_PACKAGE_VERSION}"
|
||||||
echo "testVersion: $testVersion"
|
echo "testVersion: $testVersion"
|
||||||
@@ -271,7 +279,9 @@ jobs:
|
|||||||
HUSKY: 0
|
HUSKY: 0
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||||
@@ -369,7 +379,9 @@ jobs:
|
|||||||
HUSKY: 0
|
HUSKY: 0
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||||
@@ -381,7 +393,7 @@ jobs:
|
|||||||
- name: Update NPM
|
- name: Update NPM
|
||||||
run: |
|
run: |
|
||||||
npm install -g node-gyp
|
npm install -g node-gyp
|
||||||
node-gyp install $(node -v)
|
node-gyp install "$(node -v)"
|
||||||
|
|
||||||
- name: Set up environment
|
- name: Set up environment
|
||||||
run: |
|
run: |
|
||||||
@@ -427,7 +439,9 @@ jobs:
|
|||||||
HUSKY: 0
|
HUSKY: 0
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||||
@@ -439,7 +453,7 @@ jobs:
|
|||||||
- name: Update NPM
|
- name: Update NPM
|
||||||
run: |
|
run: |
|
||||||
npm install -g node-gyp
|
npm install -g node-gyp
|
||||||
node-gyp install $(node -v)
|
node-gyp install "$(node -v)"
|
||||||
|
|
||||||
- name: Print environment
|
- name: Print environment
|
||||||
run: |
|
run: |
|
||||||
@@ -464,16 +478,16 @@ jobs:
|
|||||||
|
|
||||||
- name: Get certificates
|
- name: Get certificates
|
||||||
run: |
|
run: |
|
||||||
mkdir -p $HOME/certificates
|
mkdir -p "$HOME/certificates"
|
||||||
|
|
||||||
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-app-cert |
|
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-app-cert |
|
||||||
jq -r .value | base64 -d > $HOME/certificates/devid-app-cert.p12
|
jq -r .value | base64 -d > "$HOME/certificates/devid-app-cert.p12"
|
||||||
|
|
||||||
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-installer-cert |
|
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/devid-installer-cert |
|
||||||
jq -r .value | base64 -d > $HOME/certificates/devid-installer-cert.p12
|
jq -r .value | base64 -d > "$HOME/certificates/devid-installer-cert.p12"
|
||||||
|
|
||||||
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert |
|
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert |
|
||||||
jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12
|
jq -r .value | base64 -d > "$HOME/certificates/macdev-cert.p12"
|
||||||
|
|
||||||
- name: Log out from Azure
|
- name: Log out from Azure
|
||||||
uses: bitwarden/gh-actions/azure-logout@main
|
uses: bitwarden/gh-actions/azure-logout@main
|
||||||
@@ -482,9 +496,9 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
KEYCHAIN_PASSWORD: ${{ steps.get-kv-secrets.outputs.KEYCHAIN-PASSWORD }}
|
KEYCHAIN_PASSWORD: ${{ steps.get-kv-secrets.outputs.KEYCHAIN-PASSWORD }}
|
||||||
run: |
|
run: |
|
||||||
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
|
security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
|
||||||
security default-keychain -s build.keychain
|
security default-keychain -s build.keychain
|
||||||
security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain
|
security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
|
||||||
security set-keychain-settings -lut 1200 build.keychain
|
security set-keychain-settings -lut 1200 build.keychain
|
||||||
|
|
||||||
security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \
|
security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \
|
||||||
@@ -496,12 +510,12 @@ jobs:
|
|||||||
security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \
|
security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \
|
||||||
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
|
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
|
||||||
|
|
||||||
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $KEYCHAIN_PASSWORD build.keychain
|
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain
|
||||||
|
|
||||||
- name: Load package version
|
- name: Load package version
|
||||||
run: |
|
run: |
|
||||||
$rootPath = $env:GITHUB_WORKSPACE;
|
$rootPath = $env:GITHUB_WORKSPACE;
|
||||||
$packageVersion = (Get-Content -Raw -Path $rootPath\package.json | ConvertFrom-Json).version;
|
$packageVersion = (Get-Content -Raw -Path "$rootPath\package.json" | ConvertFrom-Json).version;
|
||||||
|
|
||||||
Write-Output "Setting package version to $packageVersion";
|
Write-Output "Setting package version to $packageVersion";
|
||||||
Write-Output "PACKAGE_VERSION=$packageVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append;
|
Write-Output "PACKAGE_VERSION=$packageVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append;
|
||||||
@@ -511,10 +525,12 @@ jobs:
|
|||||||
run: npm install
|
run: npm install
|
||||||
|
|
||||||
- name: Set up private auth key
|
- name: Set up private auth key
|
||||||
|
env:
|
||||||
|
_APP_STORE_CONNECT_AUTH_KEY: ${{ steps.get-kv-secrets.outputs.APP-STORE-CONNECT-AUTH-KEY }}
|
||||||
run: |
|
run: |
|
||||||
mkdir ~/private_keys
|
mkdir ~/private_keys
|
||||||
cat << EOF > ~/private_keys/AuthKey_UFD296548T.p8
|
cat << EOF > ~/private_keys/AuthKey_UFD296548T.p8
|
||||||
${{ steps.get-kv-secrets.outputs.APP-STORE-CONNECT-AUTH-KEY }}
|
${_APP_STORE_CONNECT_AUTH_KEY}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
- name: Build application
|
- name: Build application
|
||||||
|
|||||||
6
.github/workflows/integration-test.yml
vendored
6
.github/workflows/integration-test.yml
vendored
@@ -29,14 +29,16 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repo
|
- name: Check out repo
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Get Node version
|
- name: Get Node version
|
||||||
id: retrieve-node-version
|
id: retrieve-node-version
|
||||||
run: |
|
run: |
|
||||||
NODE_NVMRC=$(cat .nvmrc)
|
NODE_NVMRC=$(cat .nvmrc)
|
||||||
NODE_VERSION=${NODE_NVMRC/v/''}
|
NODE_VERSION=${NODE_NVMRC/v/''}
|
||||||
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
|
echo "node_version=$NODE_VERSION" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||||
|
|||||||
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -26,7 +26,9 @@ jobs:
|
|||||||
release_version: ${{ steps.version.outputs.version }}
|
release_version: ${{ steps.version.outputs.version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Branch check
|
- name: Branch check
|
||||||
if: ${{ inputs.release_type != 'Dry Run' }}
|
if: ${{ inputs.release_type != 'Dry Run' }}
|
||||||
|
|||||||
6
.github/workflows/test.yml
vendored
6
.github/workflows/test.yml
vendored
@@ -22,14 +22,16 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repo
|
- name: Check out repo
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Get Node version
|
- name: Get Node version
|
||||||
id: retrieve-node-version
|
id: retrieve-node-version
|
||||||
run: |
|
run: |
|
||||||
NODE_NVMRC=$(cat .nvmrc)
|
NODE_NVMRC=$(cat .nvmrc)
|
||||||
NODE_VERSION=${NODE_NVMRC/v/''}
|
NODE_VERSION=${NODE_NVMRC/v/''}
|
||||||
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
|
echo "node_version=$NODE_VERSION" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
|
||||||
|
|||||||
30
.github/workflows/version-bump.yml
vendored
30
.github/workflows/version-bump.yml
vendored
@@ -49,9 +49,10 @@ jobs:
|
|||||||
private-key: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-KEY }}
|
private-key: ${{ steps.get-kv-secrets.outputs.BW-GHAPP-KEY }}
|
||||||
|
|
||||||
- name: Checkout Branch
|
- name: Checkout Branch
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||||
with:
|
with:
|
||||||
token: ${{ steps.app-token.outputs.token }}
|
token: ${{ steps.app-token.outputs.token }}
|
||||||
|
persist-credentials: true
|
||||||
|
|
||||||
- name: Setup git
|
- name: Setup git
|
||||||
run: |
|
run: |
|
||||||
@@ -62,7 +63,7 @@ jobs:
|
|||||||
id: current-version
|
id: current-version
|
||||||
run: |
|
run: |
|
||||||
CURRENT_VERSION=$(cat package.json | jq -r '.version')
|
CURRENT_VERSION=$(cat package.json | jq -r '.version')
|
||||||
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
|
echo "version=$CURRENT_VERSION" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- name: Verify input version
|
- name: Verify input version
|
||||||
if: ${{ inputs.version_number_override != '' }}
|
if: ${{ inputs.version_number_override != '' }}
|
||||||
@@ -77,8 +78,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if version is newer.
|
# Check if version is newer.
|
||||||
printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V
|
if printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V; then
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo "Version check successful."
|
echo "Version check successful."
|
||||||
else
|
else
|
||||||
echo "Version check failed."
|
echo "Version check failed."
|
||||||
@@ -110,26 +110,34 @@ jobs:
|
|||||||
|
|
||||||
- name: Set final version output
|
- name: Set final version output
|
||||||
id: set-final-version-output
|
id: set-final-version-output
|
||||||
|
env:
|
||||||
|
_BUMP_VERSION_OVERRIDE_OUTCOME: ${{ steps.bump-version-override.outcome }}
|
||||||
|
_INPUT_VERSION_NUMBER_OVERRIDE: ${{ inputs.version_number_override }}
|
||||||
|
_BUMP_VERSION_AUTOMATIC_OUTCOME: ${{ steps.bump-version-automatic.outcome }}
|
||||||
|
_CALCULATE_NEXT_VERSION: ${{ steps.calculate-next-version.outputs.version }}
|
||||||
|
|
||||||
run: |
|
run: |
|
||||||
if [[ "${{ steps.bump-version-override.outcome }}" == "success" ]]; then
|
if [[ "$_BUMP_VERSION_OVERRIDE_OUTCOME" == "success" ]]; then
|
||||||
echo "version=${{ inputs.version_number_override }}" >> $GITHUB_OUTPUT
|
echo "version=$_INPUT_VERSION_NUMBER_OVERRIDE" >> "$GITHUB_OUTPUT"
|
||||||
elif [[ "${{ steps.bump-version-automatic.outcome }}" == "success" ]]; then
|
elif [[ "$_BUMP_VERSION_AUTOMATIC_OUTCOME" == "success" ]]; then
|
||||||
echo "version=${{ steps.calculate-next-version.outputs.version }}" >> $GITHUB_OUTPUT
|
echo "version=$_CALCULATE_NEXT_VERSION" >> "$GITHUB_OUTPUT"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Check if version changed
|
- name: Check if version changed
|
||||||
id: version-changed
|
id: version-changed
|
||||||
run: |
|
run: |
|
||||||
if [ -n "$(git status --porcelain)" ]; then
|
if [ -n "$(git status --porcelain)" ]; then
|
||||||
echo "changes_to_commit=TRUE" >> $GITHUB_OUTPUT
|
echo "changes_to_commit=TRUE" >> "$GITHUB_OUTPUT"
|
||||||
else
|
else
|
||||||
echo "changes_to_commit=FALSE" >> $GITHUB_OUTPUT
|
echo "changes_to_commit=FALSE" >> "$GITHUB_OUTPUT"
|
||||||
echo "No changes to commit!";
|
echo "No changes to commit!";
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Commit files
|
- name: Commit files
|
||||||
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
|
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
|
||||||
run: git commit -m "Bumped version to ${{ steps.set-final-version-output.outputs.version }}" -a
|
env:
|
||||||
|
_VERSION: ${{ steps.set-final-version-output.outputs.version }}
|
||||||
|
run: git commit -m "Bumped version to $_VERSION" -a
|
||||||
|
|
||||||
- name: Push changes
|
- name: Push changes
|
||||||
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
|
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
open-ldap:
|
open-ldap:
|
||||||
image: bitnami/openldap:latest
|
image: bitnamilegacy/openldap:latest
|
||||||
hostname: openldap
|
hostname: openldap
|
||||||
environment:
|
environment:
|
||||||
- LDAP_ADMIN_USERNAME=admin
|
- LDAP_ADMIN_USERNAME=admin
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { InjectFlags, InjectOptions, Injector, ProviderToken } from "@angular/core";
|
import { InjectOptions, Injector, ProviderToken } from "@angular/core";
|
||||||
|
|
||||||
export class ModalInjector implements Injector {
|
export class ModalInjector implements Injector {
|
||||||
constructor(
|
constructor(
|
||||||
@@ -12,8 +12,7 @@ export class ModalInjector implements Injector {
|
|||||||
options: InjectOptions & { optional?: false },
|
options: InjectOptions & { optional?: false },
|
||||||
): T;
|
): T;
|
||||||
get<T>(token: ProviderToken<T>, notFoundValue: null, options: InjectOptions): T;
|
get<T>(token: ProviderToken<T>, notFoundValue: null, options: InjectOptions): T;
|
||||||
get<T>(token: ProviderToken<T>, notFoundValue?: T, options?: InjectOptions | InjectFlags): T;
|
get<T>(token: ProviderToken<T>, notFoundValue?: T, options?: InjectOptions): T;
|
||||||
get<T>(token: ProviderToken<T>, notFoundValue?: T, flags?: InjectFlags): T;
|
|
||||||
get(token: any, notFoundValue?: any): any;
|
get(token: any, notFoundValue?: any): any;
|
||||||
get(token: any, notFoundValue?: any, flags?: any): any {
|
get(token: any, notFoundValue?: any, flags?: any): any {
|
||||||
return this._additionalTokens.get(token) ?? this._parentInjector.get<any>(token, notFoundValue);
|
return this._additionalTokens.get(token) ?? this._parentInjector.get<any>(token, notFoundValue);
|
||||||
|
|||||||
@@ -35,6 +35,29 @@ const data: Jsonify<GroupEntry>[] = [
|
|||||||
externalId: "cn=Cleaners,ou=Janitorial,dc=bitwarden,dc=com",
|
externalId: "cn=Cleaners,ou=Janitorial,dc=bitwarden,dc=com",
|
||||||
name: "Cleaners",
|
name: "Cleaners",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
userMemberExternalIds: [
|
||||||
|
"cn=Painterson Miki,ou=Product Development,dc=bitwarden,dc=com",
|
||||||
|
"cn=Virgina Pichocki,ou=Product Development,dc=bitwarden,dc=com",
|
||||||
|
"cn=Steffen Carsten,ou=Product Development,dc=bitwarden,dc=com",
|
||||||
|
],
|
||||||
|
groupMemberReferenceIds: [],
|
||||||
|
users: [],
|
||||||
|
referenceId: "cn=DevOps Team,dc=bitwarden,dc=com",
|
||||||
|
externalId: "cn=DevOps Team,dc=bitwarden,dc=com",
|
||||||
|
name: "DevOps Team",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
userMemberExternalIds: [
|
||||||
|
"cn=Angus Merizzi,ou=Management,dc=bitwarden,dc=com",
|
||||||
|
"cn=Grissel Currer,ou=Management,dc=bitwarden,dc=com",
|
||||||
|
],
|
||||||
|
groupMemberReferenceIds: [],
|
||||||
|
users: [],
|
||||||
|
referenceId: "cn=Security Team,dc=bitwarden,dc=com",
|
||||||
|
externalId: "cn=Security Team,dc=bitwarden,dc=com",
|
||||||
|
name: "Security Team",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const groupFixtures = data.map((g) => GroupEntry.fromJSON(g));
|
export const groupFixtures = data.map((g) => GroupEntry.fromJSON(g));
|
||||||
|
|||||||
@@ -689,3 +689,26 @@ pager: +1 804 815-3661
|
|||||||
roomNumber: 9273
|
roomNumber: 9273
|
||||||
manager: cn=Inga Schnirer,ou=Product Testing,dc=bitwarden, dc=com
|
manager: cn=Inga Schnirer,ou=Product Testing,dc=bitwarden, dc=com
|
||||||
secretary: cn=Keven Gilleland,ou=Administrative,dc=bitwarden, dc=com
|
secretary: cn=Keven Gilleland,ou=Administrative,dc=bitwarden, dc=com
|
||||||
|
|
||||||
|
# DevOps Team and Security Team identify their members by the member uid attribute,
|
||||||
|
# instead of the member Dn attribute.
|
||||||
|
# These test that group membership by uid works correctly.
|
||||||
|
|
||||||
|
dn: cn=DevOps Team,dc=bitwarden,dc=com
|
||||||
|
changetype: add
|
||||||
|
cn: DevOps Team
|
||||||
|
gidnumber: 800
|
||||||
|
memberuid: mikip
|
||||||
|
memberuid: pichockv
|
||||||
|
memberuid: carstens
|
||||||
|
objectclass: posixGroup
|
||||||
|
objectclass: top
|
||||||
|
|
||||||
|
dn: cn=Security Team,dc=bitwarden,dc=com
|
||||||
|
changetype: add
|
||||||
|
cn: Security Team
|
||||||
|
gidnumber: 900
|
||||||
|
memberuid: merizzia
|
||||||
|
memberuid: currerg
|
||||||
|
objectclass: posixGroup
|
||||||
|
objectclass: top
|
||||||
10181
package-lock.json
generated
10181
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
54
package.json
54
package.json
@@ -2,7 +2,7 @@
|
|||||||
"name": "@bitwarden/directory-connector",
|
"name": "@bitwarden/directory-connector",
|
||||||
"productName": "Bitwarden Directory Connector",
|
"productName": "Bitwarden Directory Connector",
|
||||||
"description": "Sync your user directory to your Bitwarden organization.",
|
"description": "Sync your user directory to your Bitwarden organization.",
|
||||||
"version": "2025.8.0",
|
"version": "2025.10.0",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"bitwarden",
|
"bitwarden",
|
||||||
"password",
|
"password",
|
||||||
@@ -73,15 +73,15 @@
|
|||||||
"test:types": "npx tsc --noEmit"
|
"test:types": "npx tsc --noEmit"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "19.2.15",
|
"@angular-devkit/build-angular": "20.3.3",
|
||||||
"@angular-eslint/eslint-plugin-template": "19.8.0",
|
"@angular-eslint/eslint-plugin-template": "20.3.0",
|
||||||
"@angular-eslint/template-parser": "19.8.0",
|
"@angular-eslint/template-parser": "20.3.0",
|
||||||
"@angular/compiler-cli": "19.2.14",
|
"@angular/compiler-cli": "20.3.3",
|
||||||
"@electron/notarize": "2.5.0",
|
"@electron/notarize": "2.5.0",
|
||||||
"@electron/rebuild": "4.0.1",
|
"@electron/rebuild": "4.0.1",
|
||||||
"@fluffy-spoon/substitute": "1.208.0",
|
"@fluffy-spoon/substitute": "1.208.0",
|
||||||
"@microsoft/microsoft-graph-types": "2.40.0",
|
"@microsoft/microsoft-graph-types": "2.40.0",
|
||||||
"@ngtools/webpack": "19.2.14",
|
"@ngtools/webpack": "20.3.3",
|
||||||
"@types/inquirer": "8.2.10",
|
"@types/inquirer": "8.2.10",
|
||||||
"@types/jest": "29.5.14",
|
"@types/jest": "29.5.14",
|
||||||
"@types/lowdb": "1.0.15",
|
"@types/lowdb": "1.0.15",
|
||||||
@@ -90,16 +90,16 @@
|
|||||||
"@types/node-forge": "1.3.11",
|
"@types/node-forge": "1.3.11",
|
||||||
"@types/proper-lockfile": "4.1.4",
|
"@types/proper-lockfile": "4.1.4",
|
||||||
"@types/tldjs": "2.3.4",
|
"@types/tldjs": "2.3.4",
|
||||||
"@typescript-eslint/eslint-plugin": "8.43.0",
|
"@typescript-eslint/eslint-plugin": "8.46.0",
|
||||||
"@typescript-eslint/parser": "8.43.0",
|
"@typescript-eslint/parser": "8.46.0",
|
||||||
"@yao-pkg/pkg": "6.5.1",
|
"@yao-pkg/pkg": "5.16.1",
|
||||||
"clean-webpack-plugin": "4.0.0",
|
"clean-webpack-plugin": "4.0.0",
|
||||||
"concurrently": "9.2.0",
|
"concurrently": "9.2.0",
|
||||||
"copy-webpack-plugin": "13.0.0",
|
"copy-webpack-plugin": "13.0.0",
|
||||||
"cross-env": "7.0.3",
|
"cross-env": "7.0.3",
|
||||||
"css-loader": "7.1.2",
|
"css-loader": "7.1.2",
|
||||||
"dotenv": "17.2.0",
|
"dotenv": "17.2.0",
|
||||||
"electron": "37.4.0",
|
"electron": "38.1.0",
|
||||||
"electron-builder": "24.13.3",
|
"electron-builder": "24.13.3",
|
||||||
"electron-log": "5.4.1",
|
"electron-log": "5.4.1",
|
||||||
"electron-reload": "2.0.0-alpha.1",
|
"electron-reload": "2.0.0-alpha.1",
|
||||||
@@ -112,6 +112,7 @@
|
|||||||
"eslint-plugin-rxjs": "5.0.3",
|
"eslint-plugin-rxjs": "5.0.3",
|
||||||
"eslint-plugin-rxjs-angular": "2.0.1",
|
"eslint-plugin-rxjs-angular": "2.0.1",
|
||||||
"form-data": "4.0.4",
|
"form-data": "4.0.4",
|
||||||
|
"glob": "8.1.0",
|
||||||
"html-loader": "5.1.0",
|
"html-loader": "5.1.0",
|
||||||
"html-webpack-plugin": "5.6.3",
|
"html-webpack-plugin": "5.6.3",
|
||||||
"husky": "9.1.7",
|
"husky": "9.1.7",
|
||||||
@@ -121,18 +122,19 @@
|
|||||||
"jest-preset-angular": "14.6.0",
|
"jest-preset-angular": "14.6.0",
|
||||||
"lint-staged": "16.1.2",
|
"lint-staged": "16.1.2",
|
||||||
"mini-css-extract-plugin": "2.9.2",
|
"mini-css-extract-plugin": "2.9.2",
|
||||||
"node-abi": "3.75.0",
|
"minimatch": "5.1.2",
|
||||||
|
"node-abi": "3.77.0",
|
||||||
"node-forge": "1.3.1",
|
"node-forge": "1.3.1",
|
||||||
"node-loader": "2.1.0",
|
"node-loader": "2.1.0",
|
||||||
"prettier": "3.6.2",
|
"prettier": "3.6.2",
|
||||||
"rimraf": "6.0.1",
|
"rimraf": "6.0.1",
|
||||||
"rxjs": "7.8.2",
|
"rxjs": "7.8.2",
|
||||||
"sass": "1.92.1",
|
"sass": "1.93.2",
|
||||||
"sass-loader": "16.0.5",
|
"sass-loader": "16.0.5",
|
||||||
"ts-jest": "29.4.1",
|
"ts-jest": "29.4.1",
|
||||||
"ts-loader": "9.5.2",
|
"ts-loader": "9.5.2",
|
||||||
"tsconfig-paths-webpack-plugin": "4.2.0",
|
"tsconfig-paths-webpack-plugin": "4.2.0",
|
||||||
"type-fest": "4.41.0",
|
"type-fest": "5.0.1",
|
||||||
"typescript": "5.8.3",
|
"typescript": "5.8.3",
|
||||||
"webpack": "5.101.0",
|
"webpack": "5.101.0",
|
||||||
"webpack-cli": "6.0.1",
|
"webpack-cli": "6.0.1",
|
||||||
@@ -141,16 +143,16 @@
|
|||||||
"zone.js": "0.15.1"
|
"zone.js": "0.15.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "19.2.14",
|
"@angular/animations": "20.3.3",
|
||||||
"@angular/cdk": "19.2.14",
|
"@angular/cdk": "20.2.7",
|
||||||
"@angular/cli": "19.2.14",
|
"@angular/cli": "20.3.3",
|
||||||
"@angular/common": "19.2.14",
|
"@angular/common": "20.3.3",
|
||||||
"@angular/compiler": "19.2.14",
|
"@angular/compiler": "20.3.3",
|
||||||
"@angular/core": "19.2.14",
|
"@angular/core": "20.3.3",
|
||||||
"@angular/forms": "19.2.14",
|
"@angular/forms": "20.3.3",
|
||||||
"@angular/platform-browser": "19.2.14",
|
"@angular/platform-browser": "20.3.3",
|
||||||
"@angular/platform-browser-dynamic": "19.2.14",
|
"@angular/platform-browser-dynamic": "20.3.3",
|
||||||
"@angular/router": "19.2.14",
|
"@angular/router": "20.3.3",
|
||||||
"@microsoft/microsoft-graph-client": "3.0.7",
|
"@microsoft/microsoft-graph-client": "3.0.7",
|
||||||
"big-integer": "1.6.52",
|
"big-integer": "1.6.52",
|
||||||
"bootstrap": "5.3.7",
|
"bootstrap": "5.3.7",
|
||||||
@@ -158,15 +160,13 @@
|
|||||||
"chalk": "4.1.2",
|
"chalk": "4.1.2",
|
||||||
"commander": "14.0.0",
|
"commander": "14.0.0",
|
||||||
"form-data": "4.0.4",
|
"form-data": "4.0.4",
|
||||||
"google-auth-library": "10.3.0",
|
"googleapis": "149.0.0",
|
||||||
"googleapis": "153.0.0",
|
|
||||||
"googleapis-common": "8.0.0",
|
|
||||||
"https-proxy-agent": "7.0.6",
|
"https-proxy-agent": "7.0.6",
|
||||||
"inquirer": "8.2.6",
|
"inquirer": "8.2.6",
|
||||||
"keytar": "7.9.0",
|
"keytar": "7.9.0",
|
||||||
"ldapts": "8.0.1",
|
"ldapts": "8.0.1",
|
||||||
"lowdb": "1.0.0",
|
"lowdb": "1.0.0",
|
||||||
"ngx-toastr": "19.0.0",
|
"ngx-toastr": "19.1.0",
|
||||||
"node-fetch": "2.7.0",
|
"node-fetch": "2.7.0",
|
||||||
"parse5": "8.0.0",
|
"parse5": "8.0.0",
|
||||||
"proper-lockfile": "4.1.2",
|
"proper-lockfile": "4.1.2",
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ export class LdapDirectoryService implements IDirectoryService {
|
|||||||
[delControl],
|
[delControl],
|
||||||
);
|
);
|
||||||
return regularUsers.concat(deletedUsers);
|
return regularUsers.concat(deletedUsers);
|
||||||
} catch (e) {
|
} catch {
|
||||||
this.logService.warning("Cannot query deleted users.");
|
this.logService.warning("Cannot query deleted users.");
|
||||||
return regularUsers;
|
return regularUsers;
|
||||||
}
|
}
|
||||||
@@ -192,14 +192,21 @@ export class LdapDirectoryService implements IDirectoryService {
|
|||||||
this.syncConfig.userFilter,
|
this.syncConfig.userFilter,
|
||||||
);
|
);
|
||||||
const userPath = this.makeSearchPath(this.syncConfig.userPath);
|
const userPath = this.makeSearchPath(this.syncConfig.userPath);
|
||||||
const userIdMap = new Map<string, string>();
|
const userDnMap = new Map<string, string>();
|
||||||
|
const userUidMap = new Map<string, string>();
|
||||||
await this.search<string>(userPath, userFilter, (se: any) => {
|
await this.search<string>(userPath, userFilter, (se: any) => {
|
||||||
userIdMap.set(this.getReferenceId(se), this.getExternalId(se, this.getReferenceId(se)));
|
const dn = this.getReferenceId(se);
|
||||||
|
const uid = this.getAttr<string>(se, "uid");
|
||||||
|
const externalId = this.getExternalId(se, dn);
|
||||||
|
userDnMap.set(dn, externalId);
|
||||||
|
if (uid != null) {
|
||||||
|
userUidMap.set(uid.toLowerCase(), externalId);
|
||||||
|
}
|
||||||
return se;
|
return se;
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const se of groupSearchEntries) {
|
for (const se of groupSearchEntries) {
|
||||||
const group = this.buildGroup(se, userIdMap);
|
const group = this.buildGroup(se, userDnMap, userUidMap);
|
||||||
if (group != null) {
|
if (group != null) {
|
||||||
entries.push(group);
|
entries.push(group);
|
||||||
}
|
}
|
||||||
@@ -208,7 +215,20 @@ export class LdapDirectoryService implements IDirectoryService {
|
|||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildGroup(searchEntry: any, userMap: Map<string, string>) {
|
/**
|
||||||
|
* Builds a GroupEntry from LDAP search results, including membership.
|
||||||
|
* Supports user membership by DN or UID and nested group membership by DN.
|
||||||
|
*
|
||||||
|
* @param searchEntry - The LDAP search entry containing group data
|
||||||
|
* @param userDnMap - Map of user DNs to their external IDs
|
||||||
|
* @param userUidMap - Map of user UIDs to their external IDs
|
||||||
|
* @returns A populated GroupEntry object, or null if the group lacks required properties
|
||||||
|
*/
|
||||||
|
private buildGroup(
|
||||||
|
searchEntry: any,
|
||||||
|
userDnMap: Map<string, string>,
|
||||||
|
userUidMap: Map<string, string>,
|
||||||
|
) {
|
||||||
const group = new GroupEntry();
|
const group = new GroupEntry();
|
||||||
group.referenceId = this.getReferenceId(searchEntry);
|
group.referenceId = this.getReferenceId(searchEntry);
|
||||||
if (group.referenceId == null) {
|
if (group.referenceId == null) {
|
||||||
@@ -228,11 +248,34 @@ export class LdapDirectoryService implements IDirectoryService {
|
|||||||
|
|
||||||
const members = this.getAttrVals<string>(searchEntry, this.syncConfig.memberAttribute);
|
const members = this.getAttrVals<string>(searchEntry, this.syncConfig.memberAttribute);
|
||||||
if (members != null) {
|
if (members != null) {
|
||||||
for (const memDn of members) {
|
// Parses a group member attribute and identifies it as a member DN, member Uid, or a group Dn
|
||||||
if (userMap.has(memDn) && !group.userMemberExternalIds.has(userMap.get(memDn))) {
|
const getMemberAttributeType = (member: string): "memberDn" | "memberUid" | "groupDn" => {
|
||||||
group.userMemberExternalIds.add(userMap.get(memDn));
|
const isDnLike = member.includes("=") && member.includes(",");
|
||||||
} else if (!group.groupMemberReferenceIds.has(memDn)) {
|
if (isDnLike) {
|
||||||
group.groupMemberReferenceIds.add(memDn);
|
return userDnMap.has(member) ? "memberDn" : "groupDn";
|
||||||
|
}
|
||||||
|
return "memberUid";
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const member of members) {
|
||||||
|
switch (getMemberAttributeType(member)) {
|
||||||
|
case "memberDn": {
|
||||||
|
const externalId = userDnMap.get(member);
|
||||||
|
if (externalId != null) {
|
||||||
|
group.userMemberExternalIds.add(externalId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "memberUid": {
|
||||||
|
const externalId = userUidMap.get(member.toLowerCase());
|
||||||
|
if (externalId != null) {
|
||||||
|
group.userMemberExternalIds.add(externalId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "groupDn":
|
||||||
|
group.groupMemberReferenceIds.add(member);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,7 +123,10 @@ describe("SyncService", () => {
|
|||||||
expect(apiService.postPublicImportDirectory).toHaveBeenCalledWith(
|
expect(apiService.postPublicImportDirectory).toHaveBeenCalledWith(
|
||||||
expect.objectContaining({ overwriteExisting: false }),
|
expect.objectContaining({ overwriteExisting: false }),
|
||||||
);
|
);
|
||||||
expect(apiService.postPublicImportDirectory).toHaveBeenCalledTimes(6);
|
|
||||||
|
// The expected number of calls may change if more data is added to the ldif
|
||||||
|
// Make sure it equals (number of users / 4) + (number of groups / 4)
|
||||||
|
expect(apiService.postPublicImportDirectory).toHaveBeenCalledTimes(7);
|
||||||
|
|
||||||
// @ts-expect-error Reset batch size to original state.
|
// @ts-expect-error Reset batch size to original state.
|
||||||
constants.batchSize = originalBatchSize;
|
constants.batchSize = originalBatchSize;
|
||||||
|
|||||||
Reference in New Issue
Block a user