mirror of
https://github.com/bitwarden/browser.git
synced 2025-01-22 21:21:35 +01:00
Merge branch 'main' into autofill/pm-5189-fix-issues-present-with-inline-menu-rendering-in-iframes
This commit is contained in:
commit
6112d989ce
9
.github/workflows/release-desktop-beta.yml
vendored
9
.github/workflows/release-desktop-beta.yml
vendored
@ -415,6 +415,9 @@ jobs:
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
node-version: ${{ env._NODE_VERSION }}
|
||||
|
||||
- name: Set up Node-gyp
|
||||
run: python3 -m pip install setuptools
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
node --version
|
||||
@ -546,6 +549,9 @@ jobs:
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
node-version: ${{ env._NODE_VERSION }}
|
||||
|
||||
- name: Set up Node-gyp
|
||||
run: python3 -m pip install setuptools
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
node --version
|
||||
@ -756,6 +762,9 @@ jobs:
|
||||
cache-dependency-path: '**/package-lock.json'
|
||||
node-version: ${{ env._NODE_VERSION }}
|
||||
|
||||
- name: Set up Node-gyp
|
||||
run: python3 -m pip install setuptools
|
||||
|
||||
- name: Print environment
|
||||
run: |
|
||||
node --version
|
||||
|
@ -58,7 +58,7 @@
|
||||
"dependencies": {
|
||||
"@koa/multer": "3.0.2",
|
||||
"@koa/router": "12.0.1",
|
||||
"argon2": "0.31.0",
|
||||
"argon2": "0.40.1",
|
||||
"big-integer": "1.6.51",
|
||||
"browser-hrtime": "1.1.8",
|
||||
"chalk": "4.1.2",
|
||||
@ -80,7 +80,7 @@
|
||||
"papaparse": "5.4.1",
|
||||
"proper-lockfile": "4.1.2",
|
||||
"rxjs": "7.8.1",
|
||||
"tldts": "6.1.25",
|
||||
"tldts": "6.1.29",
|
||||
"zxcvbn": "4.4.2"
|
||||
}
|
||||
}
|
||||
|
@ -20,9 +20,9 @@
|
||||
"**/node_modules/@bitwarden/desktop-native/desktop_native.${platform}-${arch}*.node",
|
||||
|
||||
"!**/node_modules/argon2/**/*",
|
||||
"**/node_modules/argon2/argon2.js",
|
||||
"**/node_modules/argon2/argon2.cjs",
|
||||
"**/node_modules/argon2/package.json",
|
||||
"**/node_modules/argon2/lib/binding/napi-v3/argon2.node"
|
||||
"**/node_modules/argon2/build/Release/argon2.node"
|
||||
],
|
||||
"electronVersion": "30.1.2",
|
||||
"generateUpdatesFilesForAllChannels": true,
|
||||
|
576
apps/desktop/src/package-lock.json
generated
576
apps/desktop/src/package-lock.json
generated
@ -10,10 +10,11 @@
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@bitwarden/desktop-native": "file:../desktop_native",
|
||||
"argon2": "0.31.0"
|
||||
"argon2": "0.40.1"
|
||||
}
|
||||
},
|
||||
"../desktop_native": {
|
||||
"name": "@bitwarden/desktop-native",
|
||||
"version": "0.1.0",
|
||||
"license": "GPL-3.0",
|
||||
"devDependencies": {
|
||||
@ -24,25 +25,6 @@
|
||||
"resolved": "../desktop_native",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@mapbox/node-pre-gyp": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
|
||||
"integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==",
|
||||
"dependencies": {
|
||||
"detect-libc": "^2.0.0",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"make-dir": "^3.1.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"nopt": "^5.0.0",
|
||||
"npmlog": "^5.0.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"semver": "^7.3.5",
|
||||
"tar": "^6.1.11"
|
||||
},
|
||||
"bin": {
|
||||
"node-pre-gyp": "bin/node-pre-gyp"
|
||||
}
|
||||
},
|
||||
"node_modules/@phc/format": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@phc/format/-/format-1.0.0.tgz",
|
||||
@ -51,330 +33,20 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
||||
"dependencies": {
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/aproba": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
|
||||
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
|
||||
},
|
||||
"node_modules/are-we-there-yet": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
|
||||
"integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
|
||||
"dependencies": {
|
||||
"delegates": "^1.0.0",
|
||||
"readable-stream": "^3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/argon2": {
|
||||
"version": "0.31.0",
|
||||
"resolved": "https://registry.npmjs.org/argon2/-/argon2-0.31.0.tgz",
|
||||
"integrity": "sha512-r56NWwlE3tjD/FIqL1T+V4Ka+Mb5yMF35w1YWHpwpEjeONXBUbxmjhWkWqY63mse8lpcZ+ZZIGpKL+s+qXhyfg==",
|
||||
"version": "0.40.1",
|
||||
"resolved": "https://registry.npmjs.org/argon2/-/argon2-0.40.1.tgz",
|
||||
"integrity": "sha512-DjtHDwd7pm12qeWyfihHoM8Bn5vGcgH6sKwgPqwNYroRmxlrzadHEvMyuvQxN/V8YSyRRKD5x6ito09q1e9OyA==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@mapbox/node-pre-gyp": "^1.0.11",
|
||||
"@phc/format": "^1.0.0",
|
||||
"node-addon-api": "^7.0.0"
|
||||
"node-addon-api": "^7.1.0",
|
||||
"node-gyp-build": "^4.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
"node": ">=16.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/chownr": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
|
||||
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/color-support": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
|
||||
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
|
||||
"bin": {
|
||||
"color-support": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"node_modules/console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"dependencies": {
|
||||
"ms": "2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/delegates": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
"integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
|
||||
},
|
||||
"node_modules/detect-libc": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
|
||||
"integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"node_modules/fs-minipass": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
|
||||
"dependencies": {
|
||||
"minipass": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-minipass/node_modules/minipass": {
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
|
||||
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||
},
|
||||
"node_modules/gauge": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
|
||||
"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
|
||||
"dependencies": {
|
||||
"aproba": "^1.0.3 || ^2.0.0",
|
||||
"color-support": "^1.1.2",
|
||||
"console-control-strings": "^1.0.0",
|
||||
"has-unicode": "^2.0.1",
|
||||
"object-assign": "^4.1.1",
|
||||
"signal-exit": "^3.0.0",
|
||||
"string-width": "^4.2.3",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wide-align": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
|
||||
},
|
||||
"node_modules/https-proxy-agent": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
||||
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
|
||||
"dependencies": {
|
||||
"agent-base": "6",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/make-dir": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
|
||||
"dependencies": {
|
||||
"semver": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/make-dir/node_modules/semver": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/minipass": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
|
||||
"integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/minizlib": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
|
||||
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
|
||||
"dependencies": {
|
||||
"minipass": "^3.0.0",
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/minizlib/node_modules/minipass": {
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
|
||||
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"node_modules/node-addon-api": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.0.tgz",
|
||||
@ -383,233 +55,15 @@
|
||||
"node": "^16 || ^18 || >= 20"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/nopt": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
|
||||
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
|
||||
"dependencies": {
|
||||
"abbrev": "1"
|
||||
},
|
||||
"node_modules/node-gyp-build": {
|
||||
"version": "4.8.0",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz",
|
||||
"integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==",
|
||||
"bin": {
|
||||
"nopt": "bin/nopt.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
"node-gyp-build": "bin.js",
|
||||
"node-gyp-build-optional": "optional.js",
|
||||
"node-gyp-build-test": "build-test.js"
|
||||
}
|
||||
},
|
||||
"node_modules/npmlog": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
|
||||
"integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
|
||||
"dependencies": {
|
||||
"are-we-there-yet": "^2.0.0",
|
||||
"console-control-strings": "^1.1.0",
|
||||
"gauge": "^3.0.0",
|
||||
"set-blocking": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/rimraf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
||||
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
|
||||
},
|
||||
"node_modules/signal-exit": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/tar": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
|
||||
"integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
|
||||
"dependencies": {
|
||||
"chownr": "^2.0.0",
|
||||
"fs-minipass": "^2.0.0",
|
||||
"minipass": "^5.0.0",
|
||||
"minizlib": "^2.1.1",
|
||||
"mkdirp": "^1.0.3",
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wide-align": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
|
||||
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
|
||||
"dependencies": {
|
||||
"string-width": "^1.0.2 || 2 || 3 || 4"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@bitwarden/desktop-native": "file:../desktop_native",
|
||||
"argon2": "0.31.0"
|
||||
"argon2": "0.40.1"
|
||||
}
|
||||
}
|
||||
|
@ -32,4 +32,5 @@ export abstract class VaultFilterService {
|
||||
) => Observable<TreeNode<CipherTypeFilter>>;
|
||||
// TODO: Remove this from org vault when collection admin service adopts state management
|
||||
reloadCollections?: (collections: CollectionAdminView[]) => void;
|
||||
clearOrganizationFilter: () => void;
|
||||
}
|
||||
|
@ -103,6 +103,10 @@ export class VaultFilterService implements VaultFilterServiceAbstraction {
|
||||
return this._organizationFilter;
|
||||
}
|
||||
|
||||
clearOrganizationFilter() {
|
||||
this._organizationFilter.next(null);
|
||||
}
|
||||
|
||||
setOrganizationFilter(organization: Organization) {
|
||||
if (organization?.id != "AllVaults") {
|
||||
this._organizationFilter.next(organization);
|
||||
|
@ -394,6 +394,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
||||
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
this.vaultFilterService.clearOrganizationFilter();
|
||||
}
|
||||
|
||||
async onVaultItemsEvent(event: VaultItemEvent) {
|
||||
|
@ -7892,7 +7892,7 @@
|
||||
"message": "Adjustments to seats will be reflected in the next billing cycle."
|
||||
},
|
||||
"unassignedSeatsDescription": {
|
||||
"message": "Unassigned subscription seats"
|
||||
"message": "Unassigned seats"
|
||||
},
|
||||
"purchaseSeatDescription": {
|
||||
"message": "Additional seats purchased"
|
||||
@ -8399,10 +8399,6 @@
|
||||
"exportClientReport": {
|
||||
"message": "Export client report"
|
||||
},
|
||||
"invoiceNumberHeader": {
|
||||
"message": "Invoice number",
|
||||
"description": "A table header for an invoice's number"
|
||||
},
|
||||
"memberAccessReport": {
|
||||
"message": "Member access"
|
||||
},
|
||||
@ -8450,5 +8446,29 @@
|
||||
},
|
||||
"smAccessRemovalSecretMessage": {
|
||||
"message": "This action will remove your access to this secret."
|
||||
},
|
||||
"invoice": {
|
||||
"message": "Invoice"
|
||||
},
|
||||
"unassignedSeatsAvailable": {
|
||||
"message": "You have $SEATS$ unassigned seats available.",
|
||||
"placeholders": {
|
||||
"seats": {
|
||||
"content": "$1",
|
||||
"example": "10"
|
||||
}
|
||||
},
|
||||
"description": "A message showing how many unassigned seats are available for a provider."
|
||||
},
|
||||
"contactYourProviderForAdditionalSeats": {
|
||||
"message": "Contact your provider admin to purchase additional seats."
|
||||
},
|
||||
"open": {
|
||||
"message": "Open",
|
||||
"description": "The status of an invoice."
|
||||
},
|
||||
"uncollectible": {
|
||||
"message": "Uncollectible",
|
||||
"description": "The status of an invoice."
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
|
||||
import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service";
|
||||
import { ProviderUserType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { canAccessBilling } from "@bitwarden/common/billing/abstractions/provider-billing.service.abstraction";
|
||||
import { hasConsolidatedBilling } from "@bitwarden/common/billing/abstractions/provider-billing.service.abstraction";
|
||||
import { PlanType } from "@bitwarden/common/billing/enums";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
@ -72,9 +72,9 @@ export class ClientsComponent extends BaseClientsComponent {
|
||||
switchMap((params) => {
|
||||
this.providerId = params.providerId;
|
||||
return this.providerService.get$(this.providerId).pipe(
|
||||
canAccessBilling(this.configService),
|
||||
map((canAccessBilling) => {
|
||||
if (canAccessBilling) {
|
||||
hasConsolidatedBilling(this.configService),
|
||||
map((hasConsolidatedBilling) => {
|
||||
if (hasConsolidatedBilling) {
|
||||
return from(
|
||||
this.router.navigate(["../manage-client-organizations"], {
|
||||
relativeTo: this.activatedRoute,
|
||||
|
@ -5,7 +5,7 @@
|
||||
<bit-nav-item
|
||||
icon="bwi-bank"
|
||||
[text]="'clients' | i18n"
|
||||
[route]="(canAccessBilling$ | async) ? 'manage-client-organizations' : 'clients'"
|
||||
[route]="(hasConsolidatedBilling$ | async) ? 'manage-client-organizations' : 'clients'"
|
||||
></bit-nav-item>
|
||||
<bit-nav-group
|
||||
icon="bwi-sliders"
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute, RouterModule } from "@angular/router";
|
||||
import { switchMap, Observable, Subject, filter, startWith } from "rxjs";
|
||||
import { switchMap, Observable, Subject, combineLatest, map } from "rxjs";
|
||||
import { takeUntil } from "rxjs/operators";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service";
|
||||
import { Provider } from "@bitwarden/common/admin-console/models/domain/provider";
|
||||
import { canAccessBilling } from "@bitwarden/common/billing/abstractions/provider-billing.service.abstraction";
|
||||
import { hasConsolidatedBilling } from "@bitwarden/common/billing/abstractions/provider-billing.service.abstraction";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { IconModule, LayoutComponent, NavigationModule } from "@bitwarden/components";
|
||||
@ -37,6 +37,8 @@ export class ProvidersLayoutComponent implements OnInit, OnDestroy {
|
||||
|
||||
private destroy$ = new Subject<void>();
|
||||
protected provider$: Observable<Provider>;
|
||||
|
||||
protected hasConsolidatedBilling$: Observable<boolean>;
|
||||
protected canAccessBilling$: Observable<boolean>;
|
||||
|
||||
protected showPaymentMethodWarningBanners$ = this.configService.getFeatureFlag$(
|
||||
@ -57,10 +59,15 @@ export class ProvidersLayoutComponent implements OnInit, OnDestroy {
|
||||
takeUntil(this.destroy$),
|
||||
);
|
||||
|
||||
this.canAccessBilling$ = this.provider$.pipe(
|
||||
filter((provider) => !!provider),
|
||||
canAccessBilling(this.configService),
|
||||
startWith(false),
|
||||
this.hasConsolidatedBilling$ = this.provider$.pipe(
|
||||
hasConsolidatedBilling(this.configService),
|
||||
takeUntil(this.destroy$),
|
||||
);
|
||||
|
||||
this.canAccessBilling$ = combineLatest([this.hasConsolidatedBilling$, this.provider$]).pipe(
|
||||
map(
|
||||
([hasConsolidatedBilling, provider]) => hasConsolidatedBilling && provider.isProviderAdmin,
|
||||
),
|
||||
takeUntil(this.destroy$),
|
||||
);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import { FrontendLayoutComponent } from "@bitwarden/web-vault/app/layouts/fronte
|
||||
import { UserLayoutComponent } from "@bitwarden/web-vault/app/layouts/user-layout.component";
|
||||
|
||||
import {
|
||||
ManageClientOrganizationsComponent,
|
||||
ManageClientsComponent,
|
||||
ProviderSubscriptionComponent,
|
||||
hasConsolidatedBilling,
|
||||
ProviderPaymentMethodComponent,
|
||||
@ -85,7 +85,7 @@ const routes: Routes = [
|
||||
{
|
||||
path: "manage-client-organizations",
|
||||
canActivate: [hasConsolidatedBilling],
|
||||
component: ManageClientOrganizationsComponent,
|
||||
component: ManageClientsComponent,
|
||||
data: { titleId: "clients" },
|
||||
},
|
||||
{
|
||||
@ -118,7 +118,7 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: "billing",
|
||||
canActivate: [hasConsolidatedBilling],
|
||||
canActivate: [ProviderPermissionsGuard, hasConsolidatedBilling],
|
||||
data: { providerPermissions: (provider: Provider) => provider.isProviderAdmin },
|
||||
children: [
|
||||
{
|
||||
@ -129,6 +129,7 @@ const routes: Routes = [
|
||||
{
|
||||
path: "subscription",
|
||||
component: ProviderSubscriptionComponent,
|
||||
canActivate: [ProviderPermissionsGuard],
|
||||
data: {
|
||||
titleId: "subscription",
|
||||
},
|
||||
@ -136,6 +137,7 @@ const routes: Routes = [
|
||||
{
|
||||
path: "payment-method",
|
||||
component: ProviderPaymentMethodComponent,
|
||||
canActivate: [ProviderPermissionsGuard],
|
||||
data: {
|
||||
titleId: "paymentMethod",
|
||||
},
|
||||
@ -143,6 +145,7 @@ const routes: Routes = [
|
||||
{
|
||||
path: "history",
|
||||
component: ProviderBillingHistoryComponent,
|
||||
canActivate: [ProviderPermissionsGuard],
|
||||
data: {
|
||||
titleId: "billingHistory",
|
||||
},
|
||||
|
@ -10,11 +10,11 @@ import { PaymentMethodWarningsModule } from "@bitwarden/web-vault/app/billing/sh
|
||||
import { OssModule } from "@bitwarden/web-vault/app/oss.module";
|
||||
|
||||
import {
|
||||
CreateClientOrganizationComponent,
|
||||
CreateClientDialogComponent,
|
||||
NoClientsComponent,
|
||||
ManageClientOrganizationNameComponent,
|
||||
ManageClientOrganizationsComponent,
|
||||
ManageClientOrganizationSubscriptionComponent,
|
||||
ManageClientNameDialogComponent,
|
||||
ManageClientsComponent,
|
||||
ManageClientSubscriptionDialogComponent,
|
||||
ProviderBillingHistoryComponent,
|
||||
ProviderPaymentMethodComponent,
|
||||
ProviderSelectPaymentMethodDialogComponent,
|
||||
@ -66,11 +66,11 @@ import { SetupComponent } from "./setup/setup.component";
|
||||
SetupComponent,
|
||||
SetupProviderComponent,
|
||||
UserAddEditComponent,
|
||||
CreateClientOrganizationComponent,
|
||||
CreateClientDialogComponent,
|
||||
NoClientsComponent,
|
||||
ManageClientOrganizationsComponent,
|
||||
ManageClientOrganizationNameComponent,
|
||||
ManageClientOrganizationSubscriptionComponent,
|
||||
ManageClientsComponent,
|
||||
ManageClientNameDialogComponent,
|
||||
ManageClientSubscriptionDialogComponent,
|
||||
ProviderBillingHistoryComponent,
|
||||
ProviderSubscriptionComponent,
|
||||
ProviderSelectPaymentMethodDialogComponent,
|
||||
|
@ -56,13 +56,15 @@
|
||||
<input type="text" bitInput formControlName="seats" />
|
||||
<bit-hint
|
||||
class="tw-text-muted tw-grid tw-grid-flow-col tw-gap-1 tw-grid-cols-1 tw-grid-rows-2"
|
||||
*ngIf="unassignedSeatsForSelectedPlan > 0"
|
||||
*ngIf="openSeats > 0"
|
||||
>
|
||||
<span class="tw-col-span-1"
|
||||
>{{ unassignedSeatsForSelectedPlan }}
|
||||
{{ "unassignedSeatsDescription" | i18n | lowercase }}</span
|
||||
>{{ unassignedSeats }} {{ "unassignedSeatsDescription" | i18n | lowercase }}</span
|
||||
>
|
||||
<span class="tw-col-span-1"
|
||||
>{{ additionalSeatsPurchased }}
|
||||
{{ "purchaseSeatDescription" | i18n | lowercase }}</span
|
||||
>
|
||||
<span class="tw-col-span-1">0 {{ "purchaseSeatDescription" | i18n | lowercase }}</span>
|
||||
</bit-hint>
|
||||
</bit-form-field>
|
||||
</div>
|
@ -1,6 +1,6 @@
|
||||
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
|
||||
import { Component, Inject, OnInit } from "@angular/core";
|
||||
import { FormBuilder, Validators } from "@angular/forms";
|
||||
import { FormControl, FormGroup, Validators } from "@angular/forms";
|
||||
|
||||
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions/billilng-api.service.abstraction";
|
||||
import { PlanType } from "@bitwarden/common/billing/enums";
|
||||
@ -11,22 +11,22 @@ import { DialogService, ToastService } from "@bitwarden/components";
|
||||
|
||||
import { WebProviderService } from "../../../admin-console/providers/services/web-provider.service";
|
||||
|
||||
type CreateClientOrganizationParams = {
|
||||
type CreateClientDialogParams = {
|
||||
providerId: string;
|
||||
plans: PlanResponse[];
|
||||
};
|
||||
|
||||
export enum CreateClientOrganizationResultType {
|
||||
export enum CreateClientDialogResultType {
|
||||
Closed = "closed",
|
||||
Submitted = "submitted",
|
||||
}
|
||||
|
||||
export const openCreateClientOrganizationDialog = (
|
||||
export const openCreateClientDialog = (
|
||||
dialogService: DialogService,
|
||||
dialogConfig: DialogConfig<CreateClientOrganizationParams>,
|
||||
dialogConfig: DialogConfig<CreateClientDialogParams>,
|
||||
) =>
|
||||
dialogService.open<CreateClientOrganizationResultType, CreateClientOrganizationParams>(
|
||||
CreateClientOrganizationComponent,
|
||||
dialogService.open<CreateClientDialogResultType, CreateClientDialogParams>(
|
||||
CreateClientDialogComponent,
|
||||
dialogConfig,
|
||||
);
|
||||
|
||||
@ -39,26 +39,24 @@ type PlanCard = {
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: "app-create-client-organization",
|
||||
templateUrl: "./create-client-organization.component.html",
|
||||
templateUrl: "./create-client-dialog.component.html",
|
||||
})
|
||||
export class CreateClientOrganizationComponent implements OnInit {
|
||||
protected formGroup = this.formBuilder.group({
|
||||
clientOwnerEmail: ["", [Validators.required, Validators.email]],
|
||||
organizationName: ["", Validators.required],
|
||||
seats: [null, [Validators.required, Validators.min(1)]],
|
||||
export class CreateClientDialogComponent implements OnInit {
|
||||
protected formGroup = new FormGroup({
|
||||
clientOwnerEmail: new FormControl<string>("", [Validators.required, Validators.email]),
|
||||
organizationName: new FormControl<string>("", [Validators.required]),
|
||||
seats: new FormControl<number>(null, [Validators.required, Validators.min(1)]),
|
||||
});
|
||||
protected loading = true;
|
||||
protected planCards: PlanCard[];
|
||||
protected ResultType = CreateClientOrganizationResultType;
|
||||
protected ResultType = CreateClientDialogResultType;
|
||||
|
||||
private providerPlans: ProviderPlanResponse[];
|
||||
|
||||
constructor(
|
||||
private billingApiService: BillingApiServiceAbstraction,
|
||||
@Inject(DIALOG_DATA) private dialogParams: CreateClientOrganizationParams,
|
||||
private dialogRef: DialogRef<CreateClientOrganizationResultType>,
|
||||
private formBuilder: FormBuilder,
|
||||
@Inject(DIALOG_DATA) private dialogParams: CreateClientDialogParams,
|
||||
private dialogRef: DialogRef<CreateClientDialogResultType>,
|
||||
private i18nService: I18nService,
|
||||
private toastService: ToastService,
|
||||
private webProviderService: WebProviderService,
|
||||
@ -111,14 +109,14 @@ export class CreateClientOrganizationComponent implements OnInit {
|
||||
this.planCards = [
|
||||
{
|
||||
name: this.i18nService.t("planNameTeams"),
|
||||
cost: teamsPlan.PasswordManager.seatPrice * 0.65, // 35% off for MSPs,
|
||||
cost: teamsPlan.PasswordManager.providerPortalSeatPrice * 0.65, // 35% off for MSPs,
|
||||
type: teamsPlan.type,
|
||||
plan: teamsPlan,
|
||||
selected: true,
|
||||
},
|
||||
{
|
||||
name: this.i18nService.t("planNameEnterprise"),
|
||||
cost: enterprisePlan.PasswordManager.seatPrice * 0.65, // 35% off for MSPs,
|
||||
cost: enterprisePlan.PasswordManager.providerPortalSeatPrice * 0.65, // 35% off for MSPs,
|
||||
type: enterprisePlan.type,
|
||||
plan: enterprisePlan,
|
||||
selected: false,
|
||||
@ -159,14 +157,41 @@ export class CreateClientOrganizationComponent implements OnInit {
|
||||
this.dialogRef.close(this.ResultType.Submitted);
|
||||
};
|
||||
|
||||
protected get unassignedSeatsForSelectedPlan(): number {
|
||||
if (this.loading || !this.planCards) {
|
||||
protected get openSeats(): number {
|
||||
const selectedProviderPlan = this.getSelectedProviderPlan();
|
||||
|
||||
if (selectedProviderPlan === null) {
|
||||
return 0;
|
||||
}
|
||||
const selectedPlan = this.planCards.find((planCard) => planCard.selected).plan;
|
||||
const selectedProviderPlan = this.providerPlans.find(
|
||||
(providerPlan) => providerPlan.planName === selectedPlan.name,
|
||||
);
|
||||
|
||||
return selectedProviderPlan.seatMinimum - selectedProviderPlan.assignedSeats;
|
||||
}
|
||||
|
||||
protected get unassignedSeats(): number {
|
||||
const unassignedSeats = this.openSeats - this.formGroup.value.seats;
|
||||
|
||||
return unassignedSeats > 0 ? unassignedSeats : 0;
|
||||
}
|
||||
|
||||
protected get additionalSeatsPurchased(): number {
|
||||
const selectedProviderPlan = this.getSelectedProviderPlan();
|
||||
|
||||
if (selectedProviderPlan === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const selectedSeats = this.formGroup.value.seats ?? 0;
|
||||
|
||||
const purchased = selectedSeats - this.openSeats;
|
||||
|
||||
return purchased > 0 ? purchased : 0;
|
||||
}
|
||||
|
||||
private getSelectedProviderPlan(): ProviderPlanResponse {
|
||||
if (this.loading || !this.planCards) {
|
||||
return null;
|
||||
}
|
||||
const selectedPlan = this.planCards.find((planCard) => planCard.selected).plan;
|
||||
return this.providerPlans.find((providerPlan) => providerPlan.planName === selectedPlan.name);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
export * from "./create-client-organization.component";
|
||||
export * from "./manage-client-organizations.component";
|
||||
export * from "./manage-client-organization-name.component";
|
||||
export * from "./manage-client-organization-subscription.component";
|
||||
export * from "./create-client-dialog.component";
|
||||
export * from "./manage-clients.component";
|
||||
export * from "./manage-client-name-dialog.component";
|
||||
export * from "./manage-client-subscription-dialog.component";
|
||||
export * from "./no-clients.component";
|
||||
|
@ -7,7 +7,7 @@ import { UpdateClientOrganizationRequest } from "@bitwarden/common/billing/model
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { DialogService, ToastService } from "@bitwarden/components";
|
||||
|
||||
type ManageClientOrganizationNameParams = {
|
||||
type ManageClientNameDialogParams = {
|
||||
providerId: string;
|
||||
organization: {
|
||||
id: string;
|
||||
@ -16,34 +16,33 @@ type ManageClientOrganizationNameParams = {
|
||||
};
|
||||
};
|
||||
|
||||
export enum ManageClientOrganizationNameResultType {
|
||||
export enum ManageClientNameDialogResultType {
|
||||
Closed = "closed",
|
||||
Submitted = "submitted",
|
||||
}
|
||||
|
||||
export const openManageClientOrganizationNameDialog = (
|
||||
export const openManageClientNameDialog = (
|
||||
dialogService: DialogService,
|
||||
dialogConfig: DialogConfig<ManageClientOrganizationNameParams>,
|
||||
dialogConfig: DialogConfig<ManageClientNameDialogParams>,
|
||||
) =>
|
||||
dialogService.open<ManageClientOrganizationNameResultType, ManageClientOrganizationNameParams>(
|
||||
ManageClientOrganizationNameComponent,
|
||||
dialogService.open<ManageClientNameDialogResultType, ManageClientNameDialogParams>(
|
||||
ManageClientNameDialogComponent,
|
||||
dialogConfig,
|
||||
);
|
||||
|
||||
@Component({
|
||||
selector: "app-manage-client-organization-name",
|
||||
templateUrl: "manage-client-organization-name.component.html",
|
||||
templateUrl: "manage-client-name-dialog.component.html",
|
||||
})
|
||||
export class ManageClientOrganizationNameComponent {
|
||||
protected ResultType = ManageClientOrganizationNameResultType;
|
||||
export class ManageClientNameDialogComponent {
|
||||
protected ResultType = ManageClientNameDialogResultType;
|
||||
protected formGroup = this.formBuilder.group({
|
||||
name: [this.dialogParams.organization.name, Validators.required],
|
||||
});
|
||||
|
||||
constructor(
|
||||
@Inject(DIALOG_DATA) protected dialogParams: ManageClientOrganizationNameParams,
|
||||
@Inject(DIALOG_DATA) protected dialogParams: ManageClientNameDialogParams,
|
||||
private billingApiService: BillingApiServiceAbstraction,
|
||||
private dialogRef: DialogRef<ManageClientOrganizationNameResultType>,
|
||||
private dialogRef: DialogRef<ManageClientNameDialogResultType>,
|
||||
private formBuilder: FormBuilder,
|
||||
private i18nService: I18nService,
|
||||
private toastService: ToastService,
|
@ -1,40 +0,0 @@
|
||||
<bit-dialog dialogSize="large" [loading]="loading">
|
||||
<span bitDialogTitle>
|
||||
{{ "manageSeats" | i18n }}
|
||||
<small class="tw-text-muted" *ngIf="clientName">{{ clientName }}</small>
|
||||
</span>
|
||||
<div bitDialogContent>
|
||||
<p>
|
||||
{{ "manageSeatsDescription" | i18n }}
|
||||
</p>
|
||||
<bit-form-field disableMargin>
|
||||
<bit-label>
|
||||
{{ "assignedSeats" | i18n }}
|
||||
</bit-label>
|
||||
<input id="assignedSeats" type="number" bitInput required [(ngModel)]="assignedSeats" />
|
||||
<bit-hint class="tw-text-muted" *ngIf="remainingOpenSeats > 0">
|
||||
<div class="tw-grid tw-grid-flow-col tw-gap-1 tw-grid-cols-1 tw-grid-rows-2">
|
||||
<span class="tw-col-span-1"
|
||||
>{{ unassignedSeats }} {{ "unassignedSeatsDescription" | i18n | lowercase }}</span
|
||||
>
|
||||
<span class="tw-col-span-1">0 {{ "purchaseSeatDescription" | i18n | lowercase }}</span>
|
||||
</div>
|
||||
</bit-hint>
|
||||
</bit-form-field>
|
||||
</div>
|
||||
<ng-container bitDialogFooter>
|
||||
<button
|
||||
type="submit"
|
||||
bitButton
|
||||
buttonType="primary"
|
||||
bitFormButton
|
||||
(click)="updateSubscription(assignedSeats)"
|
||||
>
|
||||
<i class="bwi bwi-refresh bwi-fw" aria-hidden="true"></i>
|
||||
{{ "save" | i18n }}
|
||||
</button>
|
||||
<button bitButton type="button" buttonType="secondary" bitDialogClose>
|
||||
{{ "cancel" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
</bit-dialog>
|
@ -1,116 +0,0 @@
|
||||
import { DIALOG_DATA, DialogRef } from "@angular/cdk/dialog";
|
||||
import { Component, Inject, OnInit } from "@angular/core";
|
||||
|
||||
import { ProviderOrganizationOrganizationDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-organization.response";
|
||||
import { BillingApiServiceAbstraction as BillingApiService } from "@bitwarden/common/billing/abstractions/billilng-api.service.abstraction";
|
||||
import { UpdateClientOrganizationRequest } from "@bitwarden/common/billing/models/request/update-client-organization.request";
|
||||
import { ProviderPlanResponse } from "@bitwarden/common/billing/models/response/provider-subscription-response";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
|
||||
type ManageClientOrganizationDialogParams = {
|
||||
organization: ProviderOrganizationOrganizationDetailsResponse;
|
||||
};
|
||||
|
||||
@Component({
|
||||
templateUrl: "manage-client-organization-subscription.component.html",
|
||||
})
|
||||
// eslint-disable-next-line rxjs-angular/prefer-takeuntil
|
||||
export class ManageClientOrganizationSubscriptionComponent implements OnInit {
|
||||
loading = true;
|
||||
providerOrganizationId: string;
|
||||
providerId: string;
|
||||
|
||||
clientName: string;
|
||||
assignedSeats: number;
|
||||
unassignedSeats: number;
|
||||
planName: string;
|
||||
AdditionalSeatPurchased: number;
|
||||
remainingOpenSeats: number;
|
||||
|
||||
constructor(
|
||||
public dialogRef: DialogRef,
|
||||
@Inject(DIALOG_DATA) protected data: ManageClientOrganizationDialogParams,
|
||||
private billingApiService: BillingApiService,
|
||||
private i18nService: I18nService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
) {
|
||||
this.providerOrganizationId = data.organization.id;
|
||||
this.providerId = data.organization.providerId;
|
||||
this.clientName = data.organization.organizationName;
|
||||
this.assignedSeats = data.organization.seats;
|
||||
this.planName = data.organization.plan;
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
try {
|
||||
const response = await this.billingApiService.getProviderSubscription(this.providerId);
|
||||
this.AdditionalSeatPurchased = this.getPurchasedSeatsByPlan(this.planName, response.plans);
|
||||
const seatMinimum = this.getProviderSeatMinimumByPlan(this.planName, response.plans);
|
||||
const assignedByPlan = this.getAssignedByPlan(this.planName, response.plans);
|
||||
this.remainingOpenSeats = seatMinimum - assignedByPlan;
|
||||
this.unassignedSeats = Math.abs(this.remainingOpenSeats);
|
||||
} catch (error) {
|
||||
this.remainingOpenSeats = 0;
|
||||
this.AdditionalSeatPurchased = 0;
|
||||
}
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
async updateSubscription(assignedSeats: number) {
|
||||
this.loading = true;
|
||||
if (!assignedSeats) {
|
||||
this.platformUtilsService.showToast(
|
||||
"error",
|
||||
null,
|
||||
this.i18nService.t("assignedSeatCannotUpdate"),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const request = new UpdateClientOrganizationRequest();
|
||||
request.assignedSeats = assignedSeats;
|
||||
request.name = this.clientName;
|
||||
|
||||
await this.billingApiService.updateClientOrganization(
|
||||
this.providerId,
|
||||
this.providerOrganizationId,
|
||||
request,
|
||||
);
|
||||
this.platformUtilsService.showToast("success", null, this.i18nService.t("subscriptionUpdated"));
|
||||
this.loading = false;
|
||||
this.dialogRef.close();
|
||||
}
|
||||
|
||||
getPurchasedSeatsByPlan(planName: string, plans: ProviderPlanResponse[]): number {
|
||||
const plan = plans.find((plan) => plan.planName === planName);
|
||||
if (plan) {
|
||||
return plan.purchasedSeats;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
getAssignedByPlan(planName: string, plans: ProviderPlanResponse[]): number {
|
||||
const plan = plans.find((plan) => plan.planName === planName);
|
||||
if (plan) {
|
||||
return plan.assignedSeats;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
getProviderSeatMinimumByPlan(planName: string, plans: ProviderPlanResponse[]) {
|
||||
const plan = plans.find((plan) => plan.planName === planName);
|
||||
if (plan) {
|
||||
return plan.seatMinimum;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static open(dialogService: DialogService, data: ManageClientOrganizationDialogParams) {
|
||||
return dialogService.open(ManageClientOrganizationSubscriptionComponent, { data });
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
<form [formGroup]="formGroup" [bitSubmit]="submit">
|
||||
<bit-dialog dialogSize="large" [loading]="loading">
|
||||
<span bitDialogTitle>
|
||||
{{ "manageSeats" | i18n }}
|
||||
<small class="tw-text-muted">{{ dialogParams.organization.organizationName }}</small>
|
||||
</span>
|
||||
<div bitDialogContent>
|
||||
<p>{{ "manageSeatsDescription" | i18n }}</p>
|
||||
<bit-form-field disableMargin>
|
||||
<bit-label>
|
||||
{{ "assignedSeats" | i18n }}
|
||||
</bit-label>
|
||||
<input type="number" bitInput formControlName="assignedSeats" />
|
||||
<bit-hint class="tw-text-muted" *ngIf="openSeats > 0 || isServiceUserWithPurchasedSeats">
|
||||
<div
|
||||
*ngIf="!this.isServiceUserWithPurchasedSeats"
|
||||
class="tw-grid tw-grid-flow-col tw-gap-1 tw-grid-cols-1"
|
||||
[ngClass]="{ 'tw-grid-rows-2': this.isProviderAdmin }"
|
||||
>
|
||||
<span class="tw-col-span-1">
|
||||
{{ unassignedSeats }} {{ "unassignedSeatsDescription" | i18n | lowercase }}
|
||||
</span>
|
||||
<span *ngIf="this.isProviderAdmin" class="tw-col-span-1"
|
||||
>{{ additionalSeatsPurchased }}
|
||||
{{ "purchaseSeatDescription" | i18n | lowercase }}</span
|
||||
>
|
||||
</div>
|
||||
</bit-hint>
|
||||
</bit-form-field>
|
||||
</div>
|
||||
<ng-container bitDialogFooter>
|
||||
<button
|
||||
bitButton
|
||||
bitFormButton
|
||||
buttonType="primary"
|
||||
type="submit"
|
||||
[disabled]="formGroup.invalid"
|
||||
>
|
||||
{{ "save" | i18n }}
|
||||
</button>
|
||||
<button bitButton buttonType="secondary" type="button" [bitDialogClose]="ResultType.Closed">
|
||||
{{ "cancel" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
</bit-dialog>
|
||||
</form>
|
@ -0,0 +1,180 @@
|
||||
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
|
||||
import { Component, Inject, OnInit } from "@angular/core";
|
||||
import { FormControl, FormGroup, ValidationErrors, ValidatorFn, Validators } from "@angular/forms";
|
||||
|
||||
import { ProviderUserType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Provider } from "@bitwarden/common/admin-console/models/domain/provider";
|
||||
import { ProviderOrganizationOrganizationDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-organization.response";
|
||||
import { BillingApiServiceAbstraction } from "@bitwarden/common/billing/abstractions";
|
||||
import { UpdateClientOrganizationRequest } from "@bitwarden/common/billing/models/request/update-client-organization.request";
|
||||
import { ProviderPlanResponse } from "@bitwarden/common/billing/models/response/provider-subscription-response";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { DialogService, ToastService } from "@bitwarden/components";
|
||||
|
||||
type ManageClientSubscriptionDialogParams = {
|
||||
organization: ProviderOrganizationOrganizationDetailsResponse;
|
||||
provider: Provider;
|
||||
};
|
||||
|
||||
export enum ManageClientSubscriptionDialogResultType {
|
||||
Closed = "closed",
|
||||
Submitted = "submitted",
|
||||
}
|
||||
|
||||
export const openManageClientSubscriptionDialog = (
|
||||
dialogService: DialogService,
|
||||
dialogConfig: DialogConfig<ManageClientSubscriptionDialogParams>,
|
||||
) =>
|
||||
dialogService.open<
|
||||
ManageClientSubscriptionDialogResultType,
|
||||
ManageClientSubscriptionDialogParams
|
||||
>(ManageClientSubscriptionDialogComponent, dialogConfig);
|
||||
|
||||
@Component({
|
||||
templateUrl: "./manage-client-subscription-dialog.component.html",
|
||||
})
|
||||
export class ManageClientSubscriptionDialogComponent implements OnInit {
|
||||
protected loading = true;
|
||||
protected providerPlan: ProviderPlanResponse;
|
||||
protected openSeats: number;
|
||||
protected readonly ResultType = ManageClientSubscriptionDialogResultType;
|
||||
|
||||
protected formGroup = new FormGroup({
|
||||
assignedSeats: new FormControl<number>(this.dialogParams.organization.seats, [
|
||||
Validators.required,
|
||||
Validators.min(0),
|
||||
]),
|
||||
});
|
||||
|
||||
constructor(
|
||||
private billingApiService: BillingApiServiceAbstraction,
|
||||
@Inject(DIALOG_DATA) protected dialogParams: ManageClientSubscriptionDialogParams,
|
||||
private dialogRef: DialogRef<ManageClientSubscriptionDialogResultType>,
|
||||
private i18nService: I18nService,
|
||||
private toastService: ToastService,
|
||||
) {}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
const response = await this.billingApiService.getProviderSubscription(
|
||||
this.dialogParams.provider.id,
|
||||
);
|
||||
|
||||
this.providerPlan = response.plans.find(
|
||||
(plan) => plan.planName === this.dialogParams.organization.plan,
|
||||
);
|
||||
|
||||
this.openSeats = this.providerPlan.seatMinimum - this.providerPlan.assignedSeats;
|
||||
|
||||
this.formGroup.controls.assignedSeats.addValidators(
|
||||
this.isServiceUserWithPurchasedSeats
|
||||
? this.createPurchasedSeatsValidator()
|
||||
: this.createUnassignedSeatsValidator(),
|
||||
);
|
||||
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
submit = async () => {
|
||||
this.loading = true;
|
||||
|
||||
this.formGroup.markAllAsTouched();
|
||||
|
||||
if (this.formGroup.invalid) {
|
||||
return;
|
||||
}
|
||||
|
||||
const request = new UpdateClientOrganizationRequest();
|
||||
request.assignedSeats = this.formGroup.value.assignedSeats;
|
||||
request.name = this.dialogParams.organization.organizationName;
|
||||
|
||||
await this.billingApiService.updateClientOrganization(
|
||||
this.dialogParams.provider.id,
|
||||
this.dialogParams.organization.id,
|
||||
request,
|
||||
);
|
||||
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
title: null,
|
||||
message: this.i18nService.t("subscriptionUpdated"),
|
||||
});
|
||||
|
||||
this.loading = false;
|
||||
this.dialogRef.close(this.ResultType.Submitted);
|
||||
};
|
||||
|
||||
createPurchasedSeatsValidator =
|
||||
(): ValidatorFn =>
|
||||
(formControl: FormControl<number>): ValidationErrors | null => {
|
||||
if (this.isProviderAdmin) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const seatAdjustment = formControl.value - this.dialogParams.organization.seats;
|
||||
|
||||
if (seatAdjustment <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
insufficientPermissions: {
|
||||
message: this.i18nService.t("contactYourProviderForAdditionalSeats"),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
createUnassignedSeatsValidator =
|
||||
(): ValidatorFn =>
|
||||
(formControl: FormControl<number>): ValidationErrors | null => {
|
||||
if (this.isProviderAdmin) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const seatAdjustment = formControl.value - this.dialogParams.organization.seats;
|
||||
|
||||
if (seatAdjustment <= this.openSeats) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const unassignedSeatsAvailableMessage = this.i18nService.t(
|
||||
"unassignedSeatsAvailable",
|
||||
this.openSeats,
|
||||
);
|
||||
|
||||
const contactYourProviderMessage = this.i18nService.t(
|
||||
"contactYourProviderForAdditionalSeats",
|
||||
);
|
||||
|
||||
return {
|
||||
insufficientPermissions: {
|
||||
message: `${unassignedSeatsAvailableMessage} ${contactYourProviderMessage}`,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
get unassignedSeats(): number {
|
||||
const seatDifference =
|
||||
this.formGroup.value.assignedSeats - this.dialogParams.organization.seats;
|
||||
|
||||
const unassignedSeats = this.openSeats - seatDifference;
|
||||
|
||||
return unassignedSeats >= 0 ? unassignedSeats : 0;
|
||||
}
|
||||
|
||||
get additionalSeatsPurchased(): number {
|
||||
const seatDifference =
|
||||
this.formGroup.value.assignedSeats - this.dialogParams.organization.seats;
|
||||
|
||||
const purchasedSeats = seatDifference - this.openSeats;
|
||||
|
||||
return purchasedSeats > 0 ? purchasedSeats : 0;
|
||||
}
|
||||
|
||||
get isProviderAdmin(): boolean {
|
||||
return this.dialogParams.provider.type === ProviderUserType.ProviderAdmin;
|
||||
}
|
||||
|
||||
get isServiceUserWithPurchasedSeats(): boolean {
|
||||
return !this.isProviderAdmin && this.providerPlan && this.providerPlan.purchasedSeats > 0;
|
||||
}
|
||||
}
|
@ -1,12 +1,6 @@
|
||||
<app-header>
|
||||
<bit-search [placeholder]="'search' | i18n" [(ngModel)]="searchText"></bit-search>
|
||||
<a
|
||||
type="button"
|
||||
bitButton
|
||||
*ngIf="manageOrganizations"
|
||||
buttonType="primary"
|
||||
(click)="createClientOrganization()"
|
||||
>
|
||||
<a type="button" bitButton *ngIf="isProviderAdmin" buttonType="primary" (click)="createClient()">
|
||||
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
|
||||
{{ "addNewOrganization" | i18n }}
|
||||
</a>
|
||||
@ -73,15 +67,15 @@
|
||||
appA11yTitle="{{ 'options' | i18n }}"
|
||||
></button>
|
||||
<bit-menu #rowMenu>
|
||||
<button type="button" bitMenuItem (click)="manageName(client)">
|
||||
<button type="button" bitMenuItem (click)="manageClientName(client)">
|
||||
<i aria-hidden="true" class="bwi bwi-pencil-square"></i>
|
||||
{{ "updateName" | i18n }}
|
||||
</button>
|
||||
<button type="button" bitMenuItem (click)="manageSubscription(client)">
|
||||
<button type="button" bitMenuItem (click)="manageClientSubscription(client)">
|
||||
<i aria-hidden="true" class="bwi bwi-family"></i>
|
||||
{{ "manageSubscription" | i18n }}
|
||||
</button>
|
||||
<button type="button" bitMenuItem (click)="remove(client)">
|
||||
<button *ngIf="this.isProviderAdmin" type="button" bitMenuItem (click)="remove(client)">
|
||||
<span class="tw-text-danger">
|
||||
<i aria-hidden="true" class="bwi bwi-close"></i> {{ "unlinkOrganization" | i18n }}
|
||||
</span>
|
||||
@ -92,6 +86,9 @@
|
||||
</ng-template>
|
||||
</bit-table>
|
||||
<div *ngIf="clients.length === 0" class="tw-mt-10">
|
||||
<app-no-clients (addNewOrganizationClicked)="createClientOrganization()" />
|
||||
<app-no-clients
|
||||
[showAddOrganizationButton]="this.isProviderAdmin"
|
||||
(addNewOrganizationClicked)="createClient()"
|
||||
/>
|
||||
</div>
|
||||
</ng-container>
|
@ -10,7 +10,7 @@ import { ProviderUserType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Provider } from "@bitwarden/common/admin-console/models/domain/provider";
|
||||
import { ProviderOrganizationOrganizationDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-organization.response";
|
||||
import { BillingApiServiceAbstraction as BillingApiService } from "@bitwarden/common/billing/abstractions/billilng-api.service.abstraction";
|
||||
import { canAccessBilling } from "@bitwarden/common/billing/abstractions/provider-billing.service.abstraction";
|
||||
import { hasConsolidatedBilling } from "@bitwarden/common/billing/abstractions/provider-billing.service.abstraction";
|
||||
import { PlanResponse } from "@bitwarden/common/billing/models/response/plan.response";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
@ -21,24 +21,27 @@ import { BaseClientsComponent } from "../../../admin-console/providers/clients/b
|
||||
import { WebProviderService } from "../../../admin-console/providers/services/web-provider.service";
|
||||
|
||||
import {
|
||||
CreateClientOrganizationResultType,
|
||||
openCreateClientOrganizationDialog,
|
||||
} from "./create-client-organization.component";
|
||||
CreateClientDialogResultType,
|
||||
openCreateClientDialog,
|
||||
} from "./create-client-dialog.component";
|
||||
import {
|
||||
ManageClientOrganizationNameResultType,
|
||||
openManageClientOrganizationNameDialog,
|
||||
} from "./manage-client-organization-name.component";
|
||||
import { ManageClientOrganizationSubscriptionComponent } from "./manage-client-organization-subscription.component";
|
||||
ManageClientNameDialogResultType,
|
||||
openManageClientNameDialog,
|
||||
} from "./manage-client-name-dialog.component";
|
||||
import {
|
||||
ManageClientSubscriptionDialogResultType,
|
||||
openManageClientSubscriptionDialog,
|
||||
} from "./manage-client-subscription-dialog.component";
|
||||
|
||||
@Component({
|
||||
templateUrl: "manage-client-organizations.component.html",
|
||||
templateUrl: "manage-clients.component.html",
|
||||
})
|
||||
export class ManageClientOrganizationsComponent extends BaseClientsComponent {
|
||||
export class ManageClientsComponent extends BaseClientsComponent {
|
||||
providerId: string;
|
||||
provider: Provider;
|
||||
|
||||
loading = true;
|
||||
manageOrganizations = false;
|
||||
isProviderAdmin = false;
|
||||
|
||||
protected plans: PlanResponse[];
|
||||
|
||||
@ -73,9 +76,9 @@ export class ManageClientOrganizationsComponent extends BaseClientsComponent {
|
||||
switchMap((params) => {
|
||||
this.providerId = params.providerId;
|
||||
return this.providerService.get$(this.providerId).pipe(
|
||||
canAccessBilling(this.configService),
|
||||
map((canAccessBilling) => {
|
||||
if (!canAccessBilling) {
|
||||
hasConsolidatedBilling(this.configService),
|
||||
map((hasConsolidatedBilling) => {
|
||||
if (!hasConsolidatedBilling) {
|
||||
return from(
|
||||
this.router.navigate(["../clients"], {
|
||||
relativeTo: this.activatedRoute,
|
||||
@ -99,7 +102,7 @@ export class ManageClientOrganizationsComponent extends BaseClientsComponent {
|
||||
async load() {
|
||||
this.provider = await firstValueFrom(this.providerService.get$(this.providerId));
|
||||
|
||||
this.manageOrganizations = this.provider.type === ProviderUserType.ProviderAdmin;
|
||||
this.isProviderAdmin = this.provider.type === ProviderUserType.ProviderAdmin;
|
||||
|
||||
this.clients = (await this.apiService.getProviderClients(this.providerId)).data;
|
||||
|
||||
@ -110,8 +113,23 @@ export class ManageClientOrganizationsComponent extends BaseClientsComponent {
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
async manageName(organization: ProviderOrganizationOrganizationDetailsResponse) {
|
||||
const dialogRef = openManageClientOrganizationNameDialog(this.dialogService, {
|
||||
createClient = async () => {
|
||||
const reference = openCreateClientDialog(this.dialogService, {
|
||||
data: {
|
||||
providerId: this.providerId,
|
||||
plans: this.plans,
|
||||
},
|
||||
});
|
||||
|
||||
const result = await lastValueFrom(reference.closed);
|
||||
|
||||
if (result === CreateClientDialogResultType.Submitted) {
|
||||
await this.load();
|
||||
}
|
||||
};
|
||||
|
||||
manageClientName = async (organization: ProviderOrganizationOrganizationDetailsResponse) => {
|
||||
const dialogRef = openManageClientNameDialog(this.dialogService, {
|
||||
data: {
|
||||
providerId: this.providerId,
|
||||
organization: {
|
||||
@ -124,38 +142,25 @@ export class ManageClientOrganizationsComponent extends BaseClientsComponent {
|
||||
|
||||
const result = await firstValueFrom(dialogRef.closed);
|
||||
|
||||
if (result === ManageClientOrganizationNameResultType.Submitted) {
|
||||
if (result === ManageClientNameDialogResultType.Submitted) {
|
||||
await this.load();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async manageSubscription(organization: ProviderOrganizationOrganizationDetailsResponse) {
|
||||
if (organization == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dialogRef = ManageClientOrganizationSubscriptionComponent.open(this.dialogService, {
|
||||
organization: organization,
|
||||
});
|
||||
|
||||
await firstValueFrom(dialogRef.closed);
|
||||
await this.load();
|
||||
}
|
||||
|
||||
createClientOrganization = async () => {
|
||||
const reference = openCreateClientOrganizationDialog(this.dialogService, {
|
||||
manageClientSubscription = async (
|
||||
organization: ProviderOrganizationOrganizationDetailsResponse,
|
||||
) => {
|
||||
const dialogRef = openManageClientSubscriptionDialog(this.dialogService, {
|
||||
data: {
|
||||
providerId: this.providerId,
|
||||
plans: this.plans,
|
||||
organization,
|
||||
provider: this.provider,
|
||||
},
|
||||
});
|
||||
|
||||
const result = await lastValueFrom(reference.closed);
|
||||
const result = await firstValueFrom(dialogRef.closed);
|
||||
|
||||
if (result === CreateClientOrganizationResultType.Closed) {
|
||||
return;
|
||||
if (result === ManageClientSubscriptionDialogResultType.Submitted) {
|
||||
await this.load();
|
||||
}
|
||||
|
||||
await this.load();
|
||||
};
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { Component, EventEmitter, Output } from "@angular/core";
|
||||
import { Component, EventEmitter, Input, Output } from "@angular/core";
|
||||
|
||||
import { svgIcon } from "@bitwarden/components";
|
||||
|
||||
@ -26,7 +26,13 @@ const gearIcon = svgIcon`
|
||||
template: `<div class="tw-flex tw-flex-col tw-items-center tw-text-info">
|
||||
<bit-icon [icon]="icon"></bit-icon>
|
||||
<p class="tw-mt-4">{{ "noClients" | i18n }}</p>
|
||||
<a type="button" bitButton buttonType="primary" (click)="addNewOrganization()">
|
||||
<a
|
||||
*ngIf="showAddOrganizationButton"
|
||||
type="button"
|
||||
bitButton
|
||||
buttonType="primary"
|
||||
(click)="addNewOrganization()"
|
||||
>
|
||||
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
|
||||
{{ "addNewOrganization" | i18n }}
|
||||
</a>
|
||||
@ -34,6 +40,7 @@ const gearIcon = svgIcon`
|
||||
})
|
||||
export class NoClientsComponent {
|
||||
icon = gearIcon;
|
||||
@Input() showAddOrganizationButton = true;
|
||||
@Output() addNewOrganizationClicked = new EventEmitter();
|
||||
|
||||
addNewOrganization = () => this.addNewOrganizationClicked.emit();
|
||||
|
@ -20,7 +20,6 @@ export const hasConsolidatedBilling: CanActivateFn = async (route: ActivatedRout
|
||||
if (
|
||||
!consolidatedBillingEnabled ||
|
||||
!provider ||
|
||||
!provider.isProviderAdmin ||
|
||||
provider.providerStatus !== ProviderStatusType.Billable
|
||||
) {
|
||||
return createUrlTreeFromSnapshot(route, ["/providers", route.params.providerId]);
|
||||
|
@ -10,7 +10,7 @@
|
||||
<ng-container header>
|
||||
<tr>
|
||||
<th bitCell>{{ "date" | i18n }}</th>
|
||||
<th bitCell>{{ "invoiceNumberHeader" | i18n }}</th>
|
||||
<th bitCell>{{ "invoice" | i18n }}</th>
|
||||
<th bitCell>{{ "total" | i18n }}</th>
|
||||
<th bitCell>{{ "status" | i18n }}</th>
|
||||
</tr>
|
||||
@ -29,7 +29,23 @@
|
||||
</a>
|
||||
</td>
|
||||
<td bitCell>{{ invoice.total | currency: "$" }}</td>
|
||||
<td bitCell>{{ invoice.status | titlecase }}</td>
|
||||
<td bitCell *ngIf="expandInvoiceStatus(invoice) as expandedInvoiceStatus">
|
||||
<span *ngIf="expandedInvoiceStatus === 'open'">
|
||||
{{ "open" | i18n | titlecase }}
|
||||
</span>
|
||||
<span *ngIf="expandedInvoiceStatus === 'unpaid'">
|
||||
<i class="bwi bwi-exclamation-circle tw-text-muted" aria-hidden="true"></i>
|
||||
{{ "unpaid" | i18n | titlecase }}
|
||||
</span>
|
||||
<span *ngIf="expandedInvoiceStatus === 'paid'">
|
||||
<i class="bwi bwi-check tw-text-success" aria-hidden="true"></i>
|
||||
{{ "paid" | i18n | titlecase }}
|
||||
</span>
|
||||
<span *ngIf="expandedInvoiceStatus === 'uncollectible'">
|
||||
<i class="bwi bwi-error tw-text-muted" aria-hidden="true"></i>
|
||||
{{ "uncollectible" | i18n | titlecase }}
|
||||
</span>
|
||||
</td>
|
||||
<td bitCell>
|
||||
<button
|
||||
[bitMenuTriggerFor]="rowMenu"
|
||||
|
@ -46,4 +46,19 @@ export class InvoicesComponent implements OnInit {
|
||||
}
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
expandInvoiceStatus = (
|
||||
invoice: InvoiceResponse,
|
||||
): "open" | "unpaid" | "paid" | "uncollectible" => {
|
||||
switch (invoice.status) {
|
||||
case "open": {
|
||||
const dueDate = new Date(invoice.dueDate);
|
||||
return dueDate < new Date() ? "unpaid" : invoice.status;
|
||||
}
|
||||
case "paid":
|
||||
case "uncollectible": {
|
||||
return invoice.status;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import { ConfigService } from "@bitwarden/common/platform/abstractions/config/co
|
||||
|
||||
type MaybeProvider = Provider | undefined;
|
||||
|
||||
export const canAccessBilling = (
|
||||
export const hasConsolidatedBilling = (
|
||||
configService: ConfigService,
|
||||
): OperatorFunction<MaybeProvider, boolean> =>
|
||||
switchMap<MaybeProvider, Observable<boolean>>((provider) =>
|
||||
@ -16,9 +16,7 @@ export const canAccessBilling = (
|
||||
.pipe(
|
||||
map((consolidatedBillingEnabled) =>
|
||||
provider
|
||||
? provider.isProviderAdmin &&
|
||||
provider.providerStatus === ProviderStatusType.Billable &&
|
||||
consolidatedBillingEnabled
|
||||
? provider.providerStatus === ProviderStatusType.Billable && consolidatedBillingEnabled
|
||||
: false,
|
||||
),
|
||||
),
|
||||
|
@ -18,6 +18,7 @@ export class InvoiceResponse extends BaseResponse {
|
||||
number: string;
|
||||
total: number;
|
||||
status: string;
|
||||
dueDate: string;
|
||||
url: string;
|
||||
pdfUrl: string;
|
||||
|
||||
@ -28,6 +29,7 @@ export class InvoiceResponse extends BaseResponse {
|
||||
this.number = this.getResponseProperty("Number");
|
||||
this.total = this.getResponseProperty("Total");
|
||||
this.status = this.getResponseProperty("Status");
|
||||
this.dueDate = this.getResponseProperty("DueDate");
|
||||
this.url = this.getResponseProperty("Url");
|
||||
this.pdfUrl = this.getResponseProperty("PdfUrl");
|
||||
}
|
||||
|
@ -110,9 +110,11 @@ export class PasswordManagerPlanFeaturesResponse extends BaseResponse {
|
||||
// Seats
|
||||
stripePlanId: string;
|
||||
stripeSeatPlanId: string;
|
||||
stripeProviderPortalSeatPlanId: string;
|
||||
stripePremiumAccessPlanId: string;
|
||||
basePrice: number;
|
||||
seatPrice: number;
|
||||
providerPortalSeatPrice: number;
|
||||
premiumAccessOptionPrice: number;
|
||||
baseSeats: number;
|
||||
maxAdditionalSeats: number;
|
||||
@ -134,10 +136,14 @@ export class PasswordManagerPlanFeaturesResponse extends BaseResponse {
|
||||
super(response);
|
||||
this.stripePlanId = this.getResponseProperty("StripePlanId");
|
||||
this.stripeSeatPlanId = this.getResponseProperty("StripeSeatPlanId");
|
||||
this.stripeProviderPortalSeatPlanId = this.getResponseProperty(
|
||||
"StripeProviderPortalSeatPlanId",
|
||||
);
|
||||
this.stripeStoragePlanId = this.getResponseProperty("StripeStoragePlanId");
|
||||
this.stripePremiumAccessPlanId = this.getResponseProperty("StripePremiumAccessPlanId");
|
||||
this.basePrice = this.getResponseProperty("BasePrice");
|
||||
this.seatPrice = this.getResponseProperty("SeatPrice");
|
||||
this.providerPortalSeatPrice = this.getResponseProperty("ProviderPortalSeatPrice");
|
||||
this.baseSeats = this.getResponseProperty("BaseSeats");
|
||||
this.maxAdditionalSeats = this.getResponseProperty("MaxAdditionalSeats");
|
||||
this.premiumAccessOptionPrice = this.getResponseProperty("PremiumAccessOptionPrice");
|
||||
|
212
package-lock.json
generated
212
package-lock.json
generated
@ -29,7 +29,7 @@
|
||||
"@microsoft/signalr": "8.0.0",
|
||||
"@microsoft/signalr-protocol-msgpack": "8.0.0",
|
||||
"@ng-select/ng-select": "11.2.0",
|
||||
"argon2": "0.31.0",
|
||||
"argon2": "0.40.1",
|
||||
"argon2-browser": "1.18.0",
|
||||
"big-integer": "1.6.51",
|
||||
"bootstrap": "4.6.0",
|
||||
@ -67,7 +67,7 @@
|
||||
"qrious": "4.0.2",
|
||||
"rxjs": "7.8.1",
|
||||
"tabbable": "6.2.0",
|
||||
"tldts": "6.1.25",
|
||||
"tldts": "6.1.29",
|
||||
"utf-8-validate": "6.0.3",
|
||||
"zone.js": "0.13.3",
|
||||
"zxcvbn": "4.4.2"
|
||||
@ -206,7 +206,7 @@
|
||||
"dependencies": {
|
||||
"@koa/multer": "3.0.2",
|
||||
"@koa/router": "12.0.1",
|
||||
"argon2": "0.31.0",
|
||||
"argon2": "0.40.1",
|
||||
"big-integer": "1.6.51",
|
||||
"browser-hrtime": "1.1.8",
|
||||
"chalk": "4.1.2",
|
||||
@ -228,7 +228,7 @@
|
||||
"papaparse": "5.4.1",
|
||||
"proper-lockfile": "4.1.2",
|
||||
"rxjs": "7.8.1",
|
||||
"tldts": "6.1.25",
|
||||
"tldts": "6.1.29",
|
||||
"zxcvbn": "4.4.2"
|
||||
},
|
||||
"bin": {
|
||||
@ -6666,90 +6666,6 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@mapbox/node-pre-gyp": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz",
|
||||
"integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==",
|
||||
"dependencies": {
|
||||
"detect-libc": "^2.0.0",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"make-dir": "^3.1.0",
|
||||
"node-fetch": "^2.6.7",
|
||||
"nopt": "^5.0.0",
|
||||
"npmlog": "^5.0.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"semver": "^7.3.5",
|
||||
"tar": "^6.1.11"
|
||||
},
|
||||
"bin": {
|
||||
"node-pre-gyp": "bin/node-pre-gyp"
|
||||
}
|
||||
},
|
||||
"node_modules/@mapbox/node-pre-gyp/node_modules/brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@mapbox/node-pre-gyp/node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@mapbox/node-pre-gyp/node_modules/https-proxy-agent": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
||||
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
|
||||
"dependencies": {
|
||||
"agent-base": "6",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/@mapbox/node-pre-gyp/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@mapbox/node-pre-gyp/node_modules/rimraf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@mdx-js/react": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-2.3.0.tgz",
|
||||
@ -13397,7 +13313,8 @@
|
||||
"node_modules/abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/abort-controller": {
|
||||
"version": "3.0.0",
|
||||
@ -13533,6 +13450,7 @@
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"debug": "4"
|
||||
},
|
||||
@ -13886,7 +13804,8 @@
|
||||
"node_modules/aproba": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
|
||||
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
|
||||
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/archiver": {
|
||||
"version": "5.3.2",
|
||||
@ -14013,18 +13932,6 @@
|
||||
"integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/are-we-there-yet": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz",
|
||||
"integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==",
|
||||
"dependencies": {
|
||||
"delegates": "^1.0.0",
|
||||
"readable-stream": "^3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
|
||||
@ -14032,17 +13939,17 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/argon2": {
|
||||
"version": "0.31.0",
|
||||
"resolved": "https://registry.npmjs.org/argon2/-/argon2-0.31.0.tgz",
|
||||
"integrity": "sha512-r56NWwlE3tjD/FIqL1T+V4Ka+Mb5yMF35w1YWHpwpEjeONXBUbxmjhWkWqY63mse8lpcZ+ZZIGpKL+s+qXhyfg==",
|
||||
"version": "0.40.1",
|
||||
"resolved": "https://registry.npmjs.org/argon2/-/argon2-0.40.1.tgz",
|
||||
"integrity": "sha512-DjtHDwd7pm12qeWyfihHoM8Bn5vGcgH6sKwgPqwNYroRmxlrzadHEvMyuvQxN/V8YSyRRKD5x6ito09q1e9OyA==",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@mapbox/node-pre-gyp": "^1.0.11",
|
||||
"@phc/format": "^1.0.0",
|
||||
"node-addon-api": "^7.0.0"
|
||||
"node-addon-api": "^7.1.0",
|
||||
"node-gyp-build": "^4.8.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
"node": ">=16.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/argon2-browser": {
|
||||
@ -16064,6 +15971,7 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
|
||||
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
@ -16499,6 +16407,7 @@
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
|
||||
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"color-support": "bin.js"
|
||||
}
|
||||
@ -16839,7 +16748,8 @@
|
||||
"node_modules/console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
|
||||
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/constants-browserify": {
|
||||
"version": "1.0.0",
|
||||
@ -17939,6 +17849,7 @@
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
|
||||
"integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@ -21351,6 +21262,7 @@
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minipass": "^3.0.0"
|
||||
},
|
||||
@ -21362,6 +21274,7 @@
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
|
||||
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
@ -21372,7 +21285,8 @@
|
||||
"node_modules/fs-minipass/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fs-mkdirp-stream": {
|
||||
"version": "1.0.0",
|
||||
@ -21487,25 +21401,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/gauge": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz",
|
||||
"integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==",
|
||||
"dependencies": {
|
||||
"aproba": "^1.0.3 || ^2.0.0",
|
||||
"color-support": "^1.1.2",
|
||||
"console-control-strings": "^1.0.0",
|
||||
"has-unicode": "^2.0.1",
|
||||
"object-assign": "^4.1.1",
|
||||
"signal-exit": "^3.0.0",
|
||||
"string-width": "^4.2.3",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wide-align": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/gensync": {
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
@ -23023,7 +22918,8 @@
|
||||
"node_modules/has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
|
||||
"integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/has-value": {
|
||||
"version": "1.0.0",
|
||||
@ -28158,6 +28054,7 @@
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"semver": "^6.0.0"
|
||||
},
|
||||
@ -28172,6 +28069,7 @@
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
@ -29706,6 +29604,7 @@
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
|
||||
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"minipass": "^3.0.0",
|
||||
"yallist": "^4.0.0"
|
||||
@ -29718,6 +29617,7 @@
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
|
||||
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
@ -29728,7 +29628,8 @@
|
||||
"node_modules/minizlib/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/mixin-deep": {
|
||||
"version": "1.3.2",
|
||||
@ -29747,6 +29648,7 @@
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
},
|
||||
@ -30416,20 +30318,6 @@
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
|
||||
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw=="
|
||||
},
|
||||
"node_modules/nopt": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
|
||||
"integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
|
||||
"dependencies": {
|
||||
"abbrev": "1"
|
||||
},
|
||||
"bin": {
|
||||
"nopt": "bin/nopt.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/nord": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/nord/-/nord-0.2.1.tgz",
|
||||
@ -30832,17 +30720,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/npmlog": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
|
||||
"integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==",
|
||||
"dependencies": {
|
||||
"are-we-there-yet": "^2.0.0",
|
||||
"console-control-strings": "^1.1.0",
|
||||
"gauge": "^3.0.0",
|
||||
"set-blocking": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nth-check": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
||||
@ -35284,7 +35161,8 @@
|
||||
"node_modules/set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
|
||||
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/set-cookie-parser": {
|
||||
"version": "2.6.0",
|
||||
@ -36817,6 +36695,7 @@
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
|
||||
"integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chownr": "^2.0.0",
|
||||
"fs-minipass": "^2.0.0",
|
||||
@ -36867,6 +36746,7 @@
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
|
||||
"integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@ -36874,7 +36754,8 @@
|
||||
"node_modules/tar/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/teex": {
|
||||
"version": "1.0.1",
|
||||
@ -37402,21 +37283,21 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tldts": {
|
||||
"version": "6.1.25",
|
||||
"resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.25.tgz",
|
||||
"integrity": "sha512-UmjB1dVArio9hny1D84VFeEvE37nCyfW5sWHr7AUV2MxJgxD8NR/kdmEMyjx5o/kRuOOBbaaXStce2R5C6I1Gg==",
|
||||
"version": "6.1.29",
|
||||
"resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.29.tgz",
|
||||
"integrity": "sha512-6VgFZeuDsC6hrAP+H18CIofrXbA1I7yHsHcMutwK39bEc2fmXrtsLFshV4bg5vza4xiUP4zyAWr9C48KiyxZVA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tldts-core": "^6.1.25"
|
||||
"tldts-core": "^6.1.29"
|
||||
},
|
||||
"bin": {
|
||||
"tldts": "bin/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/tldts-core": {
|
||||
"version": "6.1.25",
|
||||
"resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.25.tgz",
|
||||
"integrity": "sha512-hbSsjJOeDMV91JiqcrrFQ46D7EepH880zVmPjnBDmt3P+h0Aowz8Nh1adIcqkdhJbgpzZYQr6aM8/N3tZC6JyA==",
|
||||
"version": "6.1.29",
|
||||
"resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.29.tgz",
|
||||
"integrity": "sha512-ZhgwrF9P697hrsO8PZ4dFL8UZLLmczYcFwiknsPEk81BTC0xauqQfepPefIfS/YK2z2VVRQmyg0hZujShTlH7A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tmp": {
|
||||
@ -40043,6 +39924,7 @@
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
|
||||
"integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"string-width": "^1.0.2 || 2 || 3 || 4"
|
||||
}
|
||||
|
@ -166,7 +166,7 @@
|
||||
"@microsoft/signalr": "8.0.0",
|
||||
"@microsoft/signalr-protocol-msgpack": "8.0.0",
|
||||
"@ng-select/ng-select": "11.2.0",
|
||||
"argon2": "0.31.0",
|
||||
"argon2": "0.40.1",
|
||||
"argon2-browser": "1.18.0",
|
||||
"big-integer": "1.6.51",
|
||||
"bootstrap": "4.6.0",
|
||||
@ -204,7 +204,7 @@
|
||||
"qrious": "4.0.2",
|
||||
"rxjs": "7.8.1",
|
||||
"tabbable": "6.2.0",
|
||||
"tldts": "6.1.25",
|
||||
"tldts": "6.1.29",
|
||||
"utf-8-validate": "6.0.3",
|
||||
"zone.js": "0.13.3",
|
||||
"zxcvbn": "4.4.2"
|
||||
|
Loading…
Reference in New Issue
Block a user