1
0
mirror of https://github.com/bitwarden/directory-connector synced 2025-12-05 23:53:21 +00:00

Compare commits

...

49 Commits

Author SHA1 Message Date
Thomas Rittson
d35783fad3 trigger CI 2025-01-27 13:16:47 +10:00
Thomas Rittson
cb099f902b Merge branch 'main' into feat/disable-suspended-google-accounts 2025-01-24 10:25:54 +10:00
renovate[bot]
cf54858cc5 [deps]: Update ngx-toastr to v19 (#689)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-23 10:16:54 -06:00
renovate[bot]
6cc022b135 [deps]: Update jest-preset-angular to v14.5.0 (#711)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-23 09:53:02 -06:00
renovate[bot]
a8a4390624 [deps]: Update eslint-import-resolver-typescript to v3.7.0 (#686)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-23 09:52:01 -06:00
renovate[bot]
f9d817f0b1 [deps]: Update gh minor (#645)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-23 15:38:39 +00:00
github-actions
112bda1137 Bumped version to 2025.1.1 2025-01-23 13:42:01 +00:00
Hendrik Heil
e92cb355bd feat: disable archived google users 2025-01-22 19:19:28 +01:00
renovate[bot]
23713d92fa [deps]: Update type-fest to v4.32.0 (#696)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-17 10:57:42 +10:00
renovate[bot]
6ebc9631aa [deps]: Update lint-staged to v15.4.1 (#695)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-17 10:44:56 +10:00
Matt Andreko
e8579f11d3 Removed unnecessary CODECOV_TOKEN with updated codecov-action (#709) 2025-01-16 08:53:26 -05:00
renovate[bot]
6b2c7a5f00 [deps]: Update ldapts to v7.3.1 (#699)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-16 17:19:22 +10:00
renovate[bot]
2a1a5bf064 [deps]: Update @types/node to v20.17.14 (#694)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-16 17:15:42 +10:00
Vince Grassia
1464d72b27 BRE-549 - Add rc branch logic (#708) 2025-01-14 22:24:48 -06:00
Vincent Salucci
f5cbd8f03d chore: version bump to 2025.1.0 (#707) 2025-01-14 13:16:09 -06:00
Matt Andreko
fdbbef68c1 Update SonarQube GitHub Action (#706)
* Updated SonarQube GitHub action to v4.2.1

* Removed unnecessary github token
2025-01-14 09:28:46 -05:00
renovate[bot]
efb412684d [deps]: Update rimraf to v6 (#690)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-10 12:20:13 -05:00
renovate[bot]
79f7a2b495 [deps]: Update typescript-eslint monorepo to v8 (#563)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-03 11:57:59 -06:00
renovate[bot]
4342734412 [deps]: Update https-proxy-agent to v7.0.6 (#684)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-27 15:44:26 -05:00
renovate[bot]
62f14e5043 [deps]: Update prettier to v3.4.2 (#687)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-27 13:47:47 -05:00
renovate[bot]
c2b22518fe [deps]: Update codecov/codecov-action action to v5 (#681)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-20 16:38:11 -05:00
Thomas Rittson
37c992f16b [PM-13007] Fix Active Directory externalId parsing (#693)
Return AD ObjectGuid attribute as buffer so it can be parsed properly
2024-12-19 07:43:47 +10:00
renovate[bot]
69156677ac [deps]: Update electron to v33 - abandoned (#658)
* [deps]: Update electron to v33

* remove event parameter from handler function params

* change to v.32.1.1

* clean up

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Brandon <btreston@bitwarden.com>
2024-12-17 12:40:34 -05:00
renovate[bot]
aaed7b13ea [deps]: Update ldapts to v7.2.2 (#685)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Brandon Treston <btreston@bitwarden.com>
2024-12-17 11:46:10 -05:00
renovate[bot]
096d2a03ab [deps]: Update dotenv to v16.4.7 (#683)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-10 14:25:09 -05:00
renovate[bot]
bd5bcbebd9 [deps]: Update type-fest to v4.30.0 (#677)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 15:13:26 -06:00
renovate[bot]
bb9ece6078 [deps]: Update tsconfig-paths-webpack-plugin to v4.2.0 (#676)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 14:59:35 -06:00
renovate[bot]
40de47e6e3 [deps]: Update node-loader to v2.1.0 (#675)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 14:56:39 -06:00
renovate[bot]
094ed57e03 [deps]: Update jest-preset-angular to v14.4.2 (#674)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 14:54:14 -06:00
renovate[bot]
96a38e2d76 [deps]: Update concurrently to v9.1.0 (#668)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 14:48:52 -06:00
renovate[bot]
9e200c8705 [deps]: Update @electron/rebuild to v3.7.1 (#647)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 14:44:30 -06:00
renovate[bot]
ca945318ed [deps]: Update sass-loader to v16.0.4 (#666)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 14:41:30 -06:00
renovate[bot]
04abed9251 [deps]: Update typescript-transform-paths to v3.5.2 (#667)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 14:33:00 -06:00
renovate[bot]
9b08ca6db8 [deps]: Update mini-css-extract-plugin to v2.9.2 (#665)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 14:29:11 -06:00
renovate[bot]
0cbe6e9d33 [deps]: Update husky to v9.1.7 (#673)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 13:31:28 -06:00
renovate[bot]
dda6dd99ed [deps]: Update electron-updater to v6.3.9 (#643)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 13:26:56 -06:00
renovate[bot]
5492466276 [deps]: Update electron-log to v5.2.4 (#664)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 13:20:52 -06:00
renovate[bot]
ef571ec0c3 [deps]: Update @types/node-fetch to v2.6.12 (#672)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 13:16:08 -06:00
renovate[bot]
f2bea1b6d7 [deps]: Update @types/node to v20.17.9 (#663)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-06 12:25:23 -06:00
renovate[bot]
07a1ae6dea [deps]: Update @types/jest to v29.5.14 (#655)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Brandon Treston <btreston@bitwarden.com>
2024-12-02 12:41:51 -05:00
renovate[bot]
f23997dd72 [deps]: Update @electron/notarize to v2.5.0 (#598)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-29 14:28:40 +00:00
renovate[bot]
18547d6eaa [deps]: Update html-webpack-plugin to v5.6.3 (#657)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-22 14:46:40 -05:00
moewill
c3a4f25160 fix: remove duplicate word in README.md (#662) 2024-11-19 13:04:02 -05:00
renovate[bot]
e57a52e483 [deps]: Update eslint-plugin-import to v2.31.0 (#648)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-13 11:50:04 +10:00
renovate[bot]
ff1380ee67 [deps]: Update form-data to v4.0.1 (#644)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-13 11:39:13 +10:00
renovate[bot]
2269b82e7e [deps]: Update angular-cli monorepo to v17.3.11 (#656)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-12 16:22:32 +10:00
renovate[bot]
8ab3516377 [deps]: Update @types/node to v20.17.5 (#642)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-01 13:44:58 +10:00
Thomas Rittson
91dfd7e0b7 [PM-13007] Replace ldapjs with ldapts (#641) 2024-11-01 12:58:52 +10:00
Vince Grassia
6db28408e6 Update Version Bump workflow to push directly to main (#661) 2024-10-31 15:04:12 -04:00
11 changed files with 932 additions and 904 deletions

View File

@@ -5,6 +5,8 @@ on:
push:
branches:
- "main"
- "rc"
- "hotfix-rc"
workflow_dispatch: {}
jobs:
@@ -13,7 +15,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout repo
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up CLOC
run: |
@@ -31,7 +33,7 @@ jobs:
package_version: ${{ steps.retrieve-version.outputs.package_version }}
steps:
- name: Checkout repo
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get Package Version
id: retrieve-version
@@ -50,10 +52,10 @@ jobs:
_PKG_FETCH_VERSION: 3.4
steps:
- name: Checkout repo
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Node
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
@@ -121,14 +123,14 @@ jobs:
fi
- name: Upload Linux Zip to GitHub
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: bwdc-linux-${{ env._PACKAGE_VERSION }}.zip
path: ./dist-cli/bwdc-linux-${{ env._PACKAGE_VERSION }}.zip
if-no-files-found: error
- name: Upload Linux checksum to GitHub
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: bwdc-linux-sha256-${{ env._PACKAGE_VERSION }}.txt
path: ./dist-cli/bwdc-linux-sha256-${{ env._PACKAGE_VERSION }}.txt
@@ -145,10 +147,10 @@ jobs:
_PKG_FETCH_VERSION: 3.4
steps:
- name: Checkout repo
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Node
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
@@ -209,14 +211,14 @@ jobs:
fi
- name: Upload Mac Zip to GitHub
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: bwdc-macos-${{ env._PACKAGE_VERSION }}.zip
path: ./dist-cli/bwdc-macos-${{ env._PACKAGE_VERSION }}.zip
if-no-files-found: error
- name: Upload Mac checksum to GitHub
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: bwdc-macos-sha256-${{ env._PACKAGE_VERSION }}.txt
path: ./dist-cli/bwdc-macos-sha256-${{ env._PACKAGE_VERSION }}.txt
@@ -232,7 +234,7 @@ jobs:
_WIN_PKG_VERSION: 3.4
steps:
- name: Checkout repo
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup Windows builder
run: |
@@ -240,7 +242,7 @@ jobs:
choco install reshack --no-progress
- name: Set up Node
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
@@ -353,14 +355,14 @@ jobs:
-t sha256 | Out-File ./dist-cli/bwdc-windows-sha256-${env:_PACKAGE_VERSION}.txt
- name: Upload Windows Zip to GitHub
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: bwdc-windows-${{ env._PACKAGE_VERSION }}.zip
path: ./dist-cli/bwdc-windows-${{ env._PACKAGE_VERSION }}.zip
if-no-files-found: error
- name: Upload Windows checksum to GitHub
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: bwdc-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
path: ./dist-cli/bwdc-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
@@ -377,10 +379,10 @@ jobs:
HUSKY: 0
steps:
- name: Checkout repo
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Node
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
@@ -413,28 +415,28 @@ jobs:
SIGNING_CERT_NAME: ${{ secrets.SIGNING_CERT_NAME }}
- name: Upload Portable Executable to GitHub
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: Bitwarden-Connector-Portable-${{ env._PACKAGE_VERSION }}.exe
path: ./dist/Bitwarden-Connector-Portable-${{ env._PACKAGE_VERSION }}.exe
if-no-files-found: error
- name: Upload Installer Executable to GitHub
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe
path: ./dist/Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe
if-no-files-found: error
- name: Upload Installer Executable Blockmap to GitHub
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe.blockmap
path: ./dist/Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe.blockmap
if-no-files-found: error
- name: Upload latest auto-update artifact
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: latest.yml
path: ./dist/latest.yml
@@ -451,10 +453,10 @@ jobs:
HUSKY: 0
steps:
- name: Checkout repo
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Node
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
@@ -481,14 +483,14 @@ jobs:
run: npm run dist:lin
- name: Upload AppImage
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
if-no-files-found: error
- name: Upload latest auto-update artifact
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: latest-linux.yml
path: ./dist/latest-linux.yml
@@ -505,10 +507,10 @@ jobs:
HUSKY: 0
steps:
- name: Checkout repo
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Set up Node
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
@@ -575,7 +577,7 @@ jobs:
- name: Install Node dependencies
run: npm install
- name: Set up private auth key
run: |
mkdir ~/private_keys
@@ -592,28 +594,28 @@ jobs:
CSC_FOR_PULL_REQUEST: true
- name: Upload .zip artifact
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-mac.zip
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-mac.zip
if-no-files-found: error
- name: Upload .dmg artifact
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg
if-no-files-found: error
- name: Upload .dmg Blockmap artifact
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg.blockmap
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg.blockmap
if-no-files-found: error
- name: Upload latest auto-update artifact
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: latest-mac.yml
path: ./dist/latest-mac.yml
@@ -634,7 +636,11 @@ jobs:
- macos-gui
steps:
- name: Check if any job failed
if: github.ref == 'refs/heads/main' && contains(needs.*.result, 'failure')
if: |
(github.ref == 'refs/heads/main'
|| github.ref == 'refs/heads/rc'
|| github.ref == 'refs/heads/hotfix-rc')
&& contains(needs.*.result, 'failure')
run: exit 1
- name: Login to Azure - CI subscription

View File

@@ -48,7 +48,7 @@ jobs:
steps:
- name: Check out repo
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get Node version
id: retrieve-node-version
@@ -58,7 +58,7 @@ jobs:
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
- name: Set up Node
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
@@ -88,13 +88,10 @@ jobs:
fail-on-error: true
- name: Upload coverage to codecov.io
uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
if: ${{ needs.check-test-secrets.outputs.available == 'true' }}
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
uses: codecov/codecov-action@5a605bd92782ce0810fa3b8acc235c921b497052 # v5.2.0
- name: Upload results to codecov.io
uses: codecov/test-results-action@1b5b448b98e58ba90d1a1a1d9fcb72ca2263be46 # v1.0.0
uses: codecov/test-results-action@4e79e65778be1cecd5df25e14af1eafb6df80ea9 # v1.0.2
if: ${{ needs.check-test-secrets.outputs.available == 'true' }}
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -18,17 +18,17 @@ jobs:
name: Setup
runs-on: ubuntu-24.04
outputs:
release-version: ${{ steps.version.outputs.version }}
release_version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout repo
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Branch check
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
if: ${{ inputs.release_type != 'Dry Run' }}
run: |
if [[ "$GITHUB_REF" != "refs/heads/main" ]]; then
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc" ]]; then
echo "==================================="
echo "[!] Can only release from the 'main' branch"
echo "[!] Can only release from the 'rc' or 'hotfix-rc' branches"
echo "==================================="
exit 1
fi
@@ -37,7 +37,7 @@ jobs:
id: version
uses: bitwarden/gh-actions/release-version-check@main
with:
release-type: ${{ github.event.inputs.release_type }}
release-type: ${{ inputs.release_type }}
project-type: ts
file: package.json
@@ -47,7 +47,7 @@ jobs:
needs: setup
steps:
- name: Download all artifacts
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
if: ${{ inputs.release_type != 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build.yml
@@ -55,7 +55,7 @@ jobs:
branch: ${{ github.ref_name }}
- name: Dry Run - Download all artifacts
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
if: ${{ inputs.release_type == 'Dry Run' }}
uses: bitwarden/gh-actions/download-artifacts@main
with:
workflow: build.yml
@@ -63,10 +63,10 @@ jobs:
branch: main
- name: Create release
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
uses: ncipollo/release-action@2c591bcc8ecdcd2db72b97d6147f871fcd833ba5 # v1.14.0
if: ${{ inputs.release_type != 'Dry Run' }}
uses: ncipollo/release-action@cdcc88a9acf3ca41c16c37bb7d21b9ad48560d87 # v1.15.0
env:
PKG_VERSION: ${{ needs.setup.outputs.release-version }}
PKG_VERSION: ${{ needs.setup.outputs.release_version }}
with:
artifacts: "./bwdc-windows-${{ env.PKG_VERSION }}.zip,
./bwdc-macos-${{ env.PKG_VERSION }}.zip,

View File

@@ -24,12 +24,12 @@ jobs:
steps:
- name: Check out repo
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Scan with Checkmarx
uses: checkmarx/ast-github-action@ed196cdaec9cd1bc5aacac4ca2010dd773b20893 # 2.0.35
uses: checkmarx/ast-github-action@184bf2f64f55d1c93fd6636d539edf274703e434 # 2.0.41
env:
INCREMENTAL: "${{ contains(github.event_name, 'pull_request') && '--sast-incremental' || '' }}"
with:
@@ -44,7 +44,7 @@ jobs:
--output-path . ${{ env.INCREMENTAL }}
- name: Upload Checkmarx results to GitHub
uses: github/codeql-action/upload-sarif@e2b3eafc8d227b0241d48be5f425d47c2d750a13 # v3.26.10
uses: github/codeql-action/upload-sarif@dd196fa9ce80b6bacc74ca1c32bd5b0ba22efca7 # v3.28.3
with:
sarif_file: cx_result.sarif
@@ -58,16 +58,15 @@ jobs:
steps:
- name: Check out repo
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
- name: Scan with SonarCloud
uses: sonarsource/sonarcloud-github-action@eb211723266fe8e83102bac7361f0a05c3ac1d1b # v3.0.0
uses: sonarsource/sonarqube-scan-action@bfd4e558cda28cda6b5defafb9232d191be8c203 # v4.2.1
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
args: >
-Dsonar.organization=${{ github.repository_owner }}

View File

@@ -5,6 +5,8 @@ on:
push:
branches:
- "main"
- "rc"
- "hotfix-rc"
pull_request:
jobs:
@@ -38,7 +40,7 @@ jobs:
steps:
- name: Check out repo
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Get Node version
id: retrieve-node-version
@@ -48,7 +50,7 @@ jobs:
echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT
- name: Set up Node
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
with:
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
@@ -76,13 +78,10 @@ jobs:
fail-on-error: true
- name: Upload coverage to codecov.io
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
if: ${{ needs.check-test-secrets.outputs.available == 'true' }}
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
uses: codecov/codecov-action@5a605bd92782ce0810fa3b8acc235c921b497052 # v5.2.0
- name: Upload results to codecov.io
uses: codecov/test-results-action@1b5b448b98e58ba90d1a1a1d9fcb72ca2263be46 # v1.0.0
uses: codecov/test-results-action@4e79e65778be1cecd5df25e14af1eafb6df80ea9 # v1.0.2
if: ${{ needs.check-test-secrets.outputs.available == 'true' }}
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -7,17 +7,11 @@ on:
description: "New version override (leave blank for automatic calculation, example: '2024.1.0')"
required: false
type: string
enable_slack_notification:
description: "Enable Slack notifications for upcoming release?"
default: false
type: boolean
jobs:
bump_version:
name: Bump Version
runs-on: ubuntu-24.04
outputs:
version: ${{ steps.set-final-version-output.outputs.version }}
steps:
- name: Validate version input
if: ${{ inputs.version_number_override != '' }}
@@ -25,49 +19,22 @@ jobs:
with:
version: ${{ inputs.version_number_override }}
- name: Slack Notification Check
run: |
if [[ "${{ inputs.enable_slack_notification }}" == true ]]; then
echo "Slack notifications enabled."
else
echo "Slack notifications disabled."
fi
- name: Generate GH App token
uses: actions/create-github-app-token@c1a285145b9d317df6ced56c09f525b5c2b6f755 # v1.11.1
id: app-token
with:
app-id: ${{ secrets.BW_GHAPP_ID }}
private-key: ${{ secrets.BW_GHAPP_KEY }}
- name: Checkout Branch
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
- name: Login to Azure - CI Subscription
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
- name: Retrieve secrets
id: retrieve-secrets
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "github-gpg-private-key,
github-gpg-private-key-passphrase"
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@01dd5d3ca463c7f10f7f4f7b4f177225ac661ee4 # v6.1.0
with:
gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}
git_user_signingkey: true
git_commit_gpgsign: true
token: ${{ steps.app-token.outputs.token }}
- name: Setup git
run: |
git config --local user.email "106330231+bitwarden-devops-bot@users.noreply.github.com"
git config --local user.name "bitwarden-devops-bot"
- name: Create Version Branch
id: create-branch
run: |
NAME=version_bump_${{ github.ref_name }}_$(date +"%Y-%m-%d")
git switch -c $NAME
echo "name=$NAME" >> $GITHUB_OUTPUT
git config user.name github-actions
git config user.email github-actions@github.com
- name: Get current version
id: current-version
@@ -144,61 +111,4 @@ jobs:
- name: Push changes
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
env:
PR_BRANCH: ${{ steps.create-branch.outputs.name }}
run: git push -u origin $PR_BRANCH
- name: Generate GH App token
uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
id: app-token
with:
app-id: ${{ secrets.BW_GHAPP_ID }}
private-key: ${{ secrets.BW_GHAPP_KEY }}
owner: ${{ github.repository_owner }}
- name: Create Version PR
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
id: create-pr
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
PR_BRANCH: ${{ steps.create-branch.outputs.name }}
TITLE: "Bump version to ${{ steps.set-final-version-output.outputs.version }}"
run: |
PR_URL=$(gh pr create --title "$TITLE" \
--base "main" \
--head "$PR_BRANCH" \
--label "version update" \
--label "automated pr" \
--body "
## Type of change
- [ ] Bug fix
- [ ] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [X] Other
## Objective
Automated version bump to ${{ steps.set-final-version-output.outputs.version }}")
echo "pr_number=${PR_URL##*/}" >> $GITHUB_OUTPUT
- name: Approve PR
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ steps.create-pr.outputs.pr_number }}
run: gh pr review $PR_NUMBER --approve
- name: Merge PR
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' }}
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
PR_NUMBER: ${{ steps.create-pr.outputs.pr_number }}
run: gh pr merge $PR_NUMBER --squash --auto --delete-branch
- name: Report upcoming release version to Slack
if: ${{ steps.version-changed.outputs.changes_to_commit == 'TRUE' && inputs.enable_slack_notification == true }}
uses: bitwarden/gh-actions/report-upcoming-release-version@main
with:
version: ${{ steps.set-final-version-output.outputs.version }}
project: ${{ github.repository }}
AZURE_KV_CI_SERVICE_PRINCIPAL: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
run: git push

View File

@@ -3,7 +3,7 @@
# Bitwarden Directory Connector
The Bitwarden Directory Connector is a a desktop application used to sync your Bitwarden enterprise organization to an existing directory of users and groups.
The Bitwarden Directory Connector is a desktop application used to sync your Bitwarden enterprise organization to an existing directory of users and groups.
Supported directories:

1190
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
"name": "@bitwarden/directory-connector",
"productName": "Bitwarden Directory Connector",
"description": "Sync your user directory to your Bitwarden organization.",
"version": "2024.10.0",
"version": "2025.1.1",
"keywords": [
"bitwarden",
"password",
@@ -73,68 +73,67 @@
"test:types": "npx tsc --noEmit"
},
"devDependencies": {
"@angular-devkit/build-angular": "17.3.10",
"@angular-devkit/build-angular": "17.3.11",
"@angular-eslint/eslint-plugin-template": "17.5.3",
"@angular-eslint/template-parser": "17.5.3",
"@angular/compiler-cli": "17.3.12",
"@electron/notarize": "2.2.1",
"@electron/rebuild": "3.6.0",
"@electron/notarize": "2.5.0",
"@electron/rebuild": "3.7.1",
"@fluffy-spoon/substitute": "1.208.0",
"@microsoft/microsoft-graph-types": "2.40.0",
"@ngtools/webpack": "17.3.10",
"@ngtools/webpack": "17.3.11",
"@types/inquirer": "8.2.10",
"@types/jest": "29.5.13",
"@types/ldapjs": "2.2.5",
"@types/jest": "29.5.14",
"@types/lowdb": "1.0.15",
"@types/node": "20.16.10",
"@types/node-fetch": "2.6.11",
"@types/node": "20.17.14",
"@types/node-fetch": "2.6.12",
"@types/node-forge": "1.3.11",
"@types/proper-lockfile": "4.1.4",
"@types/tldjs": "2.3.4",
"@typescript-eslint/eslint-plugin": "5.62.0",
"@typescript-eslint/parser": "5.62.0",
"@typescript-eslint/eslint-plugin": "8.19.0",
"@typescript-eslint/parser": "8.19.0",
"clean-webpack-plugin": "4.0.0",
"concurrently": "9.0.1",
"concurrently": "9.1.0",
"copy-webpack-plugin": "12.0.2",
"cross-env": "7.0.3",
"css-loader": "7.1.2",
"dotenv": "16.4.5",
"electron": "28.3.3",
"dotenv": "16.4.7",
"electron": "32.1.1",
"electron-builder": "24.13.3",
"electron-log": "5.2.0",
"electron-log": "5.2.4",
"electron-reload": "2.0.0-alpha.1",
"electron-store": "8.2.0",
"electron-updater": "6.3.4",
"electron-updater": "6.3.9",
"eslint": "8.57.1",
"eslint-config-prettier": "9.1.0",
"eslint-import-resolver-typescript": "3.6.3",
"eslint-plugin-import": "2.30.0",
"eslint-import-resolver-typescript": "3.7.0",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-rxjs": "5.0.3",
"eslint-plugin-rxjs-angular": "2.0.1",
"form-data": "4.0.0",
"form-data": "4.0.1",
"html-loader": "5.1.0",
"html-webpack-plugin": "5.6.0",
"husky": "9.1.6",
"html-webpack-plugin": "5.6.3",
"husky": "9.1.7",
"jest": "29.7.0",
"jest-junit": "16.0.0",
"jest-mock-extended": "3.0.7",
"jest-preset-angular": "14.2.4",
"lint-staged": "15.2.10",
"mini-css-extract-plugin": "2.9.1",
"jest-preset-angular": "14.5.0",
"lint-staged": "15.4.1",
"mini-css-extract-plugin": "2.9.2",
"node-forge": "1.3.1",
"node-loader": "2.0.0",
"node-loader": "2.1.0",
"pkg": "5.8.1",
"prettier": "3.3.3",
"rimraf": "5.0.10",
"prettier": "3.4.2",
"rimraf": "6.0.1",
"rxjs": "7.8.1",
"sass": "1.79.4",
"sass-loader": "16.0.2",
"sass-loader": "16.0.4",
"ts-jest": "29.2.5",
"ts-loader": "9.5.1",
"tsconfig-paths-webpack-plugin": "4.1.0",
"type-fest": "4.26.1",
"tsconfig-paths-webpack-plugin": "4.2.0",
"type-fest": "4.32.0",
"typescript": "5.4.5",
"typescript-transform-paths": "3.5.1",
"typescript-transform-paths": "3.5.2",
"webpack": "5.95.0",
"webpack-cli": "5.1.4",
"webpack-merge": "6.0.1",
@@ -158,15 +157,15 @@
"chalk": "4.1.2",
"commander": "12.1.0",
"core-js": "3.38.1",
"form-data": "4.0.0",
"form-data": "4.0.1",
"google-auth-library": "7.14.1",
"googleapis": "73.0.0",
"https-proxy-agent": "7.0.5",
"https-proxy-agent": "7.0.6",
"inquirer": "8.2.6",
"keytar": "7.9.0",
"ldapjs": "2.3.3",
"ldapts": "7.3.1",
"lowdb": "1.0.0",
"ngx-toastr": "17.0.2",
"ngx-toastr": "19.0.0",
"node-fetch": "2.7.0",
"proper-lockfile": "4.1.2",
"rxjs": "7.8.1",

View File

@@ -141,7 +141,7 @@ export class GSuiteDirectoryService extends BaseDirectoryService implements IDir
entry.referenceId = user.id;
entry.externalId = user.id;
entry.email = user.primaryEmail != null ? user.primaryEmail.trim().toLowerCase() : null;
entry.disabled = user.suspended || false;
entry.disabled = user.suspended || user.archived || false;
entry.deleted = deleted;
return entry;
}

View File

@@ -1,7 +1,7 @@
import * as fs from "fs";
import { checkServerIdentity, PeerCertificate } from "tls";
import * as tls from "tls";
import * as ldap from "ldapjs";
import * as ldapts from "ldapts";
import { I18nService } from "@/jslib/common/src/abstractions/i18n.service";
import { LogService } from "@/jslib/common/src/abstractions/log.service";
@@ -18,8 +18,13 @@ import { IDirectoryService } from "./directory.service";
const UserControlAccountDisabled = 2;
/**
* The attribute name for the unique identifier used by Active Directory.
*/
const ActiveDirectoryExternalId = "objectGUID";
export class LdapDirectoryService implements IDirectoryService {
private client: ldap.Client;
private client: ldapts.Client;
private dirConfig: LdapConfiguration;
private syncConfig: SyncConfiguration;
@@ -48,21 +53,25 @@ export class LdapDirectoryService implements IDirectoryService {
await this.bind();
let users: UserEntry[];
if (this.syncConfig.users) {
users = await this.getUsers(force, test);
}
let groups: GroupEntry[];
if (this.syncConfig.groups) {
let groupForce = force;
if (!groupForce && users != null) {
const activeUsers = users.filter((u) => !u.deleted && !u.disabled);
groupForce = activeUsers.length > 0;
try {
if (this.syncConfig.users) {
users = await this.getUsers(force, test);
}
groups = await this.getGroups(groupForce);
if (this.syncConfig.groups) {
let groupForce = force;
if (!groupForce && users != null) {
const activeUsers = users.filter((u) => !u.deleted && !u.disabled);
groupForce = activeUsers.length > 0;
}
groups = await this.getGroups(groupForce);
}
} finally {
await this.client.unbind();
}
await this.unbind();
return [groups, users];
}
@@ -101,10 +110,7 @@ export class LdapDirectoryService implements IDirectoryService {
const deletedPath = this.makeSearchPath("CN=Deleted Objects");
this.logService.info("Deleted user search: " + deletedPath + " => " + deletedFilter);
const delControl = new (ldap as any).Control({
type: "1.2.840.113556.1.4.417",
criticality: true,
});
const delControl = new ldapts.Control("1.2.840.113556.1.4.417", { critical: true });
const deletedUsers = await this.search<UserEntry>(
deletedPath,
deletedFilter,
@@ -120,7 +126,7 @@ export class LdapDirectoryService implements IDirectoryService {
private buildUser(searchEntry: any, deleted: boolean): UserEntry {
const user = new UserEntry();
user.referenceId = searchEntry.objectName;
user.referenceId = this.getReferenceId(searchEntry);
user.deleted = deleted;
if (user.referenceId == null) {
@@ -172,7 +178,7 @@ export class LdapDirectoryService implements IDirectoryService {
let groupSearchEntries: any[] = [];
const initialSearchGroupIds = await this.search<string>(path, filter, (se: any) => {
groupSearchEntries.push(se);
return se.objectName;
return this.getReferenceId(se);
});
if (searchSinceRevision && initialSearchGroupIds.length === 0) {
@@ -188,7 +194,7 @@ export class LdapDirectoryService implements IDirectoryService {
const userPath = this.makeSearchPath(this.syncConfig.userPath);
const userIdMap = new Map<string, string>();
await this.search<string>(userPath, userFilter, (se: any) => {
userIdMap.set(se.objectName, this.getExternalId(se, se.objectName));
userIdMap.set(this.getReferenceId(se), this.getExternalId(se, this.getReferenceId(se)));
return se;
});
@@ -204,7 +210,7 @@ export class LdapDirectoryService implements IDirectoryService {
private buildGroup(searchEntry: any, userMap: Map<string, string>) {
const group = new GroupEntry();
group.referenceId = searchEntry.objectName;
group.referenceId = this.getReferenceId(searchEntry);
if (group.referenceId == null) {
return null;
}
@@ -220,7 +226,7 @@ export class LdapDirectoryService implements IDirectoryService {
return null;
}
const members = this.getAttrVals(searchEntry, this.syncConfig.memberAttribute);
const members = this.getAttrVals<string>(searchEntry, this.syncConfig.memberAttribute);
if (members != null) {
for (const memDn of members) {
if (userMap.has(memDn) && !group.userMemberExternalIds.has(userMap.get(memDn))) {
@@ -234,15 +240,26 @@ export class LdapDirectoryService implements IDirectoryService {
return group;
}
private getExternalId(searchEntry: any, referenceId: string) {
const attrObj = this.getAttrObj(searchEntry, "objectGUID");
if (attrObj != null && attrObj._vals != null && attrObj._vals.length > 0) {
return this.bufToGuid(attrObj._vals[0]);
/**
* The externalId is the "objectGUID" property if present (a unique identifier used by Active Directory),
* otherwise it falls back to the provided referenceId.
*/
private getExternalId(searchEntry: ldapts.Entry, referenceId: string) {
const attr = this.getAttr<Buffer>(searchEntry, ActiveDirectoryExternalId);
if (attr != null) {
return this.bufToGuid(attr);
} else {
return referenceId;
}
}
/**
* Gets the object's reference id (dn)
*/
private getReferenceId(entry: ldapts.Entry): string {
return entry.dn;
}
private buildBaseFilter(objectClass: string, subFilter: string): string {
let filter = this.buildObjectClassFilter(objectClass);
if (subFilter != null && subFilter.trim() !== "") {
@@ -281,42 +298,48 @@ export class LdapDirectoryService implements IDirectoryService {
return null;
}
private getAttrObj(searchEntry: any, attr: string): any {
if (searchEntry == null || searchEntry.attributes == null) {
/**
*/
/**
* Get all values for an ldap attribute
* @param searchEntry The ldap entry
* @param attr An attribute name on the ldap entry
* @returns An array containing all values of the attribute, or null if there are no values
*/
private getAttrVals<T extends string | Buffer>(
searchEntry: ldapts.Entry,
attr: string,
): T[] | null {
if (searchEntry == null || searchEntry[attr] == null) {
return null;
}
const attrs = searchEntry.attributes.filter((a: any) => a.type === attr);
if (
attrs == null ||
attrs.length === 0 ||
attrs[0].vals == null ||
attrs[0].vals.length === 0
) {
return null;
const vals = searchEntry[attr];
if (!Array.isArray(vals)) {
return [vals] as T[];
}
return attrs[0];
return vals as T[];
}
private getAttrVals(searchEntry: any, attr: string): string[] {
const obj = this.getAttrObj(searchEntry, attr);
if (obj == null) {
return null;
}
return obj.vals;
}
private getAttr(searchEntry: any, attr: string): string {
/**
* Get the first value for an ldap attribute
* @param searchEntry The ldap entry
* @param attr An attribute name on the ldap entry
* @returns The first value of the attribute, or null if there is not at least 1 value
*/
private getAttr<T extends string | Buffer>(searchEntry: ldapts.Entry, attr: string): T {
const vals = this.getAttrVals(searchEntry, attr);
if (vals == null) {
if (vals == null || vals.length < 1) {
return null;
}
return vals[0];
return vals[0] as T;
}
private entryDisabled(searchEntry: any): boolean {
const c = this.getAttr(searchEntry, "userAccountControl");
const c = this.getAttr<string>(searchEntry, "userAccountControl");
if (c != null) {
try {
const control = parseInt(c, null);
@@ -333,145 +356,106 @@ export class LdapDirectoryService implements IDirectoryService {
private async search<T>(
path: string,
filter: string,
processEntry: (searchEntry: any) => T,
controls: ldap.Control[] = [],
processEntry: (searchEntry: ldapts.Entry) => T,
controls: ldapts.Control[] = [],
): Promise<T[]> {
const options: ldap.SearchOptions = {
const options: ldapts.SearchOptions = {
filter: filter,
scope: "sub",
paged: this.dirConfig.pagedSearch,
// We need to expressly tell ldapts what attributes to return as Buffer objects,
// otherwise they are returned as strings
explicitBufferAttributes: [ActiveDirectoryExternalId],
};
const entries: T[] = [];
return new Promise<T[]>((resolve, reject) => {
this.client.search(path, options, controls, (err, res) => {
if (err != null) {
reject(err);
return;
}
res.on("error", (resErr) => {
reject(resErr);
});
res.on("searchEntry", (entry) => {
const e = processEntry(entry);
if (e != null) {
entries.push(e);
}
});
res.on("end", (result) => {
resolve(entries);
});
});
});
const { searchEntries } = await this.client.search(path, options, controls);
return searchEntries.map((e) => processEntry(e)).filter((e) => e != null);
}
private async bind(): Promise<any> {
return new Promise<void>((resolve, reject) => {
if (this.dirConfig.hostname == null || this.dirConfig.port == null) {
reject(this.i18nService.t("dirConfigIncomplete"));
return;
}
const protocol = "ldap" + (this.dirConfig.ssl && !this.dirConfig.startTls ? "s" : "");
const url = protocol + "://" + this.dirConfig.hostname + ":" + this.dirConfig.port;
const options: ldap.ClientOptions = {
url: url.trim().toLowerCase(),
};
if (this.dirConfig.hostname == null || this.dirConfig.port == null) {
throw new Error(this.i18nService.t("dirConfigIncomplete"));
}
const tlsOptions: any = {};
if (this.dirConfig.ssl) {
if (this.dirConfig.sslAllowUnauthorized) {
tlsOptions.rejectUnauthorized = !this.dirConfig.sslAllowUnauthorized;
}
if (!this.dirConfig.startTls) {
if (
this.dirConfig.sslCaPath != null &&
this.dirConfig.sslCaPath !== "" &&
fs.existsSync(this.dirConfig.sslCaPath)
) {
tlsOptions.ca = [fs.readFileSync(this.dirConfig.sslCaPath)];
}
if (
this.dirConfig.sslCertPath != null &&
this.dirConfig.sslCertPath !== "" &&
fs.existsSync(this.dirConfig.sslCertPath)
) {
tlsOptions.cert = fs.readFileSync(this.dirConfig.sslCertPath);
}
if (
this.dirConfig.sslKeyPath != null &&
this.dirConfig.sslKeyPath !== "" &&
fs.existsSync(this.dirConfig.sslKeyPath)
) {
tlsOptions.key = fs.readFileSync(this.dirConfig.sslKeyPath);
}
} else {
if (
this.dirConfig.tlsCaPath != null &&
this.dirConfig.tlsCaPath !== "" &&
fs.existsSync(this.dirConfig.tlsCaPath)
) {
tlsOptions.ca = [fs.readFileSync(this.dirConfig.tlsCaPath)];
}
}
}
const protocol = this.dirConfig.ssl && !this.dirConfig.startTls ? "ldaps" : "ldap";
tlsOptions.checkServerIdentity = this.checkServerIdentityAltNames;
options.tlsOptions = tlsOptions;
const url = protocol + "://" + this.dirConfig.hostname + ":" + this.dirConfig.port;
const options: ldapts.ClientOptions = {
url: url.trim().toLowerCase(),
};
this.client = ldap.createClient(options);
// If using ldaps, TLS options are given to the client constructor
if (protocol === "ldaps") {
options.tlsOptions = this.buildTlsOptions();
}
const user =
this.dirConfig.username == null || this.dirConfig.username.trim() === ""
? null
: this.dirConfig.username;
const pass =
this.dirConfig.password == null || this.dirConfig.password.trim() === ""
? null
: this.dirConfig.password;
this.client = new ldapts.Client(options);
if (user == null || pass == null) {
reject(this.i18nService.t("usernamePasswordNotConfigured"));
return;
}
const user =
this.dirConfig.username == null || this.dirConfig.username.trim() === ""
? null
: this.dirConfig.username;
const pass =
this.dirConfig.password == null || this.dirConfig.password.trim() === ""
? null
: this.dirConfig.password;
if (this.dirConfig.startTls && this.dirConfig.ssl) {
this.client.starttls(options.tlsOptions, undefined, (err, res) => {
if (err != null) {
reject(err.message);
} else {
this.client.bind(user, pass, (err2) => {
if (err2 != null) {
reject(err2.message);
} else {
resolve();
}
});
}
});
} else {
this.client.bind(user, pass, (err) => {
if (err != null) {
reject(err.message);
} else {
resolve();
}
});
}
});
if (user == null || pass == null) {
throw new Error(this.i18nService.t("usernamePasswordNotConfigured"));
}
// If using StartTLS, TLS options are given to the StartTLS call
if (this.dirConfig.startTls && this.dirConfig.ssl) {
await this.client.startTLS(this.buildTlsOptions());
}
try {
await this.client.bind(user, pass);
} catch {
await this.client.unbind();
}
}
private async unbind(): Promise<void> {
return new Promise((resolve, reject) => {
this.client.unbind((err) => {
if (err != null) {
reject(err);
} else {
resolve();
}
});
});
private buildTlsOptions(): tls.ConnectionOptions {
const tlsOptions: tls.ConnectionOptions = {};
if (this.dirConfig.sslAllowUnauthorized) {
tlsOptions.rejectUnauthorized = !this.dirConfig.sslAllowUnauthorized;
}
if (!this.dirConfig.startTls) {
if (
this.dirConfig.sslCaPath != null &&
this.dirConfig.sslCaPath !== "" &&
fs.existsSync(this.dirConfig.sslCaPath)
) {
tlsOptions.ca = [fs.readFileSync(this.dirConfig.sslCaPath)];
}
if (
this.dirConfig.sslCertPath != null &&
this.dirConfig.sslCertPath !== "" &&
fs.existsSync(this.dirConfig.sslCertPath)
) {
tlsOptions.cert = fs.readFileSync(this.dirConfig.sslCertPath);
}
if (
this.dirConfig.sslKeyPath != null &&
this.dirConfig.sslKeyPath !== "" &&
fs.existsSync(this.dirConfig.sslKeyPath)
) {
tlsOptions.key = fs.readFileSync(this.dirConfig.sslKeyPath);
}
} else {
if (
this.dirConfig.tlsCaPath != null &&
this.dirConfig.tlsCaPath !== "" &&
fs.existsSync(this.dirConfig.tlsCaPath)
) {
tlsOptions.ca = [fs.readFileSync(this.dirConfig.tlsCaPath)];
}
}
tlsOptions.checkServerIdentity = this.checkServerIdentityAltNames;
return tlsOptions;
}
private bufToGuid(buf: Buffer) {
@@ -494,7 +478,7 @@ export class LdapDirectoryService implements IDirectoryService {
return guid.toLowerCase();
}
private checkServerIdentityAltNames(host: string, cert: PeerCertificate) {
private checkServerIdentityAltNames(host: string, cert: tls.PeerCertificate) {
// Fixes the cert representation when subject is empty and altNames are present
// Required for node versions < 12.14.1 (which could be used for bwdc cli)
// Adapted from: https://github.com/auth0/ad-ldap-connector/commit/1f4dd2be6ed93dda591dd31ed5483a9b452a8d2a
@@ -510,6 +494,6 @@ export class LdapDirectoryService implements IDirectoryService {
};
}
return checkServerIdentity(host, cert);
return tls.checkServerIdentity(host, cert);
}
}