1
0
mirror of https://github.com/bitwarden/directory-connector synced 2025-12-20 02:03:21 +00:00

Compare commits

..

1 Commits

Author SHA1 Message Date
Thomas Rittson
b830c8be27 [PM-26454] Undo removal of core-js to fix dynamic import errors (#890)
* Undo removal of core-js to fix dynamic import errors

* chore: update package-lock with npm install

---------

Co-authored-by: Vincent Salucci <vincesalucci21@gmail.com>
2025-10-02 11:13:45 -05:00
16 changed files with 5776 additions and 4831 deletions

6
.github/CODEOWNERS vendored
View File

@@ -6,9 +6,3 @@
# 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

View File

@@ -8,6 +8,12 @@
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.
@@ -15,10 +21,5 @@
// 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",
], ],
} }

View File

@@ -23,22 +23,20 @@ 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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
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
@@ -51,9 +49,7 @@ jobs:
contents: read contents: read
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
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
@@ -65,7 +61,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: |
@@ -76,8 +72,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
@@ -86,19 +82,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)
@@ -129,9 +125,7 @@ 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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
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
@@ -143,7 +137,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: |
@@ -154,8 +148,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
@@ -164,12 +158,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)
@@ -200,9 +194,7 @@ 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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Setup Windows builder - name: Setup Windows builder
run: | run: |
@@ -249,7 +241,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"
@@ -279,9 +271,7 @@ jobs:
HUSKY: 0 HUSKY: 0
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
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
@@ -379,9 +369,7 @@ jobs:
HUSKY: 0 HUSKY: 0
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
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
@@ -393,7 +381,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: |
@@ -439,9 +427,7 @@ jobs:
HUSKY: 0 HUSKY: 0
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
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
@@ -453,7 +439,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: |
@@ -478,16 +464,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
@@ -496,9 +482,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 "" \
@@ -510,12 +496,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;
@@ -525,12 +511,10 @@ 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
${_APP_STORE_CONNECT_AUTH_KEY} ${{ steps.get-kv-secrets.outputs.APP-STORE-CONNECT-AUTH-KEY }}
EOF EOF
- name: Build application - name: Build application

View File

@@ -29,16 +29,14 @@ jobs:
steps: steps:
- name: Check out repo - name: Check out repo
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
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

View File

@@ -26,9 +26,7 @@ jobs:
release_version: ${{ steps.version.outputs.version }} release_version: ${{ steps.version.outputs.version }}
steps: steps:
- name: Checkout repo - name: Checkout repo
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Branch check - name: Branch check
if: ${{ inputs.release_type != 'Dry Run' }} if: ${{ inputs.release_type != 'Dry Run' }}

View File

@@ -22,16 +22,14 @@ jobs:
steps: steps:
- name: Check out repo - name: Check out repo
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
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

View File

@@ -49,10 +49,9 @@ 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@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
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: |
@@ -63,7 +62,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 != '' }}
@@ -78,7 +77,8 @@ jobs:
fi fi
# Check if version is newer. # Check if version is newer.
if printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V; then printf '%s\n' "${CURRENT_VERSION}" "${NEW_VERSION}" | sort -C -V
if [ $? -eq 0 ]; then
echo "Version check successful." echo "Version check successful."
else else
echo "Version check failed." echo "Version check failed."
@@ -110,34 +110,26 @@ 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 [[ "$_BUMP_VERSION_OVERRIDE_OUTCOME" == "success" ]]; then if [[ "${{ steps.bump-version-override.outcome }}" == "success" ]]; then
echo "version=$_INPUT_VERSION_NUMBER_OVERRIDE" >> "$GITHUB_OUTPUT" echo "version=${{ inputs.version_number_override }}" >> $GITHUB_OUTPUT
elif [[ "$_BUMP_VERSION_AUTOMATIC_OUTCOME" == "success" ]]; then elif [[ "${{ steps.bump-version-automatic.outcome }}" == "success" ]]; then
echo "version=$_CALCULATE_NEXT_VERSION" >> "$GITHUB_OUTPUT" echo "version=${{ steps.calculate-next-version.outputs.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' }}
env: run: git commit -m "Bumped version to ${{ steps.set-final-version-output.outputs.version }}" -a
_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' }}

View File

@@ -1,6 +1,6 @@
services: services:
open-ldap: open-ldap:
image: bitnamilegacy/openldap:latest image: bitnami/openldap:latest
hostname: openldap hostname: openldap
environment: environment:
- LDAP_ADMIN_USERNAME=admin - LDAP_ADMIN_USERNAME=admin

View File

@@ -1,4 +1,4 @@
import { InjectOptions, Injector, ProviderToken } from "@angular/core"; import { InjectFlags, InjectOptions, Injector, ProviderToken } from "@angular/core";
export class ModalInjector implements Injector { export class ModalInjector implements Injector {
constructor( constructor(
@@ -12,7 +12,8 @@ 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): T; get<T>(token: ProviderToken<T>, notFoundValue?: T, options?: InjectOptions | InjectFlags): 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);

View File

@@ -35,29 +35,6 @@ 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));

View File

@@ -689,26 +689,3 @@ 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

10285
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -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.10.0", "version": "2025.9.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": "20.3.3", "@angular-devkit/build-angular": "19.2.15",
"@angular-eslint/eslint-plugin-template": "20.3.0", "@angular-eslint/eslint-plugin-template": "19.8.0",
"@angular-eslint/template-parser": "20.3.0", "@angular-eslint/template-parser": "19.8.0",
"@angular/compiler-cli": "20.3.3", "@angular/compiler-cli": "19.2.14",
"@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": "20.3.3", "@ngtools/webpack": "19.2.14",
"@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,8 +90,8 @@
"@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.46.0", "@typescript-eslint/eslint-plugin": "8.43.0",
"@typescript-eslint/parser": "8.46.0", "@typescript-eslint/parser": "8.43.0",
"@yao-pkg/pkg": "5.16.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",
@@ -112,7 +112,6 @@
"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",
@@ -122,19 +121,18 @@
"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",
"minimatch": "5.1.2",
"node-abi": "3.77.0", "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.93.2", "sass": "1.92.1",
"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": "5.0.1", "type-fest": "4.41.0",
"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",
@@ -143,30 +141,33 @@
"zone.js": "0.15.1" "zone.js": "0.15.1"
}, },
"dependencies": { "dependencies": {
"@angular/animations": "20.3.3", "@angular/animations": "19.2.14",
"@angular/cdk": "20.2.7", "@angular/cdk": "19.2.14",
"@angular/cli": "20.3.3", "@angular/cli": "19.2.14",
"@angular/common": "20.3.3", "@angular/common": "19.2.14",
"@angular/compiler": "20.3.3", "@angular/compiler": "19.2.14",
"@angular/core": "20.3.3", "@angular/core": "19.2.14",
"@angular/forms": "20.3.3", "@angular/forms": "19.2.14",
"@angular/platform-browser": "20.3.3", "@angular/platform-browser": "19.2.14",
"@angular/platform-browser-dynamic": "20.3.3", "@angular/platform-browser-dynamic": "19.2.14",
"@angular/router": "20.3.3", "@angular/router": "19.2.14",
"@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",
"browser-hrtime": "1.1.8", "browser-hrtime": "1.1.8",
"chalk": "4.1.2", "chalk": "4.1.2",
"commander": "14.0.0", "commander": "14.0.0",
"core-js": "3.44.0",
"form-data": "4.0.4", "form-data": "4.0.4",
"googleapis": "149.0.0", "google-auth-library": "10.3.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.1.0", "ngx-toastr": "19.0.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",

View File

@@ -1,3 +1,6 @@
// core-js is required for bwdc cli which appears to require these pollyfills for dynamic imports
// see https://github.com/bitwarden/directory-connector/issues/878
import "core-js/stable";
import "zone.js"; import "zone.js";
import { NgModule } from "@angular/core"; import { NgModule } from "@angular/core";

View File

@@ -118,7 +118,7 @@ export class LdapDirectoryService implements IDirectoryService {
[delControl], [delControl],
); );
return regularUsers.concat(deletedUsers); return regularUsers.concat(deletedUsers);
} catch { } catch (e) {
this.logService.warning("Cannot query deleted users."); this.logService.warning("Cannot query deleted users.");
return regularUsers; return regularUsers;
} }
@@ -192,21 +192,14 @@ 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 userDnMap = new Map<string, string>(); const userIdMap = 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) => {
const dn = this.getReferenceId(se); userIdMap.set(this.getReferenceId(se), this.getExternalId(se, 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, userDnMap, userUidMap); const group = this.buildGroup(se, userIdMap);
if (group != null) { if (group != null) {
entries.push(group); entries.push(group);
} }
@@ -215,20 +208,7 @@ 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) {
@@ -248,34 +228,11 @@ 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) {
// Parses a group member attribute and identifies it as a member DN, member Uid, or a group Dn for (const memDn of members) {
const getMemberAttributeType = (member: string): "memberDn" | "memberUid" | "groupDn" => { if (userMap.has(memDn) && !group.userMemberExternalIds.has(userMap.get(memDn))) {
const isDnLike = member.includes("=") && member.includes(","); group.userMemberExternalIds.add(userMap.get(memDn));
if (isDnLike) { } else if (!group.groupMemberReferenceIds.has(memDn)) {
return userDnMap.has(member) ? "memberDn" : "groupDn"; group.groupMemberReferenceIds.add(memDn);
}
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;
} }
} }
} }

View File

@@ -123,10 +123,7 @@ 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;