mirror of
https://github.com/bitwarden/directory-connector
synced 2025-12-11 13:53:22 +00:00
Compare commits
31 Commits
jmccannon/
...
split-buil
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2bf699573 | ||
|
|
284206b735 | ||
|
|
51042857c9 | ||
|
|
a462ae7457 | ||
|
|
5dfd60d25c | ||
|
|
19937fcbe9 | ||
|
|
46405ad75c | ||
|
|
04ee7533e4 | ||
|
|
02aa653a48 | ||
|
|
921466677e | ||
|
|
e8f0d17944 | ||
|
|
2cc2292ed6 | ||
|
|
c96e0bb147 | ||
|
|
6964a7db49 | ||
|
|
32e3327974 | ||
|
|
3a46e1781e | ||
|
|
dc64f7191e | ||
|
|
570bcf1581 | ||
|
|
fc06bf401a | ||
|
|
61d7c996c1 | ||
|
|
71a19fecaa | ||
|
|
ae37cea276 | ||
|
|
09f1f6981c | ||
|
|
ceff0559f2 | ||
|
|
4d55bf0527 | ||
|
|
7347c1992f | ||
|
|
46d2797d8c | ||
|
|
ed58d7c758 | ||
|
|
cd6bbd792a | ||
|
|
3b3ea8ac47 | ||
|
|
5f9adf9ab7 |
@@ -1,4 +1,4 @@
|
|||||||
name: Build
|
name: Build CLI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request: {}
|
pull_request: {}
|
||||||
@@ -9,6 +9,9 @@ on:
|
|||||||
- "hotfix-rc"
|
- "hotfix-rc"
|
||||||
workflow_dispatch: {}
|
workflow_dispatch: {}
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
cloc:
|
cloc:
|
||||||
name: CLOC
|
name: CLOC
|
||||||
@@ -95,11 +98,6 @@ jobs:
|
|||||||
- 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: Create checksums
|
|
||||||
run: |
|
|
||||||
shasum -a 256 dist-cli/bwdc-linux-$_PACKAGE_VERSION.zip | \
|
|
||||||
cut -d " " -f 1 > dist-cli/bwdc-linux-sha256-$_PACKAGE_VERSION.txt
|
|
||||||
|
|
||||||
- name: Version Test
|
- name: Version Test
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
@@ -129,13 +127,6 @@ jobs:
|
|||||||
path: ./dist-cli/bwdc-linux-${{ env._PACKAGE_VERSION }}.zip
|
path: ./dist-cli/bwdc-linux-${{ env._PACKAGE_VERSION }}.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Linux checksum to GitHub
|
|
||||||
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
|
|
||||||
if-no-files-found: error
|
|
||||||
|
|
||||||
|
|
||||||
macos-cli:
|
macos-cli:
|
||||||
name: Build Mac CLI
|
name: Build Mac CLI
|
||||||
@@ -190,11 +181,6 @@ jobs:
|
|||||||
- 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: Create checksums
|
|
||||||
run: |
|
|
||||||
shasum -a 256 dist-cli/bwdc-macos-$_PACKAGE_VERSION.zip | \
|
|
||||||
cut -d " " -f 1 > dist-cli/bwdc-macos-sha256-$_PACKAGE_VERSION.txt
|
|
||||||
|
|
||||||
- name: Version Test
|
- name: Version Test
|
||||||
run: |
|
run: |
|
||||||
mkdir -p test/macos
|
mkdir -p test/macos
|
||||||
@@ -217,12 +203,6 @@ jobs:
|
|||||||
path: ./dist-cli/bwdc-macos-${{ env._PACKAGE_VERSION }}.zip
|
path: ./dist-cli/bwdc-macos-${{ env._PACKAGE_VERSION }}.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Mac checksum to GitHub
|
|
||||||
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
|
|
||||||
if-no-files-found: error
|
|
||||||
|
|
||||||
windows-cli:
|
windows-cli:
|
||||||
name: Build Windows CLI
|
name: Build Windows CLI
|
||||||
@@ -349,11 +329,6 @@ jobs:
|
|||||||
Throw "Version test failed."
|
Throw "Version test failed."
|
||||||
}
|
}
|
||||||
|
|
||||||
- name: Create checksums
|
|
||||||
run: |
|
|
||||||
checksum -f="./dist-cli/bwdc-windows-${env:_PACKAGE_VERSION}.zip" `
|
|
||||||
-t sha256 | Out-File ./dist-cli/bwdc-windows-sha256-${env:_PACKAGE_VERSION}.txt
|
|
||||||
|
|
||||||
- name: Upload Windows Zip to GitHub
|
- name: Upload Windows Zip to GitHub
|
||||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||||
with:
|
with:
|
||||||
@@ -361,283 +336,6 @@ jobs:
|
|||||||
path: ./dist-cli/bwdc-windows-${{ env._PACKAGE_VERSION }}.zip
|
path: ./dist-cli/bwdc-windows-${{ env._PACKAGE_VERSION }}.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Windows checksum to GitHub
|
|
||||||
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
|
|
||||||
if-no-files-found: error
|
|
||||||
|
|
||||||
|
|
||||||
windows-gui:
|
|
||||||
name: Build Windows GUI
|
|
||||||
runs-on: windows-2022
|
|
||||||
needs: setup
|
|
||||||
env:
|
|
||||||
NODE_OPTIONS: --max_old_space_size=4096
|
|
||||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
|
||||||
HUSKY: 0
|
|
||||||
steps:
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
||||||
|
|
||||||
- name: Set up Node
|
|
||||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
|
||||||
with:
|
|
||||||
cache: 'npm'
|
|
||||||
cache-dependency-path: '**/package-lock.json'
|
|
||||||
node-version: '18'
|
|
||||||
|
|
||||||
- name: Update NPM
|
|
||||||
run: |
|
|
||||||
npm install -g node-gyp
|
|
||||||
node-gyp install $(node -v)
|
|
||||||
|
|
||||||
- name: Print environment
|
|
||||||
run: |
|
|
||||||
node --version
|
|
||||||
npm --version
|
|
||||||
|
|
||||||
- name: Install AST
|
|
||||||
run: dotnet tool install --global AzureSignTool --version 4.0.1
|
|
||||||
|
|
||||||
- name: Install Node dependencies
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- name: Login to Azure
|
|
||||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
|
||||||
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: "code-signing-vault-url,
|
|
||||||
code-signing-client-id,
|
|
||||||
code-signing-tenant-id,
|
|
||||||
code-signing-client-secret,
|
|
||||||
code-signing-cert-name"
|
|
||||||
|
|
||||||
- name: Build & Sign
|
|
||||||
run: npm run dist:win
|
|
||||||
env:
|
|
||||||
ELECTRON_BUILDER_SIGN: 1
|
|
||||||
SIGNING_VAULT_URL: ${{ steps.retrieve-secrets.outputs.code-signing-vault-url }}
|
|
||||||
SIGNING_CLIENT_ID: ${{ steps.retrieve-secrets.outputs.code-signing-client-id }}
|
|
||||||
SIGNING_TENANT_ID: ${{ steps.retrieve-secrets.outputs.code-signing-tenant-id }}
|
|
||||||
SIGNING_CLIENT_SECRET: ${{ steps.retrieve-secrets.outputs.code-signing-client-secret }}
|
|
||||||
SIGNING_CERT_NAME: ${{ steps.retrieve-secrets.outputs.code-signing-cert-name }}
|
|
||||||
|
|
||||||
- name: Upload Portable Executable to GitHub
|
|
||||||
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@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@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@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
|
||||||
with:
|
|
||||||
name: latest.yml
|
|
||||||
path: ./dist/latest.yml
|
|
||||||
if-no-files-found: error
|
|
||||||
|
|
||||||
|
|
||||||
linux-gui:
|
|
||||||
name: Build Linux GUI
|
|
||||||
runs-on: ubuntu-24.04
|
|
||||||
needs: setup
|
|
||||||
env:
|
|
||||||
NODE_OPTIONS: --max_old_space_size=4096
|
|
||||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
|
||||||
HUSKY: 0
|
|
||||||
steps:
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
||||||
|
|
||||||
- name: Set up Node
|
|
||||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
|
||||||
with:
|
|
||||||
cache: 'npm'
|
|
||||||
cache-dependency-path: '**/package-lock.json'
|
|
||||||
node-version: '18'
|
|
||||||
|
|
||||||
- name: Update NPM
|
|
||||||
run: |
|
|
||||||
npm install -g node-gyp
|
|
||||||
node-gyp install $(node -v)
|
|
||||||
|
|
||||||
- name: Set up environment
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get -y install pkg-config libxss-dev libsecret-1-dev
|
|
||||||
sudo apt-get -y install rpm
|
|
||||||
|
|
||||||
- name: NPM Install
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- name: NPM Rebuild
|
|
||||||
run: npm run rebuild
|
|
||||||
|
|
||||||
- name: NPM Package
|
|
||||||
run: npm run dist:lin
|
|
||||||
|
|
||||||
- name: Upload AppImage
|
|
||||||
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@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
|
||||||
with:
|
|
||||||
name: latest-linux.yml
|
|
||||||
path: ./dist/latest-linux.yml
|
|
||||||
if-no-files-found: error
|
|
||||||
|
|
||||||
|
|
||||||
macos-gui:
|
|
||||||
name: Build MacOS GUI
|
|
||||||
runs-on: macos-13
|
|
||||||
needs: setup
|
|
||||||
env:
|
|
||||||
NODE_OPTIONS: --max_old_space_size=4096
|
|
||||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
|
||||||
HUSKY: 0
|
|
||||||
steps:
|
|
||||||
- name: Checkout repo
|
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
||||||
|
|
||||||
- name: Set up Node
|
|
||||||
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
|
||||||
with:
|
|
||||||
cache: 'npm'
|
|
||||||
cache-dependency-path: '**/package-lock.json'
|
|
||||||
node-version: '18'
|
|
||||||
|
|
||||||
- name: Update NPM
|
|
||||||
run: |
|
|
||||||
npm install -g node-gyp
|
|
||||||
node-gyp install $(node -v)
|
|
||||||
|
|
||||||
- name: Print environment
|
|
||||||
run: |
|
|
||||||
node --version
|
|
||||||
npm --version
|
|
||||||
echo "GitHub ref: $GITHUB_REF"
|
|
||||||
echo "GitHub event: $GITHUB_EVENT"
|
|
||||||
|
|
||||||
- name: Login to Azure
|
|
||||||
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
|
||||||
with:
|
|
||||||
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
|
||||||
|
|
||||||
- name: Get certificates
|
|
||||||
run: |
|
|
||||||
mkdir -p $HOME/certificates
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert |
|
|
||||||
jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12
|
|
||||||
|
|
||||||
- name: Set up keychain
|
|
||||||
env:
|
|
||||||
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
|
||||||
run: |
|
|
||||||
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
|
|
||||||
security default-keychain -s build.keychain
|
|
||||||
security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain
|
|
||||||
security set-keychain-settings -lut 1200 build.keychain
|
|
||||||
|
|
||||||
security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \
|
|
||||||
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
|
|
||||||
|
|
||||||
security import "$HOME/certificates/devid-installer-cert.p12" -k build.keychain -P "" \
|
|
||||||
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
|
|
||||||
|
|
||||||
security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \
|
|
||||||
-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
|
|
||||||
|
|
||||||
- name: Load package version
|
|
||||||
run: |
|
|
||||||
$rootPath = $env:GITHUB_WORKSPACE;
|
|
||||||
$packageVersion = (Get-Content -Raw -Path $rootPath\package.json | ConvertFrom-Json).version;
|
|
||||||
|
|
||||||
Write-Output "Setting package version to $packageVersion";
|
|
||||||
Write-Output "PACKAGE_VERSION=$packageVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append;
|
|
||||||
shell: pwsh
|
|
||||||
|
|
||||||
- name: Install Node dependencies
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- name: Set up private auth key
|
|
||||||
run: |
|
|
||||||
mkdir ~/private_keys
|
|
||||||
cat << EOF > ~/private_keys/AuthKey_UFD296548T.p8
|
|
||||||
${{ secrets.APP_STORE_CONNECT_AUTH_KEY }}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
- name: Build application
|
|
||||||
run: npm run dist:mac
|
|
||||||
env:
|
|
||||||
APP_STORE_CONNECT_TEAM_ISSUER: ${{ secrets.APP_STORE_CONNECT_TEAM_ISSUER }}
|
|
||||||
APP_STORE_CONNECT_AUTH_KEY: UFD296548T
|
|
||||||
APP_STORE_CONNECT_AUTH_KEY_PATH: ~/private_keys/AuthKey_UFD296548T.p8
|
|
||||||
CSC_FOR_PULL_REQUEST: true
|
|
||||||
|
|
||||||
- name: Upload .zip artifact
|
|
||||||
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@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@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@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
|
||||||
with:
|
|
||||||
name: latest-mac.yml
|
|
||||||
path: ./dist/latest-mac.yml
|
|
||||||
if-no-files-found: error
|
|
||||||
|
|
||||||
|
|
||||||
check-failures:
|
check-failures:
|
||||||
name: Check for failures
|
name: Check for failures
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
@@ -647,9 +345,6 @@ jobs:
|
|||||||
- linux-cli
|
- linux-cli
|
||||||
- macos-cli
|
- macos-cli
|
||||||
- windows-cli
|
- windows-cli
|
||||||
- windows-gui
|
|
||||||
- linux-gui
|
|
||||||
- macos-gui
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check if any job failed
|
- name: Check if any job failed
|
||||||
if: |
|
if: |
|
||||||
354
.github/workflows/build-gui.yml
vendored
Normal file
354
.github/workflows/build-gui.yml
vendored
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
name: Build GUI
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request: {}
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "main"
|
||||||
|
- "rc"
|
||||||
|
- "hotfix-rc"
|
||||||
|
workflow_dispatch: {}
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
cloc:
|
||||||
|
name: CLOC
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
|
- name: Set up CLOC
|
||||||
|
run: |
|
||||||
|
sudo apt update
|
||||||
|
sudo apt -y install cloc
|
||||||
|
|
||||||
|
- name: Print lines of code
|
||||||
|
run: cloc --include-lang TypeScript,JavaScript,HTML,Sass,CSS --vcs git
|
||||||
|
|
||||||
|
|
||||||
|
setup:
|
||||||
|
name: Setup
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
outputs:
|
||||||
|
package_version: ${{ steps.retrieve-version.outputs.package_version }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
|
- name: Get Package Version
|
||||||
|
id: retrieve-version
|
||||||
|
run: |
|
||||||
|
PKG_VERSION=$(jq -r .version package.json)
|
||||||
|
echo "package_version=$PKG_VERSION" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
windows-gui:
|
||||||
|
name: Build Windows GUI
|
||||||
|
runs-on: windows-2022
|
||||||
|
needs: setup
|
||||||
|
env:
|
||||||
|
NODE_OPTIONS: --max_old_space_size=4096
|
||||||
|
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||||
|
HUSKY: 0
|
||||||
|
steps:
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
|
- name: Set up Node
|
||||||
|
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||||
|
with:
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: '**/package-lock.json'
|
||||||
|
node-version: '18'
|
||||||
|
|
||||||
|
- name: Update NPM
|
||||||
|
run: |
|
||||||
|
npm install -g node-gyp
|
||||||
|
node-gyp install $(node -v)
|
||||||
|
|
||||||
|
- name: Print environment
|
||||||
|
run: |
|
||||||
|
node --version
|
||||||
|
npm --version
|
||||||
|
|
||||||
|
- name: Install AST
|
||||||
|
run: dotnet tool install --global AzureSignTool --version 4.0.1
|
||||||
|
|
||||||
|
- name: Install Node dependencies
|
||||||
|
run: npm install
|
||||||
|
|
||||||
|
- name: Login to Azure
|
||||||
|
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||||
|
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: "code-signing-vault-url,
|
||||||
|
code-signing-client-id,
|
||||||
|
code-signing-tenant-id,
|
||||||
|
code-signing-client-secret,
|
||||||
|
code-signing-cert-name"
|
||||||
|
|
||||||
|
- name: Build & Sign
|
||||||
|
run: npm run dist:win
|
||||||
|
env:
|
||||||
|
ELECTRON_BUILDER_SIGN: 1
|
||||||
|
SIGNING_VAULT_URL: ${{ steps.retrieve-secrets.outputs.code-signing-vault-url }}
|
||||||
|
SIGNING_CLIENT_ID: ${{ steps.retrieve-secrets.outputs.code-signing-client-id }}
|
||||||
|
SIGNING_TENANT_ID: ${{ steps.retrieve-secrets.outputs.code-signing-tenant-id }}
|
||||||
|
SIGNING_CLIENT_SECRET: ${{ steps.retrieve-secrets.outputs.code-signing-client-secret }}
|
||||||
|
SIGNING_CERT_NAME: ${{ steps.retrieve-secrets.outputs.code-signing-cert-name }}
|
||||||
|
|
||||||
|
- name: Upload Portable Executable to GitHub
|
||||||
|
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@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@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@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||||
|
with:
|
||||||
|
name: latest.yml
|
||||||
|
path: ./dist/latest.yml
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
|
||||||
|
linux-gui:
|
||||||
|
name: Build Linux GUI
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
needs: setup
|
||||||
|
env:
|
||||||
|
NODE_OPTIONS: --max_old_space_size=4096
|
||||||
|
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||||
|
HUSKY: 0
|
||||||
|
steps:
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
|
- name: Set up Node
|
||||||
|
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||||
|
with:
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: '**/package-lock.json'
|
||||||
|
node-version: '18'
|
||||||
|
|
||||||
|
- name: Update NPM
|
||||||
|
run: |
|
||||||
|
npm install -g node-gyp
|
||||||
|
node-gyp install $(node -v)
|
||||||
|
|
||||||
|
- name: Set up environment
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get -y install pkg-config libxss-dev libsecret-1-dev
|
||||||
|
sudo apt-get -y install rpm
|
||||||
|
|
||||||
|
- name: NPM Install
|
||||||
|
run: npm install
|
||||||
|
|
||||||
|
- name: NPM Rebuild
|
||||||
|
run: npm run rebuild
|
||||||
|
|
||||||
|
- name: NPM Package
|
||||||
|
run: npm run dist:lin
|
||||||
|
|
||||||
|
- name: Upload AppImage
|
||||||
|
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@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||||
|
with:
|
||||||
|
name: latest-linux.yml
|
||||||
|
path: ./dist/latest-linux.yml
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
|
||||||
|
macos-gui:
|
||||||
|
name: Build MacOS GUI
|
||||||
|
runs-on: macos-13
|
||||||
|
needs: setup
|
||||||
|
env:
|
||||||
|
NODE_OPTIONS: --max_old_space_size=4096
|
||||||
|
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||||
|
HUSKY: 0
|
||||||
|
steps:
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
|
- name: Set up Node
|
||||||
|
uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
||||||
|
with:
|
||||||
|
cache: 'npm'
|
||||||
|
cache-dependency-path: '**/package-lock.json'
|
||||||
|
node-version: '18'
|
||||||
|
|
||||||
|
- name: Update NPM
|
||||||
|
run: |
|
||||||
|
npm install -g node-gyp
|
||||||
|
node-gyp install $(node -v)
|
||||||
|
|
||||||
|
- name: Print environment
|
||||||
|
run: |
|
||||||
|
node --version
|
||||||
|
npm --version
|
||||||
|
echo "GitHub ref: $GITHUB_REF"
|
||||||
|
echo "GitHub event: $GITHUB_EVENT"
|
||||||
|
|
||||||
|
- name: Login to Azure
|
||||||
|
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||||
|
with:
|
||||||
|
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||||
|
|
||||||
|
- name: Get certificates
|
||||||
|
run: |
|
||||||
|
mkdir -p $HOME/certificates
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
az keyvault secret show --id https://bitwarden-ci.vault.azure.net/certificates/macdev-cert |
|
||||||
|
jq -r .value | base64 -d > $HOME/certificates/macdev-cert.p12
|
||||||
|
|
||||||
|
- name: Set up keychain
|
||||||
|
env:
|
||||||
|
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
||||||
|
run: |
|
||||||
|
security create-keychain -p $KEYCHAIN_PASSWORD build.keychain
|
||||||
|
security default-keychain -s build.keychain
|
||||||
|
security unlock-keychain -p $KEYCHAIN_PASSWORD build.keychain
|
||||||
|
security set-keychain-settings -lut 1200 build.keychain
|
||||||
|
|
||||||
|
security import "$HOME/certificates/devid-app-cert.p12" -k build.keychain -P "" \
|
||||||
|
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
|
||||||
|
|
||||||
|
security import "$HOME/certificates/devid-installer-cert.p12" -k build.keychain -P "" \
|
||||||
|
-T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
|
||||||
|
|
||||||
|
security import "$HOME/certificates/macdev-cert.p12" -k build.keychain -P "" \
|
||||||
|
-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
|
||||||
|
|
||||||
|
- name: Load package version
|
||||||
|
run: |
|
||||||
|
$rootPath = $env:GITHUB_WORKSPACE;
|
||||||
|
$packageVersion = (Get-Content -Raw -Path $rootPath\package.json | ConvertFrom-Json).version;
|
||||||
|
|
||||||
|
Write-Output "Setting package version to $packageVersion";
|
||||||
|
Write-Output "PACKAGE_VERSION=$packageVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append;
|
||||||
|
shell: pwsh
|
||||||
|
|
||||||
|
- name: Install Node dependencies
|
||||||
|
run: npm install
|
||||||
|
|
||||||
|
- name: Set up private auth key
|
||||||
|
run: |
|
||||||
|
mkdir ~/private_keys
|
||||||
|
cat << EOF > ~/private_keys/AuthKey_UFD296548T.p8
|
||||||
|
${{ secrets.APP_STORE_CONNECT_AUTH_KEY }}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
- name: Build application
|
||||||
|
run: npm run dist:mac
|
||||||
|
env:
|
||||||
|
APP_STORE_CONNECT_TEAM_ISSUER: ${{ secrets.APP_STORE_CONNECT_TEAM_ISSUER }}
|
||||||
|
APP_STORE_CONNECT_AUTH_KEY: UFD296548T
|
||||||
|
APP_STORE_CONNECT_AUTH_KEY_PATH: ~/private_keys/AuthKey_UFD296548T.p8
|
||||||
|
CSC_FOR_PULL_REQUEST: true
|
||||||
|
|
||||||
|
- name: Upload .zip artifact
|
||||||
|
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@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@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@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
|
||||||
|
with:
|
||||||
|
name: latest-mac.yml
|
||||||
|
path: ./dist/latest-mac.yml
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
|
||||||
|
check-failures:
|
||||||
|
name: Check for failures
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
needs:
|
||||||
|
- cloc
|
||||||
|
- setup
|
||||||
|
- windows-gui
|
||||||
|
- linux-gui
|
||||||
|
- macos-gui
|
||||||
|
steps:
|
||||||
|
- name: Check if any job failed
|
||||||
|
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
|
||||||
|
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||||
|
|
||||||
|
- name: Retrieve secrets
|
||||||
|
id: retrieve-secrets
|
||||||
|
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||||
|
if: failure()
|
||||||
|
with:
|
||||||
|
keyvault: "bitwarden-ci"
|
||||||
|
secrets: "devops-alerts-slack-webhook-url"
|
||||||
|
|
||||||
|
- name: Notify Slack on failure
|
||||||
|
uses: act10ns/slack@44541246747a30eb3102d87f7a4cc5471b0ffb7d # v2.1.0
|
||||||
|
if: failure()
|
||||||
|
env:
|
||||||
|
SLACK_WEBHOOK_URL: ${{ steps.retrieve-secrets.outputs.devops-alerts-slack-webhook-url }}
|
||||||
|
with:
|
||||||
|
status: ${{ job.status }}
|
||||||
3
.github/workflows/enforce-labels.yml
vendored
3
.github/workflows/enforce-labels.yml
vendored
@@ -3,6 +3,9 @@ name: Enforce PR labels
|
|||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
types: [labeled, unlabeled, opened, edited, synchronize]
|
types: [labeled, unlabeled, opened, edited, synchronize]
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pull-requests: read
|
||||||
jobs:
|
jobs:
|
||||||
enforce-label:
|
enforce-label:
|
||||||
name: EnforceLabel
|
name: EnforceLabel
|
||||||
|
|||||||
83
.github/workflows/release-cli.yml
vendored
Normal file
83
.github/workflows/release-cli.yml
vendored
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
|
||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
release_type:
|
||||||
|
description: 'Release Options'
|
||||||
|
required: true
|
||||||
|
default: 'Initial Release'
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- Initial Release
|
||||||
|
- Redeploy
|
||||||
|
- Dry Run
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
setup:
|
||||||
|
name: Setup
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
outputs:
|
||||||
|
release_version: ${{ steps.version.outputs.version }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
|
|
||||||
|
- name: Branch check
|
||||||
|
if: ${{ inputs.release_type != 'Dry Run' }}
|
||||||
|
run: |
|
||||||
|
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc" ]]; then
|
||||||
|
echo "==================================="
|
||||||
|
echo "[!] Can only release from the 'rc' or 'hotfix-rc' branches"
|
||||||
|
echo "==================================="
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check Release Version
|
||||||
|
id: version
|
||||||
|
uses: bitwarden/gh-actions/release-version-check@main
|
||||||
|
with:
|
||||||
|
release-type: ${{ inputs.release_type }}
|
||||||
|
project-type: ts
|
||||||
|
file: package.json
|
||||||
|
|
||||||
|
release:
|
||||||
|
name: Release
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
needs: setup
|
||||||
|
steps:
|
||||||
|
- name: Download all artifacts
|
||||||
|
if: ${{ inputs.release_type != 'Dry Run' }}
|
||||||
|
uses: bitwarden/gh-actions/download-artifacts@main
|
||||||
|
with:
|
||||||
|
workflow: build-cli.yml
|
||||||
|
workflow_conclusion: success
|
||||||
|
branch: ${{ github.ref_name }}
|
||||||
|
|
||||||
|
- name: Dry Run - Download all artifacts
|
||||||
|
if: ${{ inputs.release_type == 'Dry Run' }}
|
||||||
|
uses: bitwarden/gh-actions/download-artifacts@main
|
||||||
|
with:
|
||||||
|
workflow: build-cli.yml
|
||||||
|
workflow_conclusion: success
|
||||||
|
branch: main
|
||||||
|
|
||||||
|
- name: Create release
|
||||||
|
if: ${{ inputs.release_type != 'Dry Run' }}
|
||||||
|
uses: ncipollo/release-action@cdcc88a9acf3ca41c16c37bb7d21b9ad48560d87 # v1.15.0
|
||||||
|
env:
|
||||||
|
PKG_VERSION: ${{ needs.setup.outputs.release_version }}
|
||||||
|
with:
|
||||||
|
artifacts: "./bwdc-windows-${{ env.PKG_VERSION }}.zip,
|
||||||
|
./bwdc-macos-${{ env.PKG_VERSION }}.zip,
|
||||||
|
./bwdc-linux-${{ env.PKG_VERSION }}.zip"
|
||||||
|
commit: ${{ github.sha }}
|
||||||
|
tag: v${{ env.PKG_VERSION }}
|
||||||
|
name: Version ${{ env.PKG_VERSION }}
|
||||||
|
body: "<insert release notes here>"
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
draft: true
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
name: Release
|
name: Release GUI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -13,6 +13,9 @@ on:
|
|||||||
- Redeploy
|
- Redeploy
|
||||||
- Dry Run
|
- Dry Run
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
setup:
|
setup:
|
||||||
name: Setup
|
name: Setup
|
||||||
@@ -50,7 +53,7 @@ jobs:
|
|||||||
if: ${{ inputs.release_type != 'Dry Run' }}
|
if: ${{ inputs.release_type != 'Dry Run' }}
|
||||||
uses: bitwarden/gh-actions/download-artifacts@main
|
uses: bitwarden/gh-actions/download-artifacts@main
|
||||||
with:
|
with:
|
||||||
workflow: build.yml
|
workflow: build-gui.yml
|
||||||
workflow_conclusion: success
|
workflow_conclusion: success
|
||||||
branch: ${{ github.ref_name }}
|
branch: ${{ github.ref_name }}
|
||||||
|
|
||||||
@@ -58,7 +61,7 @@ jobs:
|
|||||||
if: ${{ inputs.release_type == 'Dry Run' }}
|
if: ${{ inputs.release_type == 'Dry Run' }}
|
||||||
uses: bitwarden/gh-actions/download-artifacts@main
|
uses: bitwarden/gh-actions/download-artifacts@main
|
||||||
with:
|
with:
|
||||||
workflow: build.yml
|
workflow: build-gui.yml
|
||||||
workflow_conclusion: success
|
workflow_conclusion: success
|
||||||
branch: main
|
branch: main
|
||||||
|
|
||||||
@@ -68,13 +71,7 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
PKG_VERSION: ${{ needs.setup.outputs.release_version }}
|
PKG_VERSION: ${{ needs.setup.outputs.release_version }}
|
||||||
with:
|
with:
|
||||||
artifacts: "./bwdc-windows-${{ env.PKG_VERSION }}.zip,
|
artifacts: " ./Bitwarden-Connector-Portable-${{ env.PKG_VERSION }}.exe,
|
||||||
./bwdc-macos-${{ env.PKG_VERSION }}.zip,
|
|
||||||
./bwdc-linux-${{ env.PKG_VERSION }}.zip,
|
|
||||||
./bwdc-windows-sha256-${{ env.PKG_VERSION }}.txt,
|
|
||||||
./bwdc-macos-sha256-${{ env.PKG_VERSION }}.txt,
|
|
||||||
./bwdc-linux-sha256-${{ env.PKG_VERSION }}.txt,
|
|
||||||
./Bitwarden-Connector-Portable-${{ env.PKG_VERSION }}.exe,
|
|
||||||
./Bitwarden-Connector-Installer-${{ env.PKG_VERSION }}.exe,
|
./Bitwarden-Connector-Installer-${{ env.PKG_VERSION }}.exe,
|
||||||
./Bitwarden-Connector-Installer-${{ env.PKG_VERSION }}.exe.blockmap,
|
./Bitwarden-Connector-Installer-${{ env.PKG_VERSION }}.exe.blockmap,
|
||||||
./Bitwarden-Connector-${{ env.PKG_VERSION }}-x86_64.AppImage,
|
./Bitwarden-Connector-${{ env.PKG_VERSION }}-x86_64.AppImage,
|
||||||
14
.github/workflows/scan.yml
vendored
14
.github/workflows/scan.yml
vendored
@@ -5,13 +5,23 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "main"
|
- "main"
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
branches-ignore:
|
||||||
|
- main
|
||||||
pull_request_target:
|
pull_request_target:
|
||||||
types: [opened, synchronize]
|
types: [opened, synchronize, reopened]
|
||||||
|
branches:
|
||||||
|
- "main"
|
||||||
|
|
||||||
|
permissions: {}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check-run:
|
check-run:
|
||||||
name: Check PR run
|
name: Check PR run
|
||||||
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
|
uses: bitwarden/gh-actions/.github/workflows/check-run.yml@main
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
sast:
|
sast:
|
||||||
name: SAST scan
|
name: SAST scan
|
||||||
@@ -66,7 +76,7 @@ jobs:
|
|||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
|
||||||
- name: Scan with SonarCloud
|
- name: Scan with SonarCloud
|
||||||
uses: sonarsource/sonarqube-scan-action@bfd4e558cda28cda6b5defafb9232d191be8c203 # v4.2.1
|
uses: sonarsource/sonarqube-scan-action@2500896589ef8f7247069a56136f8dc177c27ccf # v5.2.0
|
||||||
env:
|
env:
|
||||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Supported directories:
|
|||||||
|
|
||||||
- Active Directory
|
- Active Directory
|
||||||
- Any other LDAP-based directory
|
- Any other LDAP-based directory
|
||||||
- Azure Active Directory
|
- Microsoft Entra ID
|
||||||
- G Suite (Google)
|
- G Suite (Google)
|
||||||
- Okta
|
- Okta
|
||||||
|
|
||||||
|
|||||||
2220
package-lock.json
generated
2220
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
45
package.json
45
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.5.0",
|
"version": "2025.6.1",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"bitwarden",
|
"bitwarden",
|
||||||
"password",
|
"password",
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
"@angular-eslint/template-parser": "17.5.3",
|
"@angular-eslint/template-parser": "17.5.3",
|
||||||
"@angular/compiler-cli": "17.3.12",
|
"@angular/compiler-cli": "17.3.12",
|
||||||
"@electron/notarize": "2.5.0",
|
"@electron/notarize": "2.5.0",
|
||||||
"@electron/rebuild": "3.7.1",
|
"@electron/rebuild": "3.7.2",
|
||||||
"@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": "17.3.17",
|
"@ngtools/webpack": "17.3.17",
|
||||||
@@ -90,17 +90,17 @@
|
|||||||
"@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.32.1",
|
"@typescript-eslint/eslint-plugin": "8.35.0",
|
||||||
"@typescript-eslint/parser": "8.32.1",
|
"@typescript-eslint/parser": "8.35.0",
|
||||||
"clean-webpack-plugin": "4.0.0",
|
"clean-webpack-plugin": "4.0.0",
|
||||||
"concurrently": "9.1.2",
|
"concurrently": "9.1.2",
|
||||||
"copy-webpack-plugin": "12.0.2",
|
"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": "16.5.0",
|
"dotenv": "16.5.0",
|
||||||
"electron": "34.1.1",
|
"electron": "34.5.8",
|
||||||
"electron-builder": "24.13.3",
|
"electron-builder": "24.13.3",
|
||||||
"electron-log": "5.2.4",
|
"electron-log": "5.4.1",
|
||||||
"electron-reload": "2.0.0-alpha.1",
|
"electron-reload": "2.0.0-alpha.1",
|
||||||
"electron-store": "8.2.0",
|
"electron-store": "8.2.0",
|
||||||
"electron-updater": "6.6.2",
|
"electron-updater": "6.6.2",
|
||||||
@@ -110,31 +110,31 @@
|
|||||||
"eslint-plugin-import": "2.31.0",
|
"eslint-plugin-import": "2.31.0",
|
||||||
"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.1",
|
"form-data": "4.0.3",
|
||||||
"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",
|
||||||
"jest": "29.7.0",
|
"jest": "29.7.0",
|
||||||
"jest-junit": "16.0.0",
|
"jest-junit": "16.0.0",
|
||||||
"jest-mock-extended": "3.0.7",
|
"jest-mock-extended": "4.0.0",
|
||||||
"jest-preset-angular": "14.5.5",
|
"jest-preset-angular": "14.6.0",
|
||||||
"lint-staged": "15.5.2",
|
"lint-staged": "16.1.2",
|
||||||
"mini-css-extract-plugin": "2.9.2",
|
"mini-css-extract-plugin": "2.9.2",
|
||||||
"node-abi": "3.74.0",
|
"node-abi": "3.75.0",
|
||||||
"node-forge": "1.3.1",
|
"node-forge": "1.3.1",
|
||||||
"node-loader": "2.1.0",
|
"node-loader": "2.1.0",
|
||||||
"pkg": "5.8.1",
|
"pkg": "5.8.1",
|
||||||
"prettier": "3.5.3",
|
"prettier": "3.5.3",
|
||||||
"rimraf": "6.0.1",
|
"rimraf": "6.0.1",
|
||||||
"rxjs": "7.8.2",
|
"rxjs": "7.8.2",
|
||||||
"sass": "1.79.4",
|
"sass": "1.89.2",
|
||||||
"sass-loader": "16.0.4",
|
"sass-loader": "16.0.5",
|
||||||
"ts-jest": "29.2.5",
|
"ts-jest": "29.4.0",
|
||||||
"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": "4.41.0",
|
||||||
"typescript": "5.4.5",
|
"typescript": "5.4.5",
|
||||||
"webpack": "5.97.1",
|
"webpack": "5.99.9",
|
||||||
"webpack-cli": "6.0.1",
|
"webpack-cli": "6.0.1",
|
||||||
"webpack-merge": "6.0.1",
|
"webpack-merge": "6.0.1",
|
||||||
"webpack-node-externals": "3.0.0",
|
"webpack-node-externals": "3.0.0",
|
||||||
@@ -152,25 +152,26 @@
|
|||||||
"@angular/router": "17.3.12",
|
"@angular/router": "17.3.12",
|
||||||
"@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.3",
|
"bootstrap": "5.3.7",
|
||||||
"browser-hrtime": "1.1.8",
|
"browser-hrtime": "1.1.8",
|
||||||
"chalk": "4.1.2",
|
"chalk": "4.1.2",
|
||||||
"commander": "13.1.0",
|
"commander": "14.0.0",
|
||||||
"core-js": "3.42.0",
|
"core-js": "3.43.0",
|
||||||
"form-data": "4.0.1",
|
"form-data": "4.0.3",
|
||||||
"google-auth-library": "9.15.1",
|
"google-auth-library": "9.15.1",
|
||||||
"googleapis": "144.0.0",
|
"googleapis": "144.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": "7.4.0",
|
"ldapts": "8.0.1",
|
||||||
"lowdb": "1.0.0",
|
"lowdb": "1.0.0",
|
||||||
"ngx-toastr": "19.0.0",
|
"ngx-toastr": "19.0.0",
|
||||||
"node-fetch": "2.7.0",
|
"node-fetch": "2.7.0",
|
||||||
"proper-lockfile": "4.1.2",
|
"proper-lockfile": "4.1.2",
|
||||||
"rxjs": "7.8.2",
|
"rxjs": "7.8.2",
|
||||||
"tldjs": "2.3.1",
|
"tldjs": "2.3.1",
|
||||||
"zone.js": "0.14.10"
|
"zone.js": "0.14.10",
|
||||||
|
"parse5": "7.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "~22.13.0",
|
"node": "~22.13.0",
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { StorageOptions } from "@/jslib/common/src/models/domain/storageOptions"
|
|||||||
|
|
||||||
import { DirectoryType } from "@/src/enums/directoryType";
|
import { DirectoryType } from "@/src/enums/directoryType";
|
||||||
import { Account } from "@/src/models/account";
|
import { Account } from "@/src/models/account";
|
||||||
import { AzureConfiguration } from "@/src/models/azureConfiguration";
|
import { EntraIdConfiguration } from "@/src/models/entraIdConfiguration";
|
||||||
import { GSuiteConfiguration } from "@/src/models/gsuiteConfiguration";
|
import { GSuiteConfiguration } from "@/src/models/gsuiteConfiguration";
|
||||||
import { LdapConfiguration } from "@/src/models/ldapConfiguration";
|
import { LdapConfiguration } from "@/src/models/ldapConfiguration";
|
||||||
import { OktaConfiguration } from "@/src/models/oktaConfiguration";
|
import { OktaConfiguration } from "@/src/models/oktaConfiguration";
|
||||||
@@ -17,7 +17,7 @@ export abstract class StateService extends BaseStateServiceAbstraction<Account>
|
|||||||
config:
|
config:
|
||||||
| LdapConfiguration
|
| LdapConfiguration
|
||||||
| GSuiteConfiguration
|
| GSuiteConfiguration
|
||||||
| AzureConfiguration
|
| EntraIdConfiguration
|
||||||
| OktaConfiguration
|
| OktaConfiguration
|
||||||
| OneLoginConfiguration,
|
| OneLoginConfiguration,
|
||||||
) => Promise<any>;
|
) => Promise<any>;
|
||||||
@@ -25,8 +25,8 @@ export abstract class StateService extends BaseStateServiceAbstraction<Account>
|
|||||||
setLdapConfiguration: (value: LdapConfiguration, options?: StorageOptions) => Promise<void>;
|
setLdapConfiguration: (value: LdapConfiguration, options?: StorageOptions) => Promise<void>;
|
||||||
getGsuiteConfiguration: (options?: StorageOptions) => Promise<GSuiteConfiguration>;
|
getGsuiteConfiguration: (options?: StorageOptions) => Promise<GSuiteConfiguration>;
|
||||||
setGsuiteConfiguration: (value: GSuiteConfiguration, options?: StorageOptions) => Promise<void>;
|
setGsuiteConfiguration: (value: GSuiteConfiguration, options?: StorageOptions) => Promise<void>;
|
||||||
getAzureConfiguration: (options?: StorageOptions) => Promise<AzureConfiguration>;
|
getEntraConfiguration: (options?: StorageOptions) => Promise<EntraIdConfiguration>;
|
||||||
setAzureConfiguration: (value: AzureConfiguration, options?: StorageOptions) => Promise<void>;
|
setEntraConfiguration: (value: EntraIdConfiguration, options?: StorageOptions) => Promise<void>;
|
||||||
getOktaConfiguration: (options?: StorageOptions) => Promise<OktaConfiguration>;
|
getOktaConfiguration: (options?: StorageOptions) => Promise<OktaConfiguration>;
|
||||||
setOktaConfiguration: (value: OktaConfiguration, options?: StorageOptions) => Promise<void>;
|
setOktaConfiguration: (value: OktaConfiguration, options?: StorageOptions) => Promise<void>;
|
||||||
getOneLoginConfiguration: (options?: StorageOptions) => Promise<OneLoginConfiguration>;
|
getOneLoginConfiguration: (options?: StorageOptions) => Promise<OneLoginConfiguration>;
|
||||||
|
|||||||
@@ -242,7 +242,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div [hidden]="directory != directoryType.AzureActiveDirectory">
|
<div [hidden]="directory != directoryType.EntraID">
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="identityAuthority" class="form-label">{{
|
<label for="identityAuthority" class="form-label">{{
|
||||||
"identityAuthority" | i18n
|
"identityAuthority" | i18n
|
||||||
@@ -251,10 +251,10 @@
|
|||||||
class="form-select"
|
class="form-select"
|
||||||
id="identityAuthority"
|
id="identityAuthority"
|
||||||
name="IdentityAuthority"
|
name="IdentityAuthority"
|
||||||
[(ngModel)]="azure.identityAuthority"
|
[(ngModel)]="entra.identityAuthority"
|
||||||
>
|
>
|
||||||
<option value="login.microsoftonline.com">Azure AD Public</option>
|
<option value="login.microsoftonline.com">Entra Id Public</option>
|
||||||
<option value="login.microsoftonline.us">Azure AD Government</option>
|
<option value="login.microsoftonline.us">Entra Id Government</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
@@ -264,7 +264,7 @@
|
|||||||
class="form-control"
|
class="form-control"
|
||||||
id="tenant"
|
id="tenant"
|
||||||
name="Tenant"
|
name="Tenant"
|
||||||
[(ngModel)]="azure.tenant"
|
[(ngModel)]="entra.tenant"
|
||||||
/>
|
/>
|
||||||
<div class="form-text">{{ "ex" | i18n }} companyad.onmicrosoft.com</div>
|
<div class="form-text">{{ "ex" | i18n }} companyad.onmicrosoft.com</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -275,29 +275,29 @@
|
|||||||
class="form-control"
|
class="form-control"
|
||||||
id="applicationId"
|
id="applicationId"
|
||||||
name="ApplicationId"
|
name="ApplicationId"
|
||||||
[(ngModel)]="azure.applicationId"
|
[(ngModel)]="entra.applicationId"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label for="secretKey" class="form-label">{{ "secretKey" | i18n }}</label>
|
<label for="secretKey" class="form-label">{{ "secretKey" | i18n }}</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input
|
<input
|
||||||
type="{{ showAzureKey ? 'text' : 'password' }}"
|
type="{{ showEntraKey ? 'text' : 'password' }}"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="secretKey"
|
id="secretKey"
|
||||||
name="SecretKey"
|
name="SecretKey"
|
||||||
[(ngModel)]="azure.key"
|
[(ngModel)]="entra.key"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-outline-secondary"
|
class="btn btn-outline-secondary"
|
||||||
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
|
||||||
(click)="toggleAzureKey()"
|
(click)="toggleEntraKey()"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
class="bwi bwi-lg"
|
class="bwi bwi-lg"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
[ngClass]="showAzureKey ? 'bwi-eye-slash' : 'bwi-eye'"
|
[ngClass]="showEntraKey ? 'bwi-eye-slash' : 'bwi-eye'"
|
||||||
></i>
|
></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -607,7 +607,7 @@
|
|||||||
<div class="form-text" *ngIf="directory === directoryType.Ldap">
|
<div class="form-text" *ngIf="directory === directoryType.Ldap">
|
||||||
{{ "ex" | i18n }} (&(givenName=John)(|(l=Dallas)(l=Austin)))
|
{{ "ex" | i18n }} (&(givenName=John)(|(l=Dallas)(l=Austin)))
|
||||||
</div>
|
</div>
|
||||||
<div class="form-text" *ngIf="directory === directoryType.AzureActiveDirectory">
|
<div class="form-text" *ngIf="directory === directoryType.EntraID">
|
||||||
{{ "ex" | i18n }} exclude:joe@company.com
|
{{ "ex" | i18n }} exclude:joe@company.com
|
||||||
</div>
|
</div>
|
||||||
<div class="form-text" *ngIf="directory === directoryType.Okta">
|
<div class="form-text" *ngIf="directory === directoryType.Okta">
|
||||||
@@ -684,7 +684,7 @@
|
|||||||
<div class="form-text" *ngIf="directory === directoryType.Ldap">
|
<div class="form-text" *ngIf="directory === directoryType.Ldap">
|
||||||
{{ "ex" | i18n }} (&(objectClass=group)(!(cn=Sales*))(!(cn=IT*)))
|
{{ "ex" | i18n }} (&(objectClass=group)(!(cn=Sales*))(!(cn=IT*)))
|
||||||
</div>
|
</div>
|
||||||
<div class="form-text" *ngIf="directory === directoryType.AzureActiveDirectory">
|
<div class="form-text" *ngIf="directory === directoryType.EntraID">
|
||||||
{{ "ex" | i18n }} include:Sales,IT
|
{{ "ex" | i18n }} include:Sales,IT
|
||||||
</div>
|
</div>
|
||||||
<div class="form-text" *ngIf="directory === directoryType.Okta">
|
<div class="form-text" *ngIf="directory === directoryType.Okta">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { LogService } from "@/jslib/common/src/abstractions/log.service";
|
|||||||
|
|
||||||
import { StateService } from "../../abstractions/state.service";
|
import { StateService } from "../../abstractions/state.service";
|
||||||
import { DirectoryType } from "../../enums/directoryType";
|
import { DirectoryType } from "../../enums/directoryType";
|
||||||
import { AzureConfiguration } from "../../models/azureConfiguration";
|
import { EntraIdConfiguration } from "../../models/entraIdConfiguration";
|
||||||
import { GSuiteConfiguration } from "../../models/gsuiteConfiguration";
|
import { GSuiteConfiguration } from "../../models/gsuiteConfiguration";
|
||||||
import { LdapConfiguration } from "../../models/ldapConfiguration";
|
import { LdapConfiguration } from "../../models/ldapConfiguration";
|
||||||
import { OktaConfiguration } from "../../models/oktaConfiguration";
|
import { OktaConfiguration } from "../../models/oktaConfiguration";
|
||||||
@@ -22,13 +22,13 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
|||||||
directoryType = DirectoryType;
|
directoryType = DirectoryType;
|
||||||
ldap = new LdapConfiguration();
|
ldap = new LdapConfiguration();
|
||||||
gsuite = new GSuiteConfiguration();
|
gsuite = new GSuiteConfiguration();
|
||||||
azure = new AzureConfiguration();
|
entra = new EntraIdConfiguration();
|
||||||
okta = new OktaConfiguration();
|
okta = new OktaConfiguration();
|
||||||
oneLogin = new OneLoginConfiguration();
|
oneLogin = new OneLoginConfiguration();
|
||||||
sync = new SyncConfiguration();
|
sync = new SyncConfiguration();
|
||||||
directoryOptions: any[];
|
directoryOptions: any[];
|
||||||
showLdapPassword = false;
|
showLdapPassword = false;
|
||||||
showAzureKey = false;
|
showEntraKey = false;
|
||||||
showOktaKey = false;
|
showOktaKey = false;
|
||||||
showOneLoginSecret = false;
|
showOneLoginSecret = false;
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
|||||||
this.directoryOptions = [
|
this.directoryOptions = [
|
||||||
{ name: this.i18nService.t("select"), value: null },
|
{ name: this.i18nService.t("select"), value: null },
|
||||||
{ name: "Active Directory / LDAP", value: DirectoryType.Ldap },
|
{ name: "Active Directory / LDAP", value: DirectoryType.Ldap },
|
||||||
{ name: "Azure Active Directory", value: DirectoryType.AzureActiveDirectory },
|
{ name: "Entra ID", value: DirectoryType.EntraID },
|
||||||
{ name: "G Suite (Google)", value: DirectoryType.GSuite },
|
{ name: "G Suite (Google)", value: DirectoryType.GSuite },
|
||||||
{ name: "Okta", value: DirectoryType.Okta },
|
{ name: "Okta", value: DirectoryType.Okta },
|
||||||
{ name: "OneLogin", value: DirectoryType.OneLogin },
|
{ name: "OneLogin", value: DirectoryType.OneLogin },
|
||||||
@@ -56,10 +56,9 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
|||||||
this.gsuite =
|
this.gsuite =
|
||||||
(await this.stateService.getDirectory<GSuiteConfiguration>(DirectoryType.GSuite)) ||
|
(await this.stateService.getDirectory<GSuiteConfiguration>(DirectoryType.GSuite)) ||
|
||||||
this.gsuite;
|
this.gsuite;
|
||||||
this.azure =
|
this.entra =
|
||||||
(await this.stateService.getDirectory<AzureConfiguration>(
|
(await this.stateService.getDirectory<EntraIdConfiguration>(DirectoryType.EntraID)) ||
|
||||||
DirectoryType.AzureActiveDirectory,
|
this.entra;
|
||||||
)) || this.azure;
|
|
||||||
this.okta =
|
this.okta =
|
||||||
(await this.stateService.getDirectory<OktaConfiguration>(DirectoryType.Okta)) || this.okta;
|
(await this.stateService.getDirectory<OktaConfiguration>(DirectoryType.Okta)) || this.okta;
|
||||||
this.oneLogin =
|
this.oneLogin =
|
||||||
@@ -80,7 +79,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
|||||||
await this.stateService.setDirectoryType(this.directory);
|
await this.stateService.setDirectoryType(this.directory);
|
||||||
await this.stateService.setDirectory(DirectoryType.Ldap, this.ldap);
|
await this.stateService.setDirectory(DirectoryType.Ldap, this.ldap);
|
||||||
await this.stateService.setDirectory(DirectoryType.GSuite, this.gsuite);
|
await this.stateService.setDirectory(DirectoryType.GSuite, this.gsuite);
|
||||||
await this.stateService.setDirectory(DirectoryType.AzureActiveDirectory, this.azure);
|
await this.stateService.setDirectory(DirectoryType.EntraID, this.entra);
|
||||||
await this.stateService.setDirectory(DirectoryType.Okta, this.okta);
|
await this.stateService.setDirectory(DirectoryType.Okta, this.okta);
|
||||||
await this.stateService.setDirectory(DirectoryType.OneLogin, this.oneLogin);
|
await this.stateService.setDirectory(DirectoryType.OneLogin, this.oneLogin);
|
||||||
await this.stateService.setSync(this.sync);
|
await this.stateService.setSync(this.sync);
|
||||||
@@ -135,8 +134,8 @@ export class SettingsComponent implements OnInit, OnDestroy {
|
|||||||
document.getElementById("password").focus();
|
document.getElementById("password").focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleAzureKey() {
|
toggleEntraKey() {
|
||||||
this.showAzureKey = !this.showAzureKey;
|
this.showEntraKey = !this.showEntraKey;
|
||||||
document.getElementById("secretKey").focus();
|
document.getElementById("secretKey").focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { MessageResponse } from "@/jslib/node/src/cli/models/response/messageRes
|
|||||||
|
|
||||||
import { StateService } from "../abstractions/state.service";
|
import { StateService } from "../abstractions/state.service";
|
||||||
import { DirectoryType } from "../enums/directoryType";
|
import { DirectoryType } from "../enums/directoryType";
|
||||||
import { AzureConfiguration } from "../models/azureConfiguration";
|
import { EntraIdConfiguration } from "../models/entraIdConfiguration";
|
||||||
import { GSuiteConfiguration } from "../models/gsuiteConfiguration";
|
import { GSuiteConfiguration } from "../models/gsuiteConfiguration";
|
||||||
import { LdapConfiguration } from "../models/ldapConfiguration";
|
import { LdapConfiguration } from "../models/ldapConfiguration";
|
||||||
import { OktaConfiguration } from "../models/oktaConfiguration";
|
import { OktaConfiguration } from "../models/oktaConfiguration";
|
||||||
@@ -20,7 +20,7 @@ export class ConfigCommand {
|
|||||||
private directory: DirectoryType;
|
private directory: DirectoryType;
|
||||||
private ldap = new LdapConfiguration();
|
private ldap = new LdapConfiguration();
|
||||||
private gsuite = new GSuiteConfiguration();
|
private gsuite = new GSuiteConfiguration();
|
||||||
private azure = new AzureConfiguration();
|
private entra = new EntraIdConfiguration();
|
||||||
private okta = new OktaConfiguration();
|
private okta = new OktaConfiguration();
|
||||||
private oneLogin = new OneLoginConfiguration();
|
private oneLogin = new OneLoginConfiguration();
|
||||||
private sync = new SyncConfiguration();
|
private sync = new SyncConfiguration();
|
||||||
@@ -54,8 +54,11 @@ export class ConfigCommand {
|
|||||||
case "gsuite.key":
|
case "gsuite.key":
|
||||||
await this.setGSuiteKey(value);
|
await this.setGSuiteKey(value);
|
||||||
break;
|
break;
|
||||||
|
// Azure Active Directory was renamed to Entra ID, but we've kept the old key name
|
||||||
|
// to be backwards compatible with existing configurations.
|
||||||
case "azure.key":
|
case "azure.key":
|
||||||
await this.setAzureKey(value);
|
case "entra.key":
|
||||||
|
await this.setEntraIdKey(value);
|
||||||
break;
|
break;
|
||||||
case "okta.token":
|
case "okta.token":
|
||||||
await this.setOktaToken(value);
|
await this.setOktaToken(value);
|
||||||
@@ -102,9 +105,9 @@ export class ConfigCommand {
|
|||||||
await this.saveConfig();
|
await this.saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async setAzureKey(key: string) {
|
private async setEntraIdKey(key: string) {
|
||||||
await this.loadConfig();
|
await this.loadConfig();
|
||||||
this.azure.key = key;
|
this.entra.key = key;
|
||||||
await this.saveConfig();
|
await this.saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,10 +130,9 @@ export class ConfigCommand {
|
|||||||
this.gsuite =
|
this.gsuite =
|
||||||
(await this.stateService.getDirectory<GSuiteConfiguration>(DirectoryType.GSuite)) ||
|
(await this.stateService.getDirectory<GSuiteConfiguration>(DirectoryType.GSuite)) ||
|
||||||
this.gsuite;
|
this.gsuite;
|
||||||
this.azure =
|
this.entra =
|
||||||
(await this.stateService.getDirectory<AzureConfiguration>(
|
(await this.stateService.getDirectory<EntraIdConfiguration>(DirectoryType.EntraID)) ||
|
||||||
DirectoryType.AzureActiveDirectory,
|
this.entra;
|
||||||
)) || this.azure;
|
|
||||||
this.okta =
|
this.okta =
|
||||||
(await this.stateService.getDirectory<OktaConfiguration>(DirectoryType.Okta)) || this.okta;
|
(await this.stateService.getDirectory<OktaConfiguration>(DirectoryType.Okta)) || this.okta;
|
||||||
this.oneLogin =
|
this.oneLogin =
|
||||||
@@ -144,7 +146,7 @@ export class ConfigCommand {
|
|||||||
await this.stateService.setDirectoryType(this.directory);
|
await this.stateService.setDirectoryType(this.directory);
|
||||||
await this.stateService.setDirectory(DirectoryType.Ldap, this.ldap);
|
await this.stateService.setDirectory(DirectoryType.Ldap, this.ldap);
|
||||||
await this.stateService.setDirectory(DirectoryType.GSuite, this.gsuite);
|
await this.stateService.setDirectory(DirectoryType.GSuite, this.gsuite);
|
||||||
await this.stateService.setDirectory(DirectoryType.AzureActiveDirectory, this.azure);
|
await this.stateService.setDirectory(DirectoryType.EntraID, this.entra);
|
||||||
await this.stateService.setDirectory(DirectoryType.Okta, this.okta);
|
await this.stateService.setDirectory(DirectoryType.Okta, this.okta);
|
||||||
await this.stateService.setDirectory(DirectoryType.OneLogin, this.oneLogin);
|
await this.stateService.setDirectory(DirectoryType.OneLogin, this.oneLogin);
|
||||||
await this.stateService.setSync(this.sync);
|
await this.stateService.setSync(this.sync);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
export enum DirectoryType {
|
export enum DirectoryType {
|
||||||
Ldap = 0,
|
Ldap = 0,
|
||||||
AzureActiveDirectory = 1,
|
EntraID = 1,
|
||||||
GSuite = 2,
|
GSuite = 2,
|
||||||
Okta = 3,
|
Okta = 3,
|
||||||
OneLogin = 4,
|
OneLogin = 4,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Account as BaseAccount } from "@/jslib/common/src/models/domain/account
|
|||||||
|
|
||||||
import { DirectoryType } from "@/src/enums/directoryType";
|
import { DirectoryType } from "@/src/enums/directoryType";
|
||||||
|
|
||||||
import { AzureConfiguration } from "./azureConfiguration";
|
import { EntraIdConfiguration } from "./entraIdConfiguration";
|
||||||
import { GSuiteConfiguration } from "./gsuiteConfiguration";
|
import { GSuiteConfiguration } from "./gsuiteConfiguration";
|
||||||
import { LdapConfiguration } from "./ldapConfiguration";
|
import { LdapConfiguration } from "./ldapConfiguration";
|
||||||
import { OktaConfiguration } from "./oktaConfiguration";
|
import { OktaConfiguration } from "./oktaConfiguration";
|
||||||
@@ -29,7 +29,10 @@ export class ClientKeys {
|
|||||||
export class DirectoryConfigurations {
|
export class DirectoryConfigurations {
|
||||||
ldap: LdapConfiguration;
|
ldap: LdapConfiguration;
|
||||||
gsuite: GSuiteConfiguration;
|
gsuite: GSuiteConfiguration;
|
||||||
azure: AzureConfiguration;
|
entra: EntraIdConfiguration;
|
||||||
|
// Azure Active Directory was renamed to Entra ID, but we've kept the old account property name
|
||||||
|
// to be backwards compatible with existing configurations.
|
||||||
|
azure: EntraIdConfiguration;
|
||||||
okta: OktaConfiguration;
|
okta: OktaConfiguration;
|
||||||
oneLogin: OneLoginConfiguration;
|
oneLogin: OneLoginConfiguration;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { IConfiguration } from "./IConfiguration";
|
import { IConfiguration } from "./IConfiguration";
|
||||||
|
|
||||||
export class AzureConfiguration implements IConfiguration {
|
export class EntraIdConfiguration implements IConfiguration {
|
||||||
identityAuthority: string;
|
identityAuthority: string;
|
||||||
tenant: string;
|
tenant: string;
|
||||||
applicationId: string;
|
applicationId: string;
|
||||||
@@ -190,7 +190,7 @@ export class Program extends BaseProgram {
|
|||||||
writeLn(" server - On-premise hosted installation URL.");
|
writeLn(" server - On-premise hosted installation URL.");
|
||||||
writeLn(" directory - The type of directory to use.");
|
writeLn(" directory - The type of directory to use.");
|
||||||
writeLn(" ldap.password - The password for connection to this LDAP server.");
|
writeLn(" ldap.password - The password for connection to this LDAP server.");
|
||||||
writeLn(" azure.key - The Azure AD secret key.");
|
writeLn(" entra.key - The Entra Id secret key.");
|
||||||
writeLn(" gsuite.key - The G Suite private key.");
|
writeLn(" gsuite.key - The G Suite private key.");
|
||||||
writeLn(" okta.token - The Okta token.");
|
writeLn(" okta.token - The Okta token.");
|
||||||
writeLn(" onelogin.secret - The OneLogin client secret.");
|
writeLn(" onelogin.secret - The OneLogin client secret.");
|
||||||
@@ -202,7 +202,7 @@ export class Program extends BaseProgram {
|
|||||||
writeLn(" bwdc config directory 1");
|
writeLn(" bwdc config directory 1");
|
||||||
writeLn(" bwdc config ldap.password <password>");
|
writeLn(" bwdc config ldap.password <password>");
|
||||||
writeLn(" bwdc config ldap.password --secretenv LDAP_PWD");
|
writeLn(" bwdc config ldap.password --secretenv LDAP_PWD");
|
||||||
writeLn(" bwdc config azure.key <key>");
|
writeLn(" bwdc config entra.key <key>");
|
||||||
writeLn(" bwdc config gsuite.key <key>");
|
writeLn(" bwdc config gsuite.key <key>");
|
||||||
writeLn(" bwdc config okta.token <token>");
|
writeLn(" bwdc config okta.token <token>");
|
||||||
writeLn(" bwdc config onelogin.secret <secret>");
|
writeLn(" bwdc config onelogin.secret <secret>");
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { DirectoryFactoryService } from "../abstractions/directory-factory.servi
|
|||||||
import { StateService } from "../abstractions/state.service";
|
import { StateService } from "../abstractions/state.service";
|
||||||
import { DirectoryType } from "../enums/directoryType";
|
import { DirectoryType } from "../enums/directoryType";
|
||||||
|
|
||||||
import { AzureDirectoryService } from "./azure-directory.service";
|
import { EntraIdDirectoryService } from "./entra-id-directory.service";
|
||||||
import { GSuiteDirectoryService } from "./gsuite-directory.service";
|
import { GSuiteDirectoryService } from "./gsuite-directory.service";
|
||||||
import { LdapDirectoryService } from "./ldap-directory.service";
|
import { LdapDirectoryService } from "./ldap-directory.service";
|
||||||
import { OktaDirectoryService } from "./okta-directory.service";
|
import { OktaDirectoryService } from "./okta-directory.service";
|
||||||
@@ -22,8 +22,8 @@ export class DefaultDirectoryFactoryService implements DirectoryFactoryService {
|
|||||||
switch (directoryType) {
|
switch (directoryType) {
|
||||||
case DirectoryType.GSuite:
|
case DirectoryType.GSuite:
|
||||||
return new GSuiteDirectoryService(this.logService, this.i18nService, this.stateService);
|
return new GSuiteDirectoryService(this.logService, this.i18nService, this.stateService);
|
||||||
case DirectoryType.AzureActiveDirectory:
|
case DirectoryType.EntraID:
|
||||||
return new AzureDirectoryService(this.logService, this.i18nService, this.stateService);
|
return new EntraIdDirectoryService(this.logService, this.i18nService, this.stateService);
|
||||||
case DirectoryType.Ldap:
|
case DirectoryType.Ldap:
|
||||||
return new LdapDirectoryService(this.logService, this.i18nService, this.stateService);
|
return new LdapDirectoryService(this.logService, this.i18nService, this.stateService);
|
||||||
case DirectoryType.Okta:
|
case DirectoryType.Okta:
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { LogService } from "@/jslib/common/src/abstractions/log.service";
|
|||||||
|
|
||||||
import { StateService } from "../abstractions/state.service";
|
import { StateService } from "../abstractions/state.service";
|
||||||
import { DirectoryType } from "../enums/directoryType";
|
import { DirectoryType } from "../enums/directoryType";
|
||||||
import { AzureConfiguration } from "../models/azureConfiguration";
|
import { EntraIdConfiguration } from "../models/entraIdConfiguration";
|
||||||
import { GroupEntry } from "../models/groupEntry";
|
import { GroupEntry } from "../models/groupEntry";
|
||||||
import { SyncConfiguration } from "../models/syncConfiguration";
|
import { SyncConfiguration } from "../models/syncConfiguration";
|
||||||
import { UserEntry } from "../models/userEntry";
|
import { UserEntry } from "../models/userEntry";
|
||||||
@@ -17,8 +17,10 @@ import { UserEntry } from "../models/userEntry";
|
|||||||
import { BaseDirectoryService } from "./baseDirectory.service";
|
import { BaseDirectoryService } from "./baseDirectory.service";
|
||||||
import { IDirectoryService } from "./directory.service";
|
import { IDirectoryService } from "./directory.service";
|
||||||
|
|
||||||
const AzurePublicIdentityAuhtority = "login.microsoftonline.com";
|
const EntraIdPublicIdentityAuthority = "login.microsoftonline.com";
|
||||||
const AzureGovermentIdentityAuhtority = "login.microsoftonline.us";
|
const EntraIdPublicGraphEndpoint = "https://graph.microsoft.com";
|
||||||
|
const EntraIdGovernmentIdentityAuthority = "login.microsoftonline.us";
|
||||||
|
const EntraIdGovernmentGraphEndpoint = "https://graph.microsoft.us";
|
||||||
|
|
||||||
const NextLink = "@odata.nextLink";
|
const NextLink = "@odata.nextLink";
|
||||||
const DeltaLink = "@odata.deltaLink";
|
const DeltaLink = "@odata.deltaLink";
|
||||||
@@ -32,9 +34,9 @@ enum UserSetType {
|
|||||||
ExcludeGroup,
|
ExcludeGroup,
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AzureDirectoryService extends BaseDirectoryService implements IDirectoryService {
|
export class EntraIdDirectoryService extends BaseDirectoryService implements IDirectoryService {
|
||||||
private client: graph.Client;
|
private client: graph.Client;
|
||||||
private dirConfig: AzureConfiguration;
|
private dirConfig: EntraIdConfiguration;
|
||||||
private syncConfig: SyncConfiguration;
|
private syncConfig: SyncConfiguration;
|
||||||
private accessToken: string;
|
private accessToken: string;
|
||||||
private accessTokenExpiration: Date;
|
private accessTokenExpiration: Date;
|
||||||
@@ -50,12 +52,12 @@ export class AzureDirectoryService extends BaseDirectoryService implements IDire
|
|||||||
|
|
||||||
async getEntries(force: boolean, test: boolean): Promise<[GroupEntry[], UserEntry[]]> {
|
async getEntries(force: boolean, test: boolean): Promise<[GroupEntry[], UserEntry[]]> {
|
||||||
const type = await this.stateService.getDirectoryType();
|
const type = await this.stateService.getDirectoryType();
|
||||||
if (type !== DirectoryType.AzureActiveDirectory) {
|
if (type !== DirectoryType.EntraID) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dirConfig = await this.stateService.getDirectory<AzureConfiguration>(
|
this.dirConfig = await this.stateService.getDirectory<EntraIdConfiguration>(
|
||||||
DirectoryType.AzureActiveDirectory,
|
DirectoryType.EntraID,
|
||||||
);
|
);
|
||||||
if (this.dirConfig == null) {
|
if (this.dirConfig == null) {
|
||||||
return;
|
return;
|
||||||
@@ -207,7 +209,7 @@ export class AzureDirectoryService extends BaseDirectoryService implements IDire
|
|||||||
if (keyword === "excludeadministrativeunit" || keyword === "includeadministrativeunit") {
|
if (keyword === "excludeadministrativeunit" || keyword === "includeadministrativeunit") {
|
||||||
for (const p of pieces) {
|
for (const p of pieces) {
|
||||||
let auMembers = await this.client
|
let auMembers = await this.client
|
||||||
.api(`https://graph.microsoft.com/v1.0/directory/administrativeUnits/${p}/members`)
|
.api(`${this.getGraphApiEndpoint()}/v1.0/directory/administrativeUnits/${p}/members`)
|
||||||
.get();
|
.get();
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -457,10 +459,10 @@ export class AzureDirectoryService extends BaseDirectoryService implements IDire
|
|||||||
const identityAuthority =
|
const identityAuthority =
|
||||||
this.dirConfig.identityAuthority != null
|
this.dirConfig.identityAuthority != null
|
||||||
? this.dirConfig.identityAuthority
|
? this.dirConfig.identityAuthority
|
||||||
: AzurePublicIdentityAuhtority;
|
: EntraIdPublicIdentityAuthority;
|
||||||
if (
|
if (
|
||||||
identityAuthority !== AzurePublicIdentityAuhtority &&
|
identityAuthority !== EntraIdPublicIdentityAuthority &&
|
||||||
identityAuthority !== AzureGovermentIdentityAuhtority
|
identityAuthority !== EntraIdGovernmentIdentityAuthority
|
||||||
) {
|
) {
|
||||||
done(new Error(this.i18nService.t("dirConfigIncomplete")), null);
|
done(new Error(this.i18nService.t("dirConfigIncomplete")), null);
|
||||||
return;
|
return;
|
||||||
@@ -478,7 +480,7 @@ export class AzureDirectoryService extends BaseDirectoryService implements IDire
|
|||||||
client_id: this.dirConfig.applicationId,
|
client_id: this.dirConfig.applicationId,
|
||||||
client_secret: this.dirConfig.key,
|
client_secret: this.dirConfig.key,
|
||||||
grant_type: "client_credentials",
|
grant_type: "client_credentials",
|
||||||
scope: "https://graph.microsoft.com/.default",
|
scope: `${this.getGraphApiEndpoint()}/.default`,
|
||||||
});
|
});
|
||||||
|
|
||||||
const req = https
|
const req = https
|
||||||
@@ -542,4 +544,10 @@ export class AzureDirectoryService extends BaseDirectoryService implements IDire
|
|||||||
exp.setSeconds(exp.getSeconds() + expSeconds);
|
exp.setSeconds(exp.getSeconds() + expSeconds);
|
||||||
this.accessTokenExpiration = exp;
|
this.accessTokenExpiration = exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getGraphApiEndpoint(): string {
|
||||||
|
return this.dirConfig.identityAuthority === EntraIdGovernmentIdentityAuthority
|
||||||
|
? EntraIdGovernmentGraphEndpoint
|
||||||
|
: EntraIdPublicGraphEndpoint;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,7 @@ import { StateService as StateServiceAbstraction } from "@/src/abstractions/stat
|
|||||||
import { DirectoryType } from "@/src/enums/directoryType";
|
import { DirectoryType } from "@/src/enums/directoryType";
|
||||||
import { IConfiguration } from "@/src/models/IConfiguration";
|
import { IConfiguration } from "@/src/models/IConfiguration";
|
||||||
import { Account } from "@/src/models/account";
|
import { Account } from "@/src/models/account";
|
||||||
import { AzureConfiguration } from "@/src/models/azureConfiguration";
|
import { EntraIdConfiguration } from "@/src/models/entraIdConfiguration";
|
||||||
import { GSuiteConfiguration } from "@/src/models/gsuiteConfiguration";
|
import { GSuiteConfiguration } from "@/src/models/gsuiteConfiguration";
|
||||||
import { LdapConfiguration } from "@/src/models/ldapConfiguration";
|
import { LdapConfiguration } from "@/src/models/ldapConfiguration";
|
||||||
import { OktaConfiguration } from "@/src/models/oktaConfiguration";
|
import { OktaConfiguration } from "@/src/models/oktaConfiguration";
|
||||||
@@ -21,7 +21,10 @@ import { SyncConfiguration } from "@/src/models/syncConfiguration";
|
|||||||
const SecureStorageKeys = {
|
const SecureStorageKeys = {
|
||||||
ldap: "ldapPassword",
|
ldap: "ldapPassword",
|
||||||
gsuite: "gsuitePrivateKey",
|
gsuite: "gsuitePrivateKey",
|
||||||
|
// Azure Active Directory was renamed to Entra ID, but we've kept the old property name
|
||||||
|
// to be backwards compatible with existing configurations.
|
||||||
azure: "azureKey",
|
azure: "azureKey",
|
||||||
|
entra: "entraKey",
|
||||||
okta: "oktaToken",
|
okta: "oktaToken",
|
||||||
oneLogin: "oneLoginClientSecret",
|
oneLogin: "oneLoginClientSecret",
|
||||||
userDelta: "userDeltaToken",
|
userDelta: "userDeltaToken",
|
||||||
@@ -68,8 +71,8 @@ export class StateService
|
|||||||
case DirectoryType.Ldap:
|
case DirectoryType.Ldap:
|
||||||
(configWithSecrets as any).password = await this.getLdapKey();
|
(configWithSecrets as any).password = await this.getLdapKey();
|
||||||
break;
|
break;
|
||||||
case DirectoryType.AzureActiveDirectory:
|
case DirectoryType.EntraID:
|
||||||
(configWithSecrets as any).key = await this.getAzureKey();
|
(configWithSecrets as any).key = await this.getEntraKey();
|
||||||
break;
|
break;
|
||||||
case DirectoryType.Okta:
|
case DirectoryType.Okta:
|
||||||
(configWithSecrets as any).token = await this.getOktaKey();
|
(configWithSecrets as any).token = await this.getOktaKey();
|
||||||
@@ -93,7 +96,7 @@ export class StateService
|
|||||||
config:
|
config:
|
||||||
| LdapConfiguration
|
| LdapConfiguration
|
||||||
| GSuiteConfiguration
|
| GSuiteConfiguration
|
||||||
| AzureConfiguration
|
| EntraIdConfiguration
|
||||||
| OktaConfiguration
|
| OktaConfiguration
|
||||||
| OneLoginConfiguration,
|
| OneLoginConfiguration,
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
@@ -106,11 +109,11 @@ export class StateService
|
|||||||
await this.setLdapConfiguration(ldapConfig);
|
await this.setLdapConfiguration(ldapConfig);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DirectoryType.AzureActiveDirectory: {
|
case DirectoryType.EntraID: {
|
||||||
const azureConfig = config as AzureConfiguration;
|
const entraConfig = config as EntraIdConfiguration;
|
||||||
await this.setAzureKey(azureConfig.key);
|
await this.setEntraKey(entraConfig.key);
|
||||||
azureConfig.key = StoredSecurely;
|
entraConfig.key = StoredSecurely;
|
||||||
await this.setAzureConfiguration(azureConfig);
|
await this.setEntraConfiguration(entraConfig);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DirectoryType.Okta: {
|
case DirectoryType.Okta: {
|
||||||
@@ -187,23 +190,32 @@ export class StateService
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getAzureKey(options?: StorageOptions): Promise<string> {
|
private async getEntraKey(options?: StorageOptions): Promise<string> {
|
||||||
options = this.reconcileOptions(options, await this.defaultSecureStorageOptions());
|
options = this.reconcileOptions(options, await this.defaultSecureStorageOptions());
|
||||||
if (options?.userId == null) {
|
if (options?.userId == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const entraKey = await this.secureStorageService.get<string>(
|
||||||
|
`${options.userId}_${SecureStorageKeys.entra}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (entraKey != null) {
|
||||||
|
return entraKey;
|
||||||
|
}
|
||||||
|
|
||||||
return await this.secureStorageService.get<string>(
|
return await this.secureStorageService.get<string>(
|
||||||
`${options.userId}_${SecureStorageKeys.azure}`,
|
`${options.userId}_${SecureStorageKeys.azure}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async setAzureKey(value: string, options?: StorageOptions): Promise<void> {
|
private async setEntraKey(value: string, options?: StorageOptions): Promise<void> {
|
||||||
options = this.reconcileOptions(options, await this.defaultSecureStorageOptions());
|
options = this.reconcileOptions(options, await this.defaultSecureStorageOptions());
|
||||||
if (options?.userId == null) {
|
if (options?.userId == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await this.secureStorageService.save(
|
await this.secureStorageService.save(
|
||||||
`${options.userId}_${SecureStorageKeys.azure}`,
|
`${options.userId}_${SecureStorageKeys.entra}`,
|
||||||
value,
|
value,
|
||||||
options,
|
options,
|
||||||
);
|
);
|
||||||
@@ -259,8 +271,8 @@ export class StateService
|
|||||||
return await this.getLdapConfiguration();
|
return await this.getLdapConfiguration();
|
||||||
case DirectoryType.GSuite:
|
case DirectoryType.GSuite:
|
||||||
return await this.getGsuiteConfiguration();
|
return await this.getGsuiteConfiguration();
|
||||||
case DirectoryType.AzureActiveDirectory:
|
case DirectoryType.EntraID:
|
||||||
return await this.getAzureConfiguration();
|
return await this.getEntraConfiguration();
|
||||||
case DirectoryType.Okta:
|
case DirectoryType.Okta:
|
||||||
return await this.getOktaConfiguration();
|
return await this.getOktaConfiguration();
|
||||||
case DirectoryType.OneLogin:
|
case DirectoryType.OneLogin:
|
||||||
@@ -305,17 +317,28 @@ export class StateService
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAzureConfiguration(options?: StorageOptions): Promise<AzureConfiguration> {
|
async getEntraConfiguration(options?: StorageOptions): Promise<EntraIdConfiguration> {
|
||||||
|
const entraConfig = (
|
||||||
|
await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()))
|
||||||
|
)?.directoryConfigurations?.entra;
|
||||||
|
|
||||||
|
if (entraConfig != null) {
|
||||||
|
return entraConfig;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()))
|
await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()))
|
||||||
)?.directoryConfigurations?.azure;
|
)?.directoryConfigurations?.azure;
|
||||||
}
|
}
|
||||||
|
|
||||||
async setAzureConfiguration(value: AzureConfiguration, options?: StorageOptions): Promise<void> {
|
async setEntraConfiguration(
|
||||||
|
value: EntraIdConfiguration,
|
||||||
|
options?: StorageOptions,
|
||||||
|
): Promise<void> {
|
||||||
const account = await this.getAccount(
|
const account = await this.getAccount(
|
||||||
this.reconcileOptions(options, await this.defaultOnDiskOptions()),
|
this.reconcileOptions(options, await this.defaultOnDiskOptions()),
|
||||||
);
|
);
|
||||||
account.directoryConfigurations.azure = value;
|
account.directoryConfigurations.entra = value;
|
||||||
await this.saveAccount(
|
await this.saveAccount(
|
||||||
account,
|
account,
|
||||||
this.reconcileOptions(options, await this.defaultOnDiskOptions()),
|
this.reconcileOptions(options, await this.defaultOnDiskOptions()),
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { StateMigrationService as BaseStateMigrationService } from "@/jslib/comm
|
|||||||
|
|
||||||
import { DirectoryType } from "@/src/enums/directoryType";
|
import { DirectoryType } from "@/src/enums/directoryType";
|
||||||
import { Account, DirectoryConfigurations, DirectorySettings } from "@/src/models/account";
|
import { Account, DirectoryConfigurations, DirectorySettings } from "@/src/models/account";
|
||||||
import { AzureConfiguration } from "@/src/models/azureConfiguration";
|
import { EntraIdConfiguration } from "@/src/models/entraIdConfiguration";
|
||||||
import { GSuiteConfiguration } from "@/src/models/gsuiteConfiguration";
|
import { GSuiteConfiguration } from "@/src/models/gsuiteConfiguration";
|
||||||
import { LdapConfiguration } from "@/src/models/ldapConfiguration";
|
import { LdapConfiguration } from "@/src/models/ldapConfiguration";
|
||||||
import { OktaConfiguration } from "@/src/models/oktaConfiguration";
|
import { OktaConfiguration } from "@/src/models/oktaConfiguration";
|
||||||
@@ -14,6 +14,7 @@ const SecureStorageKeys: { [key: string]: any } = {
|
|||||||
ldap: "ldapPassword",
|
ldap: "ldapPassword",
|
||||||
gsuite: "gsuitePrivateKey",
|
gsuite: "gsuitePrivateKey",
|
||||||
azure: "azureKey",
|
azure: "azureKey",
|
||||||
|
entra: "entraIdKey",
|
||||||
okta: "oktaToken",
|
okta: "oktaToken",
|
||||||
oneLogin: "oneLoginClientSecret",
|
oneLogin: "oneLoginClientSecret",
|
||||||
directoryConfigPrefix: "directoryConfig_",
|
directoryConfigPrefix: "directoryConfig_",
|
||||||
@@ -104,13 +105,16 @@ export class StateMigrationService extends BaseStateMigrationService {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initilize typed objects from key/value pairs in storage to either be saved temporarily until an account is authed or applied to the active account
|
// Initialize typed objects from key/value pairs in storage to either be saved temporarily until an account is authed or applied to the active account
|
||||||
const getDirectoryConfig = async <T>(type: DirectoryType) =>
|
const getDirectoryConfig = async <T>(type: DirectoryType) =>
|
||||||
await this.get<T>(SecureStorageKeys.directoryConfigPrefix + type);
|
await this.get<T>(SecureStorageKeys.directoryConfigPrefix + type);
|
||||||
const directoryConfigs: DirectoryConfigurations = {
|
const directoryConfigs: DirectoryConfigurations = {
|
||||||
ldap: await getDirectoryConfig<LdapConfiguration>(DirectoryType.Ldap),
|
ldap: await getDirectoryConfig<LdapConfiguration>(DirectoryType.Ldap),
|
||||||
gsuite: await getDirectoryConfig<GSuiteConfiguration>(DirectoryType.GSuite),
|
gsuite: await getDirectoryConfig<GSuiteConfiguration>(DirectoryType.GSuite),
|
||||||
azure: await getDirectoryConfig<AzureConfiguration>(DirectoryType.AzureActiveDirectory),
|
// Azure Active Directory was renamed to Entra ID, but we've kept the old property name
|
||||||
|
// to be backwards compatible with existing configurations.
|
||||||
|
azure: await getDirectoryConfig<EntraIdConfiguration>(DirectoryType.EntraID),
|
||||||
|
entra: await getDirectoryConfig<EntraIdConfiguration>(DirectoryType.EntraID),
|
||||||
okta: await getDirectoryConfig<OktaConfiguration>(DirectoryType.Okta),
|
okta: await getDirectoryConfig<OktaConfiguration>(DirectoryType.Okta),
|
||||||
oneLogin: await getDirectoryConfig<OneLoginConfiguration>(DirectoryType.OneLogin),
|
oneLogin: await getDirectoryConfig<OneLoginConfiguration>(DirectoryType.OneLogin),
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user