mirror of
https://github.com/bitwarden/directory-connector
synced 2025-12-10 13:23:18 +00:00
Compare commits
105 Commits
refactor/i
...
ac-1743
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83c521987e | ||
|
|
cd71a7a0ae | ||
|
|
c0bdb67ce9 | ||
|
|
ae8ce6643d | ||
|
|
9e131dc9c8 | ||
|
|
ebe5eaedb2 | ||
|
|
a098620b95 | ||
|
|
d222a26eb6 | ||
|
|
d50e10bb55 | ||
|
|
aca1daa58f | ||
|
|
5bd63c6d90 | ||
|
|
f71f6db0e5 | ||
|
|
8ef50234c8 | ||
|
|
caa846f065 | ||
|
|
6c553a020c | ||
|
|
3c2caf0ef5 | ||
|
|
74b7287ba7 | ||
|
|
48ee5eb4da | ||
|
|
ce80c031db | ||
|
|
0ec615e16b | ||
|
|
3a2f0988a5 | ||
|
|
de4431a559 | ||
|
|
928785493b | ||
|
|
df696ec9d3 | ||
|
|
0debaf1237 | ||
|
|
23f4ef0bd1 | ||
|
|
c8d9a6aed9 | ||
|
|
92fb2be27c | ||
|
|
3dc66d0a9a | ||
|
|
b10ee28bfe | ||
|
|
b3d25a9615 | ||
|
|
9392e513a0 | ||
|
|
57c55d7f3c | ||
|
|
7d04a0d1eb | ||
|
|
9b043c122f | ||
|
|
9a89e95918 | ||
|
|
013c8a5293 | ||
|
|
a5f779c231 | ||
|
|
dd7df6504b | ||
|
|
f064de83e8 | ||
|
|
e27bdbc561 | ||
|
|
93407d061b | ||
|
|
8848edbb40 | ||
|
|
33da38a3f3 | ||
|
|
26e4930a9e | ||
|
|
4dba787df2 | ||
|
|
2e2b5d988c | ||
|
|
d0c126cf3e | ||
|
|
8700332d13 | ||
|
|
0e4f9c0de5 | ||
|
|
c76033b8ad | ||
|
|
50cfc50ed7 | ||
|
|
739ab3d2dd | ||
|
|
1ac402ca06 | ||
|
|
a3c8629f6d | ||
|
|
161c5f82be | ||
|
|
0476c97f5f | ||
|
|
41967d6dc1 | ||
|
|
40908e4b88 | ||
|
|
9e7a11a27c | ||
|
|
a491e2691d | ||
|
|
2c65003cf9 | ||
|
|
0d78b33ae1 | ||
|
|
a3939a31a9 | ||
|
|
3540a2741e | ||
|
|
0ddf81f644 | ||
|
|
83d527a83e | ||
|
|
63b7b9124f | ||
|
|
5d85df2105 | ||
|
|
dbc3c8795d | ||
|
|
f09f7a0e51 | ||
|
|
e3afe9fb69 | ||
|
|
1a6c51b3aa | ||
|
|
107d7afb26 | ||
|
|
0959e58dc9 | ||
|
|
911f9c0dfc | ||
|
|
7cf518edb5 | ||
|
|
4234b3b1cf | ||
|
|
0f5cdd53df | ||
|
|
50bd7ca2b3 | ||
|
|
8531a64568 | ||
|
|
c1cec89995 | ||
|
|
3d214dbedc | ||
|
|
a528480e07 | ||
|
|
af5c863f1f | ||
|
|
365bda7e21 | ||
|
|
f1b533f7b6 | ||
|
|
5bf9b128d4 | ||
|
|
0a8c4d30bb | ||
|
|
1b3f277c1f | ||
|
|
8039f93434 | ||
|
|
d05e8ab7af | ||
|
|
fb3d082b88 | ||
|
|
8541a4252b | ||
|
|
e0d36a7407 | ||
|
|
73b031b884 | ||
|
|
167c5e0108 | ||
|
|
f67f113fe1 | ||
|
|
073126949b | ||
|
|
45d0192f82 | ||
|
|
2d02d54b56 | ||
|
|
8f4da6d490 | ||
|
|
7753749b62 | ||
|
|
c5cc8eab0a | ||
|
|
8981b97632 |
@@ -1,9 +1,8 @@
|
|||||||
dist
|
dist
|
||||||
build
|
build
|
||||||
build-cli
|
build-cli
|
||||||
jslib
|
**/webpack**.config.js
|
||||||
webpack.cli.js
|
|
||||||
webpack.main.js
|
|
||||||
webpack.renderer.js
|
|
||||||
|
|
||||||
**/node_modules
|
**/node_modules
|
||||||
|
|
||||||
|
**/jest.config.js
|
||||||
|
|||||||
@@ -2,10 +2,48 @@
|
|||||||
"root": true,
|
"root": true,
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
|
"webextensions": true,
|
||||||
"node": true
|
"node": true
|
||||||
},
|
},
|
||||||
"extends": ["./jslib/shared/eslintrc.json"],
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": ["*.ts", "*.js"],
|
||||||
|
"plugins": ["@typescript-eslint", "rxjs", "rxjs-angular", "import"],
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"project": ["./tsconfig.json"],
|
||||||
|
"sourceType": "module",
|
||||||
|
"ecmaVersion": 2020
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"plugin:import/recommended",
|
||||||
|
"plugin:import/typescript",
|
||||||
|
"prettier",
|
||||||
|
"plugin:rxjs/recommended"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"import/parsers": {
|
||||||
|
"@typescript-eslint/parser": [".ts"]
|
||||||
|
},
|
||||||
|
"import/resolver": {
|
||||||
|
"typescript": {
|
||||||
|
"alwaysTryTypes": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
|
"@typescript-eslint/explicit-member-accessibility": [
|
||||||
|
"error",
|
||||||
|
{ "accessibility": "no-public" }
|
||||||
|
],
|
||||||
|
"@typescript-eslint/no-explicit-any": "off", // TODO: This should be re-enabled
|
||||||
|
"@typescript-eslint/no-misused-promises": ["error", { "checksVoidReturn": false }],
|
||||||
|
"@typescript-eslint/no-this-alias": ["error", { "allowedNames": ["self"] }],
|
||||||
|
"@typescript-eslint/no-unused-vars": ["error", { "args": "none" }],
|
||||||
|
"no-console": "error",
|
||||||
|
"import/no-unresolved": "off", // TODO: Look into turning off once each package is an actual package.
|
||||||
"import/order": [
|
"import/order": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
@@ -15,7 +53,7 @@
|
|||||||
"newlines-between": "always",
|
"newlines-between": "always",
|
||||||
"pathGroups": [
|
"pathGroups": [
|
||||||
{
|
{
|
||||||
"pattern": "jslib-*/**",
|
"pattern": "@bitwarden/**",
|
||||||
"group": "external",
|
"group": "external",
|
||||||
"position": "after"
|
"position": "after"
|
||||||
},
|
},
|
||||||
@@ -27,6 +65,28 @@
|
|||||||
],
|
],
|
||||||
"pathGroupsExcludedImportTypes": ["builtin"]
|
"pathGroupsExcludedImportTypes": ["builtin"]
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"rxjs-angular/prefer-takeuntil": "error",
|
||||||
|
"rxjs/no-exposed-subjects": ["error", { "allowProtected": true }],
|
||||||
|
"no-restricted-syntax": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"message": "Calling `svgIcon` directly is not allowed",
|
||||||
|
"selector": "CallExpression[callee.name='svgIcon']"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"message": "Accessing FormGroup using `get` is not allowed, use `.value` instead",
|
||||||
|
"selector": "ChainExpression[expression.object.callee.property.name='get'][expression.property.name='value']"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"curly": ["error", "all"],
|
||||||
|
"import/namespace": ["off"], // This doesn't resolve namespace imports correctly, but TS will throw for this anyway
|
||||||
|
"no-restricted-imports": ["error", { "patterns": ["src/**/*"] }]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": ["*.html"],
|
||||||
|
"parser": "@angular-eslint/template-parser"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
15
.github/CODEOWNERS
vendored
Normal file
15
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Please sort into logical groups with comment headers. Sort groups in order of specificity.
|
||||||
|
# For example, default owners should always be the first group.
|
||||||
|
# Sort lines alphabetically within these groups to avoid accidentally adding duplicates.
|
||||||
|
#
|
||||||
|
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
|
||||||
|
|
||||||
|
# Default file owners.
|
||||||
|
* @bitwarden/team-admin-console-dev
|
||||||
|
|
||||||
|
# DevOps for Actions and other workflow changes.
|
||||||
|
.github/workflows @bitwarden/dept-devops
|
||||||
|
.github/secrets @bitwarden/dept-devops
|
||||||
|
|
||||||
|
# Multiple Owners
|
||||||
|
**/package.json
|
||||||
41
.github/renovate.json
vendored
Normal file
41
.github/renovate.json
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": [
|
||||||
|
"config:base",
|
||||||
|
":combinePatchMinorReleases",
|
||||||
|
":dependencyDashboard",
|
||||||
|
":maintainLockFilesWeekly",
|
||||||
|
":pinAllExceptPeerDependencies",
|
||||||
|
":prConcurrentLimit10",
|
||||||
|
":rebaseStalePrs",
|
||||||
|
"schedule:weekends",
|
||||||
|
":separateMajorReleases"
|
||||||
|
],
|
||||||
|
"enabledManagers": ["github-actions", "npm"],
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"groupName": "gh minor",
|
||||||
|
"matchManagers": ["github-actions"],
|
||||||
|
"matchUpdateTypes": ["minor", "patch"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"groupName": "npm minor",
|
||||||
|
"matchManagers": ["npm"],
|
||||||
|
"matchUpdateTypes": ["minor", "patch"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"packageNames": ["typescript"],
|
||||||
|
"matchUpdateTypes": ["major", "minor"],
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"packageNames": ["typescript"],
|
||||||
|
"matchUpdateTypes": "patch"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"groupName": "jest",
|
||||||
|
"packageNames": ["@types/jest", "jest", "ts-jest", "jest-preset-angular"],
|
||||||
|
"matchUpdateTypes": "major"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
188
.github/workflows/build.yml
vendored
188
.github/workflows/build.yml
vendored
@@ -13,10 +13,10 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
cloc:
|
cloc:
|
||||||
name: CLOC
|
name: CLOC
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Set up CLOC
|
- name: Set up CLOC
|
||||||
run: |
|
run: |
|
||||||
@@ -29,38 +29,38 @@ jobs:
|
|||||||
|
|
||||||
setup:
|
setup:
|
||||||
name: Setup
|
name: Setup
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
outputs:
|
outputs:
|
||||||
package_version: ${{ steps.retrieve-version.outputs.package_version }}
|
package_version: ${{ steps.retrieve-version.outputs.package_version }}
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Get Package Version
|
- name: Get Package Version
|
||||||
id: retrieve-version
|
id: retrieve-version
|
||||||
run: |
|
run: |
|
||||||
PKG_VERSION=$(jq -r .version src/package.json)
|
PKG_VERSION=$(jq -r .version package.json)
|
||||||
echo "::set-output name=package_version::$PKG_VERSION"
|
echo "package_version=$PKG_VERSION" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
|
||||||
linux-cli:
|
linux-cli:
|
||||||
name: Build Linux CLI
|
name: Build Linux CLI
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
needs: setup
|
needs: setup
|
||||||
env:
|
env:
|
||||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||||
_PKG_FETCH_NODE_VERSION: 16.13.0
|
_PKG_FETCH_NODE_VERSION: 18.5.0
|
||||||
_PKG_FETCH_VERSION: 3.2
|
_PKG_FETCH_VERSION: 3.4
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@9ced9a43a244f3ac94f13bfd896db8c8f30da67a # v3.0.0
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/package-lock.json'
|
||||||
node-version: '16'
|
node-version: '18'
|
||||||
|
|
||||||
- name: Update NPM
|
- name: Update NPM
|
||||||
run: |
|
run: |
|
||||||
@@ -77,7 +77,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Keytar
|
- name: Keytar
|
||||||
run: |
|
run: |
|
||||||
keytarVersion=$(cat src/package.json | jq -r '.dependencies.keytar')
|
keytarVersion=$(cat package.json | jq -r '.dependencies.keytar')
|
||||||
keytarTar="keytar-v$keytarVersion-napi-v3-linux-x64.tar"
|
keytarTar="keytar-v$keytarVersion-napi-v3-linux-x64.tar"
|
||||||
|
|
||||||
keytarTarGz="$keytarTar.gz"
|
keytarTarGz="$keytarTar.gz"
|
||||||
@@ -94,13 +94,16 @@ jobs:
|
|||||||
run: npm run dist:cli:lin
|
run: npm run dist:cli:lin
|
||||||
|
|
||||||
- name: Zip
|
- name: Zip
|
||||||
run: zip -j ./dist-cli/bwdc-linux-$_PACKAGE_VERSION.zip ./dist-cli/linux/bwdc ./keytar/linux/build/Release/keytar.node
|
run: zip -j dist-cli/bwdc-linux-$_PACKAGE_VERSION.zip dist-cli/linux/bwdc keytar/linux/build/Release/keytar.node
|
||||||
|
|
||||||
- name: Create checksums
|
- name: Create checksums
|
||||||
run: sha256sum ./dist-cli/bwdc-linux-$_PACKAGE_VERSION.zip | cut -d " " -f 1 > ./dist-cli/bwdc-linux-sha256-$_PACKAGE_VERSION.txt
|
run: |
|
||||||
|
shasum -a 256 dist-cli/bwdc-linux-$_PACKAGE_VERSION.zip | \
|
||||||
|
cut -d " " -f 1 > dist-cli/bwdc-linux-sha256-$_PACKAGE_VERSION.txt
|
||||||
|
|
||||||
- name: Version Test
|
- name: Version Test
|
||||||
run: |
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
sudo apt install libsecret-1-0 dbus-x11 gnome-keyring
|
sudo apt install libsecret-1-0 dbus-x11 gnome-keyring
|
||||||
eval $(dbus-launch --sh-syntax)
|
eval $(dbus-launch --sh-syntax)
|
||||||
|
|
||||||
@@ -121,14 +124,14 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Upload Linux Zip to GitHub
|
- name: Upload Linux Zip to GitHub
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: bwdc-linux-${{ env._PACKAGE_VERSION }}.zip
|
name: bwdc-linux-${{ env._PACKAGE_VERSION }}.zip
|
||||||
path: ./dist-cli/bwdc-linux-${{ env._PACKAGE_VERSION }}.zip
|
path: ./dist-cli/bwdc-linux-${{ env._PACKAGE_VERSION }}.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Linux checksum to GitHub
|
- name: Upload Linux checksum to GitHub
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: bwdc-linux-sha256-${{ env._PACKAGE_VERSION }}.txt
|
name: bwdc-linux-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||||
path: ./dist-cli/bwdc-linux-sha256-${{ env._PACKAGE_VERSION }}.txt
|
path: ./dist-cli/bwdc-linux-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||||
@@ -137,22 +140,22 @@ jobs:
|
|||||||
|
|
||||||
macos-cli:
|
macos-cli:
|
||||||
name: Build Mac CLI
|
name: Build Mac CLI
|
||||||
runs-on: macos-11
|
runs-on: macos-12
|
||||||
needs: setup
|
needs: setup
|
||||||
env:
|
env:
|
||||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||||
_PKG_FETCH_NODE_VERSION: 16.13.0
|
_PKG_FETCH_NODE_VERSION: 18.5.0
|
||||||
_PKG_FETCH_VERSION: 3.2
|
_PKG_FETCH_VERSION: 3.4
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@9ced9a43a244f3ac94f13bfd896db8c8f30da67a # v3.0.0
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/package-lock.json'
|
||||||
node-version: '16'
|
node-version: '18'
|
||||||
|
|
||||||
- name: Update NPM
|
- name: Update NPM
|
||||||
run: |
|
run: |
|
||||||
@@ -169,7 +172,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Keytar
|
- name: Keytar
|
||||||
run: |
|
run: |
|
||||||
keytarVersion=$(cat src/package.json | jq -r '.dependencies.keytar')
|
keytarVersion=$(cat package.json | jq -r '.dependencies.keytar')
|
||||||
keytarTar="keytar-v$keytarVersion-napi-v3-darwin-x64.tar"
|
keytarTar="keytar-v$keytarVersion-napi-v3-darwin-x64.tar"
|
||||||
|
|
||||||
keytarTarGz="$keytarTar.gz"
|
keytarTarGz="$keytarTar.gz"
|
||||||
@@ -186,10 +189,12 @@ jobs:
|
|||||||
run: npm run dist:cli:mac
|
run: npm run dist:cli:mac
|
||||||
|
|
||||||
- name: Zip
|
- name: Zip
|
||||||
run: zip -j ./dist-cli/bwdc-macos-$_PACKAGE_VERSION.zip ./dist-cli/macos/bwdc ./keytar/macos/build/Release/keytar.node
|
run: zip -j dist-cli/bwdc-macos-$_PACKAGE_VERSION.zip dist-cli/macos/bwdc keytar/macos/build/Release/keytar.node
|
||||||
|
|
||||||
- name: Create checksums
|
- name: Create checksums
|
||||||
run: sha256sum ./dist-cli/bwdc-macos-$_PACKAGE_VERSION.zip | cut -d " " -f 1 > ./dist-cli/bwdc-macos-sha256-$_PACKAGE_VERSION.txt
|
run: |
|
||||||
|
shasum -a 256 dist-cli/bwdc-macos-$_PACKAGE_VERSION.zip | \
|
||||||
|
cut -d " " -f 1 > dist-cli/bwdc-macos-sha256-$_PACKAGE_VERSION.txt
|
||||||
|
|
||||||
- name: Version Test
|
- name: Version Test
|
||||||
run: |
|
run: |
|
||||||
@@ -207,31 +212,30 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Upload Mac Zip to GitHub
|
- name: Upload Mac Zip to GitHub
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: bwdc-macos-${{ env._PACKAGE_VERSION }}.zip
|
name: bwdc-macos-${{ env._PACKAGE_VERSION }}.zip
|
||||||
path: ./dist-cli/bwdc-macos-${{ env._PACKAGE_VERSION }}.zip
|
path: ./dist-cli/bwdc-macos-${{ env._PACKAGE_VERSION }}.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Mac checksum to GitHub
|
- name: Upload Mac checksum to GitHub
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: bwdc-macos-sha256-${{ env._PACKAGE_VERSION }}.txt
|
name: bwdc-macos-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||||
path: ./dist-cli/bwdc-macos-sha256-${{ env._PACKAGE_VERSION }}.txt
|
path: ./dist-cli/bwdc-macos-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
|
|
||||||
windows-cli:
|
windows-cli:
|
||||||
name: Build Windows CLI
|
name: Build Windows CLI
|
||||||
runs-on: windows-2019
|
runs-on: windows-2022
|
||||||
needs: setup
|
needs: setup
|
||||||
env:
|
env:
|
||||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||||
_WIN_PKG_FETCH_VERSION: 16.13.0
|
_WIN_PKG_FETCH_VERSION: 18.5.0
|
||||||
_WIN_PKG_VERSION: 3.2
|
_WIN_PKG_VERSION: 3.4
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Setup Windows builder
|
- name: Setup Windows builder
|
||||||
run: |
|
run: |
|
||||||
@@ -239,11 +243,11 @@ jobs:
|
|||||||
choco install reshack --no-progress
|
choco install reshack --no-progress
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@9ced9a43a244f3ac94f13bfd896db8c8f30da67a # v3.0.0
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/package-lock.json'
|
||||||
node-version: '16'
|
node-version: '18'
|
||||||
|
|
||||||
- name: Update NPM
|
- name: Update NPM
|
||||||
run: |
|
run: |
|
||||||
@@ -264,7 +268,7 @@ jobs:
|
|||||||
- name: Keytar
|
- name: Keytar
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
$keytarVersion = (Get-Content -Raw -Path ./src/package.json | ConvertFrom-Json).dependencies.keytar
|
$keytarVersion = (Get-Content -Raw -Path ./package.json | ConvertFrom-Json).dependencies.keytar
|
||||||
$keytarTar = "keytar-v${keytarVersion}-napi-v3-{0}-x64.tar"
|
$keytarTar = "keytar-v${keytarVersion}-napi-v3-{0}-x64.tar"
|
||||||
$keytarTarGz = "${keytarTar}.gz"
|
$keytarTarGz = "${keytarTar}.gz"
|
||||||
$keytarUrl = "https://github.com/atom/node-keytar/releases/download/v${keytarVersion}/${keytarTarGz}"
|
$keytarUrl = "https://github.com/atom/node-keytar/releases/download/v${keytarVersion}/${keytarTarGz}"
|
||||||
@@ -333,15 +337,17 @@ jobs:
|
|||||||
|
|
||||||
- name: Zip
|
- name: Zip
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: 7z a ./dist-cli/bwdc-windows-%_PACKAGE_VERSION%.zip ./dist-cli/windows/bwdc.exe ./keytar/windows/keytar.node
|
run: |
|
||||||
|
7z a .\dist-cli\bwdc-windows-%_PACKAGE_VERSION%.zip .\dist-cli\windows\bwdc.exe .\keytar\windows\keytar.node
|
||||||
|
|
||||||
- name: Version Test
|
- name: Version Test
|
||||||
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
Expand-Archive -Path "./dist-cli/bwdc-windows-${env:_PACKAGE_VERSION}.zip" -DestinationPath "./test/windows"
|
Expand-Archive -Path "dist-cli\bwdc-windows-${{ env._PACKAGE_VERSION }}.zip" -DestinationPath "test\windows"
|
||||||
$testVersion = Invoke-Expression '& ./test/windows/bwdc.exe -v'
|
$testVersion = Invoke-Expression '& .\test\windows\bwdc.exe -v'
|
||||||
echo "version: $env:_PACKAGE_VERSION"
|
echo "version: ${env:_PACKAGE_VERSION}"
|
||||||
echo "testVersion: $testVersion"
|
echo "testVersion: $testVersion"
|
||||||
if($testVersion -ne $env:_PACKAGE_VERSION) {
|
if ($testVersion -ne ${env:_PACKAGE_VERSION}) {
|
||||||
Throw "Version test failed."
|
Throw "Version test failed."
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,14 +357,14 @@ jobs:
|
|||||||
-t sha256 | Out-File ./dist-cli/bwdc-windows-sha256-${env:_PACKAGE_VERSION}.txt
|
-t sha256 | Out-File ./dist-cli/bwdc-windows-sha256-${env:_PACKAGE_VERSION}.txt
|
||||||
|
|
||||||
- name: Upload Windows Zip to GitHub
|
- name: Upload Windows Zip to GitHub
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: bwdc-windows-${{ env._PACKAGE_VERSION }}.zip
|
name: bwdc-windows-${{ env._PACKAGE_VERSION }}.zip
|
||||||
path: ./dist-cli/bwdc-windows-${{ env._PACKAGE_VERSION }}.zip
|
path: ./dist-cli/bwdc-windows-${{ env._PACKAGE_VERSION }}.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Windows checksum to GitHub
|
- name: Upload Windows checksum to GitHub
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: bwdc-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
|
name: bwdc-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||||
path: ./dist-cli/bwdc-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
|
path: ./dist-cli/bwdc-windows-sha256-${{ env._PACKAGE_VERSION }}.txt
|
||||||
@@ -367,50 +373,39 @@ jobs:
|
|||||||
|
|
||||||
windows-gui:
|
windows-gui:
|
||||||
name: Build Windows GUI
|
name: Build Windows GUI
|
||||||
runs-on: windows-2019
|
runs-on: windows-2022
|
||||||
needs: setup
|
needs: setup
|
||||||
env:
|
env:
|
||||||
|
NODE_OPTIONS: --max_old_space_size=4096
|
||||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||||
|
HUSKY: 0
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Set up .NET
|
|
||||||
uses: actions/setup-dotnet@9211491ffb35dd6a6657ca4f45d43dfe6e97c829
|
|
||||||
with:
|
|
||||||
dotnet-version: "3.1.x"
|
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@9ced9a43a244f3ac94f13bfd896db8c8f30da67a # v3.0.0
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/package-lock.json'
|
||||||
node-version: '16'
|
node-version: '18'
|
||||||
|
|
||||||
- name: Update NPM
|
- name: Update NPM
|
||||||
run: |
|
run: |
|
||||||
npm install -g node-gyp
|
npm install -g node-gyp
|
||||||
node-gyp install $(node -v)
|
node-gyp install $(node -v)
|
||||||
|
|
||||||
- name: Set Node options
|
|
||||||
run: echo "NODE_OPTIONS=--max_old_space_size=4096" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
|
||||||
shell: pwsh
|
|
||||||
|
|
||||||
- name: Print environment
|
- name: Print environment
|
||||||
run: |
|
run: |
|
||||||
node --version
|
node --version
|
||||||
npm --version
|
npm --version
|
||||||
dotnet --version
|
|
||||||
|
|
||||||
- name: Install AST
|
- name: Install AST
|
||||||
uses: bitwarden/gh-actions/install-ast@f135c42c8596cb535c5bcb7523c0b2eef89709ac
|
run: dotnet tool install --global AzureSignTool --version 4.0.1
|
||||||
|
|
||||||
- name: Install Node dependencies
|
- name: Install Node dependencies
|
||||||
run: npm install
|
run: npm install
|
||||||
|
|
||||||
# - name: Run linter
|
|
||||||
# run: npm run lint
|
|
||||||
|
|
||||||
- name: Build & Sign
|
- name: Build & Sign
|
||||||
run: npm run dist:win
|
run: npm run dist:win
|
||||||
env:
|
env:
|
||||||
@@ -422,28 +417,28 @@ jobs:
|
|||||||
SIGNING_CERT_NAME: ${{ secrets.SIGNING_CERT_NAME }}
|
SIGNING_CERT_NAME: ${{ secrets.SIGNING_CERT_NAME }}
|
||||||
|
|
||||||
- name: Upload Portable Executable to GitHub
|
- name: Upload Portable Executable to GitHub
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-Connector-Portable-${{ env._PACKAGE_VERSION }}.exe
|
name: Bitwarden-Connector-Portable-${{ env._PACKAGE_VERSION }}.exe
|
||||||
path: ./dist/Bitwarden-Connector-Portable-${{ env._PACKAGE_VERSION }}.exe
|
path: ./dist/Bitwarden-Connector-Portable-${{ env._PACKAGE_VERSION }}.exe
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Installer Executable to GitHub
|
- name: Upload Installer Executable to GitHub
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe
|
name: Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe
|
||||||
path: ./dist/Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe
|
path: ./dist/Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload Installer Executable Blockmap to GitHub
|
- name: Upload Installer Executable Blockmap to GitHub
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe.blockmap
|
name: Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe.blockmap
|
||||||
path: ./dist/Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe.blockmap
|
path: ./dist/Bitwarden-Connector-Installer-${{ env._PACKAGE_VERSION }}.exe.blockmap
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload latest auto-update artifact
|
- name: Upload latest auto-update artifact
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: latest.yml
|
name: latest.yml
|
||||||
path: ./dist/latest.yml
|
path: ./dist/latest.yml
|
||||||
@@ -452,29 +447,28 @@ jobs:
|
|||||||
|
|
||||||
linux-gui:
|
linux-gui:
|
||||||
name: Build Linux GUI
|
name: Build Linux GUI
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
needs: setup
|
needs: setup
|
||||||
env:
|
env:
|
||||||
|
NODE_OPTIONS: --max_old_space_size=4096
|
||||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||||
|
HUSKY: 0
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@9ced9a43a244f3ac94f13bfd896db8c8f30da67a # v3.0.0
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/package-lock.json'
|
||||||
node-version: '16'
|
node-version: '18'
|
||||||
|
|
||||||
- name: Update NPM
|
- name: Update NPM
|
||||||
run: |
|
run: |
|
||||||
npm install -g node-gyp
|
npm install -g node-gyp
|
||||||
node-gyp install $(node -v)
|
node-gyp install $(node -v)
|
||||||
|
|
||||||
- name: Set Node options
|
|
||||||
run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Set up environment
|
- name: Set up environment
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
@@ -491,14 +485,14 @@ jobs:
|
|||||||
run: npm run dist:lin
|
run: npm run dist:lin
|
||||||
|
|
||||||
- name: Upload AppImage
|
- name: Upload AppImage
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
|
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
|
||||||
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
|
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-x86_64.AppImage
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload latest auto-update artifact
|
- name: Upload latest auto-update artifact
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: latest-linux.yml
|
name: latest-linux.yml
|
||||||
path: ./dist/latest-linux.yml
|
path: ./dist/latest-linux.yml
|
||||||
@@ -507,29 +501,28 @@ jobs:
|
|||||||
|
|
||||||
macos-gui:
|
macos-gui:
|
||||||
name: Build MacOS GUI
|
name: Build MacOS GUI
|
||||||
runs-on: macos-11
|
runs-on: macos-12
|
||||||
needs: setup
|
needs: setup
|
||||||
env:
|
env:
|
||||||
|
NODE_OPTIONS: --max_old_space_size=4096
|
||||||
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
_PACKAGE_VERSION: ${{ needs.setup.outputs.package_version }}
|
||||||
|
HUSKY: 0
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repo
|
- name: Checkout repo
|
||||||
uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@9ced9a43a244f3ac94f13bfd896db8c8f30da67a # v3.0.0
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
cache-dependency-path: '**/package-lock.json'
|
cache-dependency-path: '**/package-lock.json'
|
||||||
node-version: '16'
|
node-version: '18'
|
||||||
|
|
||||||
- name: Update NPM
|
- name: Update NPM
|
||||||
run: |
|
run: |
|
||||||
npm install -g node-gyp
|
npm install -g node-gyp
|
||||||
node-gyp install $(node -v)
|
node-gyp install $(node -v)
|
||||||
|
|
||||||
- name: Set Node options
|
|
||||||
run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Print environment
|
- name: Print environment
|
||||||
run: |
|
run: |
|
||||||
node --version
|
node --version
|
||||||
@@ -579,7 +572,7 @@ jobs:
|
|||||||
- name: Load package version
|
- name: Load package version
|
||||||
run: |
|
run: |
|
||||||
$rootPath = $env:GITHUB_WORKSPACE;
|
$rootPath = $env:GITHUB_WORKSPACE;
|
||||||
$packageVersion = (Get-Content -Raw -Path $rootPath\src\package.json | ConvertFrom-Json).version;
|
$packageVersion = (Get-Content -Raw -Path $rootPath\package.json | ConvertFrom-Json).version;
|
||||||
|
|
||||||
Write-Output "Setting package version to $packageVersion";
|
Write-Output "Setting package version to $packageVersion";
|
||||||
Write-Output "PACKAGE_VERSION=$packageVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append;
|
Write-Output "PACKAGE_VERSION=$packageVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append;
|
||||||
@@ -588,44 +581,35 @@ jobs:
|
|||||||
- name: Install Node dependencies
|
- name: Install Node dependencies
|
||||||
run: npm install
|
run: npm install
|
||||||
|
|
||||||
# - name: Run linter
|
|
||||||
# run: npm run lint
|
|
||||||
|
|
||||||
- name: Build application
|
- name: Build application
|
||||||
run: npm run dist:mac
|
run: npm run dist:mac
|
||||||
env:
|
env:
|
||||||
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }}
|
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }}
|
||||||
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
|
||||||
|
|
||||||
- name: Rename Zip Artifact
|
|
||||||
run: |
|
|
||||||
cd dist
|
|
||||||
mv "Bitwarden Directory Connector-${{ env._PACKAGE_VERSION }}-mac.zip" \
|
|
||||||
"Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-mac.zip"
|
|
||||||
|
|
||||||
- name: Upload .zip artifact
|
- name: Upload .zip artifact
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-mac.zip
|
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-mac.zip
|
||||||
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-mac.zip
|
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}-mac.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload .dmg artifact
|
- name: Upload .dmg artifact
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg
|
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg
|
||||||
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg
|
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload .dmg Blockmap artifact
|
- name: Upload .dmg Blockmap artifact
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg.blockmap
|
name: Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg.blockmap
|
||||||
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg.blockmap
|
path: ./dist/Bitwarden-Connector-${{ env._PACKAGE_VERSION }}.dmg.blockmap
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
|
|
||||||
- name: Upload latest auto-update artifact
|
- name: Upload latest auto-update artifact
|
||||||
uses: actions/upload-artifact@6673cd052c4cd6fcf4b4e6e60ea986c889389535
|
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||||
with:
|
with:
|
||||||
name: latest-mac.yml
|
name: latest-mac.yml
|
||||||
path: ./dist/latest-mac.yml
|
path: ./dist/latest-mac.yml
|
||||||
@@ -634,7 +618,7 @@ jobs:
|
|||||||
|
|
||||||
check-failures:
|
check-failures:
|
||||||
name: Check for failures
|
name: Check for failures
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
needs:
|
needs:
|
||||||
- cloc
|
- cloc
|
||||||
- setup
|
- setup
|
||||||
@@ -675,22 +659,22 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Login to Azure - Prod Subscription
|
- name: Login to Azure - CI subscription
|
||||||
uses: Azure/login@1f63701bf3e6892515f1b7ce2d2bf1708b46beaf
|
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
|
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||||
|
|
||||||
- name: Retrieve secrets
|
- name: Retrieve secrets
|
||||||
id: retrieve-secrets
|
id: retrieve-secrets
|
||||||
uses: Azure/get-keyvault-secrets@b5c723b9ac7870c022b8c35befe620b7009b336f
|
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||||
if: failure()
|
if: failure()
|
||||||
with:
|
with:
|
||||||
keyvault: "bitwarden-prod-kv"
|
keyvault: "bitwarden-ci"
|
||||||
secrets: "devops-alerts-slack-webhook-url"
|
secrets: "devops-alerts-slack-webhook-url"
|
||||||
|
|
||||||
- name: Notify Slack on failure
|
- name: Notify Slack on failure
|
||||||
uses: act10ns/slack@da3191ebe2e67f49b46880b4633f5591a96d1d33
|
uses: act10ns/slack@ed1309ab9862e57e9e583e51c7889486b9a00b0f # v2.0.0
|
||||||
if: failure()
|
if: failure()
|
||||||
env:
|
env:
|
||||||
SLACK_WEBHOOK_URL: ${{ steps.retrieve-secrets.outputs.devops-alerts-slack-webhook-url }}
|
SLACK_WEBHOOK_URL: ${{ steps.retrieve-secrets.outputs.devops-alerts-slack-webhook-url }}
|
||||||
|
|||||||
4
.github/workflows/enforce-labels.yml
vendored
4
.github/workflows/enforce-labels.yml
vendored
@@ -7,10 +7,10 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
enforce-label:
|
enforce-label:
|
||||||
name: EnforceLabel
|
name: EnforceLabel
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: Enforce Label
|
- name: Enforce Label
|
||||||
uses: yogevbd/enforce-label-action@8d1e1709b1011e6d90400a0e6cf7c0b77aa5efeb
|
uses: yogevbd/enforce-label-action@a3c219da6b8fa73f6ba62b68ff09c469b3a1c024 # 2.2.2
|
||||||
with:
|
with:
|
||||||
BANNED_LABELS: "hold"
|
BANNED_LABELS: "hold"
|
||||||
BANNED_LABELS_DESCRIPTION: "PRs on hold cannot be merged"
|
BANNED_LABELS_DESCRIPTION: "PRs on hold cannot be merged"
|
||||||
|
|||||||
90
.github/workflows/release.yml
vendored
90
.github/workflows/release.yml
vendored
@@ -17,8 +17,13 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
setup:
|
setup:
|
||||||
name: Setup
|
name: Setup
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
|
outputs:
|
||||||
|
release-version: ${{ steps.version.outputs.version }}
|
||||||
steps:
|
steps:
|
||||||
|
- name: Checkout repo
|
||||||
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Branch check
|
- name: Branch check
|
||||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||||
run: |
|
run: |
|
||||||
@@ -29,49 +34,50 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
- name: Checkout repo
|
- name: Check Release Version
|
||||||
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
|
id: version
|
||||||
|
uses: bitwarden/gh-actions/release-version-check@main
|
||||||
|
with:
|
||||||
|
release-type: ${{ github.event.inputs.release_type }}
|
||||||
|
project-type: ts
|
||||||
|
file: package.json
|
||||||
|
|
||||||
- name: Retrieve Directory Connector release version
|
release:
|
||||||
id: retrieve-version
|
name: Release
|
||||||
run: |
|
runs-on: ubuntu-22.04
|
||||||
PKG_VERSION=$(jq -r .version src/package.json)
|
needs: setup
|
||||||
echo "::set-output name=package_version::$PKG_VERSION"
|
steps:
|
||||||
|
- name: Create GitHub deployment
|
||||||
- name: Check to make sure Mobile release version has been bumped
|
uses: chrnorm/deployment-action@d42cde7132fcec920de534fffc3be83794335c00 # v2.0.5
|
||||||
if: ${{ github.event.inputs.release_type == 'Initial Release' }}
|
id: deployment
|
||||||
env:
|
with:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
run: |
|
initial-status: 'in_progress'
|
||||||
latest_ver=$(hub release -L 1 -f '%T')
|
environment: 'production'
|
||||||
latest_ver=${latest_ver:1}
|
description: 'Deployment ${{ needs.setup.outputs.release-version }} from branch ${{ github.ref_name }}'
|
||||||
echo "Latest version: $latest_ver"
|
task: release
|
||||||
ver=${{ steps.retrieve-version.outputs.package_version }}
|
|
||||||
echo "Version: $ver"
|
|
||||||
if [ "$latest_ver" = "$ver" ]; then
|
|
||||||
echo "Version has not been bumped!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Get branch name
|
|
||||||
id: branch
|
|
||||||
run: |
|
|
||||||
BRANCH_NAME=$(basename ${{ github.ref }})
|
|
||||||
echo "::set-output name=branch-name::$BRANCH_NAME"
|
|
||||||
|
|
||||||
- name: Download all artifacts
|
- name: Download all artifacts
|
||||||
uses: bitwarden/gh-actions/download-artifacts@23433be15ed6fd046ce12b6889c5184a8d9c8783
|
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||||
|
uses: bitwarden/gh-actions/download-artifacts@main
|
||||||
with:
|
with:
|
||||||
workflow: build.yml
|
workflow: build.yml
|
||||||
workflow_conclusion: success
|
workflow_conclusion: success
|
||||||
branch: ${{ steps.branch.outputs.branch-name }}
|
branch: ${{ github.ref_name }}
|
||||||
|
|
||||||
|
- name: Download all artifacts
|
||||||
|
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
|
||||||
|
uses: bitwarden/gh-actions/download-artifacts@main
|
||||||
|
with:
|
||||||
|
workflow: build.yml
|
||||||
|
workflow_conclusion: success
|
||||||
|
branch: master
|
||||||
|
|
||||||
- name: Create release
|
- name: Create release
|
||||||
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
|
||||||
uses: ncipollo/release-action@40bb172bd05f266cf9ba4ff965cb61e9ee5f6d01 # v1.9.0
|
uses: ncipollo/release-action@6c75be85e571768fa31b40abf38de58ba0397db5 # v1.13.0
|
||||||
env:
|
env:
|
||||||
PKG_VERSION: ${{ steps.retrieve-version.outputs.package_version }}
|
PKG_VERSION: ${{ needs.setup.outputs.release-version }}
|
||||||
with:
|
with:
|
||||||
artifacts: "./bwdc-windows-${{ env.PKG_VERSION }}.zip,
|
artifacts: "./bwdc-windows-${{ env.PKG_VERSION }}.zip,
|
||||||
./bwdc-macos-${{ env.PKG_VERSION }}.zip,
|
./bwdc-macos-${{ env.PKG_VERSION }}.zip,
|
||||||
@@ -95,3 +101,19 @@ jobs:
|
|||||||
body: "<insert release notes here>"
|
body: "<insert release notes here>"
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
draft: true
|
draft: true
|
||||||
|
|
||||||
|
- name: Update deployment status to Success
|
||||||
|
if: ${{ success() }}
|
||||||
|
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
|
||||||
|
with:
|
||||||
|
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
|
state: 'success'
|
||||||
|
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||||
|
|
||||||
|
- name: Update deployment status to Failure
|
||||||
|
if: ${{ failure() }}
|
||||||
|
uses: chrnorm/deployment-status@2afb7d27101260f4a764219439564d954d10b5b0 # v2.0.1
|
||||||
|
with:
|
||||||
|
token: '${{ secrets.GITHUB_TOKEN }}'
|
||||||
|
state: 'failure'
|
||||||
|
deployment-id: ${{ steps.deployment.outputs.deployment_id }}
|
||||||
|
|||||||
34
.github/workflows/version-bump.yml
vendored
34
.github/workflows/version-bump.yml
vendored
@@ -11,10 +11,30 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
bump_version:
|
bump_version:
|
||||||
name: "Create version_bump_${{ github.event.inputs.version_number }} branch"
|
name: "Create version_bump_${{ github.event.inputs.version_number }} branch"
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Branch
|
- name: Checkout Branch
|
||||||
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
|
- name: Login to Azure - Prod Subscription
|
||||||
|
uses: Azure/login@92a5484dfaf04ca78a94597f4f19fea633851fa2 # v1.4.7
|
||||||
|
with:
|
||||||
|
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}
|
||||||
|
|
||||||
|
- name: Retrieve secrets
|
||||||
|
id: retrieve-secrets
|
||||||
|
uses: bitwarden/gh-actions/get-keyvault-secrets@main
|
||||||
|
with:
|
||||||
|
keyvault: "bitwarden-ci"
|
||||||
|
secrets: "github-gpg-private-key, github-gpg-private-key-passphrase"
|
||||||
|
|
||||||
|
- name: Import GPG key
|
||||||
|
uses: crazy-max/ghaction-import-gpg@82a020f1f7f605c65dd2449b392a52c3fcfef7ef # v6.0.0
|
||||||
|
with:
|
||||||
|
gpg_private_key: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key }}
|
||||||
|
passphrase: ${{ steps.retrieve-secrets.outputs.github-gpg-private-key-passphrase }}
|
||||||
|
git_user_signingkey: true
|
||||||
|
git_commit_gpgsign: true
|
||||||
|
|
||||||
- name: Create Version Branch
|
- name: Create Version Branch
|
||||||
run: |
|
run: |
|
||||||
@@ -22,20 +42,20 @@ jobs:
|
|||||||
git push -u origin version_bump_${{ github.event.inputs.version_number }}
|
git push -u origin version_bump_${{ github.event.inputs.version_number }}
|
||||||
|
|
||||||
- name: Checkout Version Branch
|
- name: Checkout Version Branch
|
||||||
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
|
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
|
||||||
with:
|
with:
|
||||||
ref: version_bump_${{ github.event.inputs.version_number }}
|
ref: version_bump_${{ github.event.inputs.version_number }}
|
||||||
|
|
||||||
- name: Bump Version - Package
|
- name: Bump Version - Package
|
||||||
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
|
uses: bitwarden/gh-actions/version-bump@main
|
||||||
with:
|
with:
|
||||||
version: ${{ github.event.inputs.version_number }}
|
version: ${{ github.event.inputs.version_number }}
|
||||||
file_path: "./src/package.json"
|
file_path: "./package.json"
|
||||||
|
|
||||||
- name: Commit files
|
- name: Commit files
|
||||||
run: |
|
run: |
|
||||||
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
git config --local user.email "106330231+bitwarden-devops-bot@users.noreply.github.com"
|
||||||
git config --local user.name "github-actions[bot]"
|
git config --local user.name "bitwarden-devops-bot"
|
||||||
git commit -m "Bumped version to ${{ github.event.inputs.version_number }}" -a
|
git commit -m "Bumped version to ${{ github.event.inputs.version_number }}" -a
|
||||||
|
|
||||||
- name: Push changes
|
- name: Push changes
|
||||||
|
|||||||
2
.github/workflows/workflow-linter.yml
vendored
2
.github/workflows/workflow-linter.yml
vendored
@@ -8,4 +8,4 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
call-workflow:
|
call-workflow:
|
||||||
uses: bitwarden/gh-actions/.github/workflows/workflow-linter.yml@master
|
uses: bitwarden/gh-actions/.github/workflows/workflow-linter.yml@c970b0fb89bd966749280e832928db62040812bf
|
||||||
|
|||||||
47
.gitignore
vendored
47
.gitignore
vendored
@@ -1,17 +1,40 @@
|
|||||||
.vs
|
# General
|
||||||
.idea
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
.idea/
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# Visual Studio Code
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.history/*
|
||||||
|
|
||||||
|
# Node
|
||||||
node_modules
|
node_modules
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
vwd.webinfo
|
|
||||||
dist/
|
# Build directories
|
||||||
dist-cli/
|
dist
|
||||||
css/
|
build
|
||||||
|
.angular/cache
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
coverage
|
||||||
|
junit.xml
|
||||||
|
|
||||||
|
# Misc
|
||||||
*.crx
|
*.crx
|
||||||
*.pem
|
*.pem
|
||||||
build-cli/
|
*.zip
|
||||||
build/
|
|
||||||
yarn-error.log
|
|
||||||
.DS_Store
|
|
||||||
*.nupkg
|
|
||||||
*.provisionprofile
|
*.provisionprofile
|
||||||
*.env
|
.swp
|
||||||
|
|||||||
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -1,4 +0,0 @@
|
|||||||
[submodule "jslib"]
|
|
||||||
path = jslib
|
|
||||||
url = https://github.com/bitwarden/jslib.git
|
|
||||||
branch = master
|
|
||||||
@@ -3,8 +3,6 @@ build
|
|||||||
build-cli
|
build-cli
|
||||||
dist
|
dist
|
||||||
|
|
||||||
jslib
|
|
||||||
|
|
||||||
# External libraries / auto synced locales
|
# External libraries / auto synced locales
|
||||||
src/locales
|
src/locales
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ We provide detailed documentation and examples for using the Directory Connector
|
|||||||
|
|
||||||
**Requirements**
|
**Requirements**
|
||||||
|
|
||||||
- [Node.js](https://nodejs.org) v16.13.1 (LTS)
|
- [Node.js](https://nodejs.org) v18 (LTS)
|
||||||
- Windows users: To compile the native node modules used in the app you will need the Visual C++ toolset, available through the standard Visual Studio installer (recommended) or by installing [`windows-build-tools`](https://github.com/felixrieseberg/windows-build-tools) through `npm`. See more at [Compiling native Addon modules](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules).
|
- Windows users: To compile the native node modules used in the app you will need the Visual C++ toolset, available through the standard Visual Studio installer (recommended) or by installing [`windows-build-tools`](https://github.com/felixrieseberg/windows-build-tools) through `npm`. See more at [Compiling native Addon modules](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules).
|
||||||
|
|
||||||
**Run the app**
|
**Run the app**
|
||||||
|
|||||||
35
angular.json
Normal file
35
angular.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
|
"version": 1,
|
||||||
|
"newProjectRoot": "apps",
|
||||||
|
"cli": {
|
||||||
|
"analytics": false
|
||||||
|
},
|
||||||
|
"projects": {
|
||||||
|
"app": {
|
||||||
|
"projectType": "application",
|
||||||
|
"schematics": {
|
||||||
|
"@schematics/angular:application": {
|
||||||
|
"strict": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": ".",
|
||||||
|
"sourceRoot": "src",
|
||||||
|
"prefix": "app",
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular-devkit/build-angular:browser",
|
||||||
|
"options": {
|
||||||
|
"outputPath": "dist",
|
||||||
|
"index": "src/index.html",
|
||||||
|
"main": "src/main.ts",
|
||||||
|
"tsConfig": "tsconfig.json",
|
||||||
|
"assets": [],
|
||||||
|
"styles": [],
|
||||||
|
"scripts": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
67
electron-builder.json
Normal file
67
electron-builder.json
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
"extraMetadata": {
|
||||||
|
"name": "bitwarden-directory-connector"
|
||||||
|
},
|
||||||
|
"productName": "Bitwarden Directory Connector",
|
||||||
|
"appId": "com.bitwarden.directory-connector",
|
||||||
|
"copyright": "Copyright © 2015-2022 Bitwarden Inc.",
|
||||||
|
"directories": {
|
||||||
|
"buildResources": "resources",
|
||||||
|
"output": "dist",
|
||||||
|
"app": "build"
|
||||||
|
},
|
||||||
|
"afterSign": "scripts/notarize.js",
|
||||||
|
"mac": {
|
||||||
|
"artifactName": "Bitwarden-Connector-${version}-mac.${ext}",
|
||||||
|
"category": "public.app-category.productivity",
|
||||||
|
"gatekeeperAssess": false,
|
||||||
|
"hardenedRuntime": true,
|
||||||
|
"entitlements": "resources/entitlements.mac.plist",
|
||||||
|
"entitlementsInherit": "resources/entitlements.mac.plist",
|
||||||
|
"target": ["dmg", "zip"]
|
||||||
|
},
|
||||||
|
"win": {
|
||||||
|
"target": ["portable", "nsis"],
|
||||||
|
"sign": "scripts/sign.js"
|
||||||
|
},
|
||||||
|
"linux": {
|
||||||
|
"category": "Utility",
|
||||||
|
"synopsis": "Sync your user directory to your Bitwarden organization.",
|
||||||
|
"target": ["AppImage"]
|
||||||
|
},
|
||||||
|
"dmg": {
|
||||||
|
"artifactName": "Bitwarden-Connector-${version}.${ext}",
|
||||||
|
"icon": "dmg.icns",
|
||||||
|
"contents": [
|
||||||
|
{
|
||||||
|
"x": 150,
|
||||||
|
"y": 185,
|
||||||
|
"type": "file"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 390,
|
||||||
|
"y": 180,
|
||||||
|
"type": "link",
|
||||||
|
"path": "/Applications"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"window": {
|
||||||
|
"width": 540,
|
||||||
|
"height": 380
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nsis": {
|
||||||
|
"oneClick": false,
|
||||||
|
"perMachine": true,
|
||||||
|
"allowToChangeInstallationDirectory": true,
|
||||||
|
"artifactName": "Bitwarden-Connector-Installer-${version}.${ext}",
|
||||||
|
"uninstallDisplayName": "${productName}",
|
||||||
|
"deleteAppDataOnUninstall": true
|
||||||
|
},
|
||||||
|
"portable": {
|
||||||
|
"artifactName": "Bitwarden-Connector-Portable-${version}.${ext}"
|
||||||
|
},
|
||||||
|
"appImage": {
|
||||||
|
"artifactName": "Bitwarden-Connector-${version}-${arch}.${ext}"
|
||||||
|
}
|
||||||
|
}
|
||||||
1
jslib
1
jslib
Submodule jslib deleted from 9950fb42a1
9
jslib/.gitignore
vendored
Normal file
9
jslib/.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
.vs
|
||||||
|
.idea
|
||||||
|
node_modules
|
||||||
|
npm-debug.log
|
||||||
|
vwd.webinfo
|
||||||
|
*.crx
|
||||||
|
*.pem
|
||||||
|
dist
|
||||||
|
coverage
|
||||||
35
jslib/angular/src/components/callout.component.html
Normal file
35
jslib/angular/src/components/callout.component.html
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<div
|
||||||
|
#callout
|
||||||
|
class="callout callout-{{ calloutStyle }}"
|
||||||
|
[ngClass]="{ clickable: clickable }"
|
||||||
|
[attr.role]="useAlertRole ? 'alert' : null"
|
||||||
|
>
|
||||||
|
<h3 class="callout-heading" *ngIf="title">
|
||||||
|
<i class="bwi {{ icon }}" *ngIf="icon" aria-hidden="true"></i>
|
||||||
|
{{ title }}
|
||||||
|
</h3>
|
||||||
|
<div class="enforced-policy-options" *ngIf="enforcedPolicyOptions">
|
||||||
|
{{ enforcedPolicyMessage }}
|
||||||
|
<ul>
|
||||||
|
<li *ngIf="enforcedPolicyOptions?.minComplexity > 0">
|
||||||
|
{{ "policyInEffectMinComplexity" | i18n : getPasswordScoreAlertDisplay() }}
|
||||||
|
</li>
|
||||||
|
<li *ngIf="enforcedPolicyOptions?.minLength > 0">
|
||||||
|
{{ "policyInEffectMinLength" | i18n : enforcedPolicyOptions?.minLength.toString() }}
|
||||||
|
</li>
|
||||||
|
<li *ngIf="enforcedPolicyOptions?.requireUpper">
|
||||||
|
{{ "policyInEffectUppercase" | i18n }}
|
||||||
|
</li>
|
||||||
|
<li *ngIf="enforcedPolicyOptions?.requireLower">
|
||||||
|
{{ "policyInEffectLowercase" | i18n }}
|
||||||
|
</li>
|
||||||
|
<li *ngIf="enforcedPolicyOptions?.requireNumbers">
|
||||||
|
{{ "policyInEffectNumbers" | i18n }}
|
||||||
|
</li>
|
||||||
|
<li *ngIf="enforcedPolicyOptions?.requireSpecial">
|
||||||
|
{{ "policyInEffectSpecial" | i18n : "!@#$%^&*" }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<ng-content></ng-content>
|
||||||
|
</div>
|
||||||
78
jslib/angular/src/components/callout.component.ts
Normal file
78
jslib/angular/src/components/callout.component.ts
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import { Component, Input, OnInit } from "@angular/core";
|
||||||
|
|
||||||
|
import { I18nService } from "@/jslib/common/src/abstractions/i18n.service";
|
||||||
|
import { MasterPasswordPolicyOptions } from "@/jslib/common/src/models/domain/masterPasswordPolicyOptions";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "app-callout",
|
||||||
|
templateUrl: "callout.component.html",
|
||||||
|
})
|
||||||
|
export class CalloutComponent implements OnInit {
|
||||||
|
@Input() type = "info";
|
||||||
|
@Input() icon: string;
|
||||||
|
@Input() title: string;
|
||||||
|
@Input() clickable: boolean;
|
||||||
|
@Input() enforcedPolicyOptions: MasterPasswordPolicyOptions;
|
||||||
|
@Input() enforcedPolicyMessage: string;
|
||||||
|
@Input() useAlertRole = false;
|
||||||
|
|
||||||
|
calloutStyle: string;
|
||||||
|
|
||||||
|
constructor(private i18nService: I18nService) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.calloutStyle = this.type;
|
||||||
|
|
||||||
|
if (this.enforcedPolicyMessage === undefined) {
|
||||||
|
this.enforcedPolicyMessage = this.i18nService.t("masterPasswordPolicyInEffect");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.type === "warning" || this.type === "danger") {
|
||||||
|
if (this.type === "danger") {
|
||||||
|
this.calloutStyle = "danger";
|
||||||
|
}
|
||||||
|
if (this.title === undefined) {
|
||||||
|
this.title = this.i18nService.t("warning");
|
||||||
|
}
|
||||||
|
if (this.icon === undefined) {
|
||||||
|
this.icon = "bwi-exclamation-triangle";
|
||||||
|
}
|
||||||
|
} else if (this.type === "error") {
|
||||||
|
this.calloutStyle = "danger";
|
||||||
|
if (this.title === undefined) {
|
||||||
|
this.title = this.i18nService.t("error");
|
||||||
|
}
|
||||||
|
if (this.icon === undefined) {
|
||||||
|
this.icon = "bwi-error";
|
||||||
|
}
|
||||||
|
} else if (this.type === "tip") {
|
||||||
|
this.calloutStyle = "success";
|
||||||
|
if (this.title === undefined) {
|
||||||
|
this.title = this.i18nService.t("tip");
|
||||||
|
}
|
||||||
|
if (this.icon === undefined) {
|
||||||
|
this.icon = "bwi-lightbulb";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getPasswordScoreAlertDisplay() {
|
||||||
|
if (this.enforcedPolicyOptions == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
let str: string;
|
||||||
|
switch (this.enforcedPolicyOptions.minComplexity) {
|
||||||
|
case 4:
|
||||||
|
str = this.i18nService.t("strong");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
str = this.i18nService.t("good");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
str = this.i18nService.t("weak");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return str + " (" + this.enforcedPolicyOptions.minComplexity + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
63
jslib/angular/src/components/environment.component.ts
Normal file
63
jslib/angular/src/components/environment.component.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import { Directive, EventEmitter, Output } from "@angular/core";
|
||||||
|
|
||||||
|
import { EnvironmentService } from "@/jslib/common/src/abstractions/environment.service";
|
||||||
|
import { I18nService } from "@/jslib/common/src/abstractions/i18n.service";
|
||||||
|
import { PlatformUtilsService } from "@/jslib/common/src/abstractions/platformUtils.service";
|
||||||
|
|
||||||
|
@Directive()
|
||||||
|
export class EnvironmentComponent {
|
||||||
|
@Output() onSaved = new EventEmitter();
|
||||||
|
|
||||||
|
iconsUrl: string;
|
||||||
|
identityUrl: string;
|
||||||
|
apiUrl: string;
|
||||||
|
webVaultUrl: string;
|
||||||
|
notificationsUrl: string;
|
||||||
|
baseUrl: string;
|
||||||
|
showCustom = false;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected platformUtilsService: PlatformUtilsService,
|
||||||
|
protected environmentService: EnvironmentService,
|
||||||
|
protected i18nService: I18nService
|
||||||
|
) {
|
||||||
|
const urls = this.environmentService.getUrls();
|
||||||
|
|
||||||
|
this.baseUrl = urls.base || "";
|
||||||
|
this.webVaultUrl = urls.webVault || "";
|
||||||
|
this.apiUrl = urls.api || "";
|
||||||
|
this.identityUrl = urls.identity || "";
|
||||||
|
this.iconsUrl = urls.icons || "";
|
||||||
|
this.notificationsUrl = urls.notifications || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
async submit() {
|
||||||
|
const resUrls = await this.environmentService.setUrls({
|
||||||
|
base: this.baseUrl,
|
||||||
|
api: this.apiUrl,
|
||||||
|
identity: this.identityUrl,
|
||||||
|
webVault: this.webVaultUrl,
|
||||||
|
icons: this.iconsUrl,
|
||||||
|
notifications: this.notificationsUrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
// re-set urls since service can change them, ex: prefixing https://
|
||||||
|
this.baseUrl = resUrls.base;
|
||||||
|
this.apiUrl = resUrls.api;
|
||||||
|
this.identityUrl = resUrls.identity;
|
||||||
|
this.webVaultUrl = resUrls.webVault;
|
||||||
|
this.iconsUrl = resUrls.icons;
|
||||||
|
this.notificationsUrl = resUrls.notifications;
|
||||||
|
|
||||||
|
this.platformUtilsService.showToast("success", null, this.i18nService.t("environmentSaved"));
|
||||||
|
this.saved();
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleCustom() {
|
||||||
|
this.showCustom = !this.showCustom;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected saved() {
|
||||||
|
this.onSaved.emit();
|
||||||
|
}
|
||||||
|
}
|
||||||
11
jslib/angular/src/components/icon.component.html
Normal file
11
jslib/angular/src/components/icon.component.html
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<div class="icon" aria-hidden="true">
|
||||||
|
<img
|
||||||
|
[src]="image"
|
||||||
|
appFallbackSrc="{{ fallbackImage }}"
|
||||||
|
*ngIf="imageEnabled && image"
|
||||||
|
alt=""
|
||||||
|
decoding="async"
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
<i class="bwi bwi-fw bwi-lg {{ icon }}" *ngIf="!imageEnabled || !image"></i>
|
||||||
|
</div>
|
||||||
112
jslib/angular/src/components/icon.component.ts
Normal file
112
jslib/angular/src/components/icon.component.ts
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
import { Component, Input, OnChanges } from "@angular/core";
|
||||||
|
|
||||||
|
import { EnvironmentService } from "@/jslib/common/src/abstractions/environment.service";
|
||||||
|
import { StateService } from "@/jslib/common/src/abstractions/state.service";
|
||||||
|
import { CipherType } from "@/jslib/common/src/enums/cipherType";
|
||||||
|
import { Utils } from "@/jslib/common/src/misc/utils";
|
||||||
|
import { CipherView } from "@/jslib/common/src/models/view/cipherView";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a mapping from supported card brands to
|
||||||
|
* the filenames of icon that should be present in images/cards folder of clients.
|
||||||
|
*/
|
||||||
|
const cardIcons: Record<string, string> = {
|
||||||
|
Visa: "card-visa",
|
||||||
|
Mastercard: "card-mastercard",
|
||||||
|
Amex: "card-amex",
|
||||||
|
Discover: "card-discover",
|
||||||
|
"Diners Club": "card-diners-club",
|
||||||
|
JCB: "card-jcb",
|
||||||
|
Maestro: "card-maestro",
|
||||||
|
UnionPay: "card-union-pay",
|
||||||
|
};
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "app-vault-icon",
|
||||||
|
templateUrl: "icon.component.html",
|
||||||
|
})
|
||||||
|
export class IconComponent implements OnChanges {
|
||||||
|
@Input() cipher: CipherView;
|
||||||
|
icon: string;
|
||||||
|
image: string;
|
||||||
|
fallbackImage: string;
|
||||||
|
imageEnabled: boolean;
|
||||||
|
|
||||||
|
private iconsUrl: string;
|
||||||
|
|
||||||
|
constructor(environmentService: EnvironmentService, private stateService: StateService) {
|
||||||
|
this.iconsUrl = environmentService.getIconsUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
async ngOnChanges() {
|
||||||
|
// Components may be re-used when using cdk-virtual-scroll. Which puts the component in a weird state,
|
||||||
|
// to avoid this we reset all state variables.
|
||||||
|
this.image = null;
|
||||||
|
this.fallbackImage = null;
|
||||||
|
this.imageEnabled = !(await this.stateService.getDisableFavicon());
|
||||||
|
this.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected load() {
|
||||||
|
switch (this.cipher.type) {
|
||||||
|
case CipherType.Login:
|
||||||
|
this.icon = "bwi-globe";
|
||||||
|
this.setLoginIcon();
|
||||||
|
break;
|
||||||
|
case CipherType.SecureNote:
|
||||||
|
this.icon = "bwi-sticky-note";
|
||||||
|
break;
|
||||||
|
case CipherType.Card:
|
||||||
|
this.icon = "bwi-credit-card";
|
||||||
|
this.setCardIcon();
|
||||||
|
break;
|
||||||
|
case CipherType.Identity:
|
||||||
|
this.icon = "bwi-id-card";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private setLoginIcon() {
|
||||||
|
if (this.cipher.login.uri) {
|
||||||
|
let hostnameUri = this.cipher.login.uri;
|
||||||
|
let isWebsite = false;
|
||||||
|
|
||||||
|
if (hostnameUri.indexOf("androidapp://") === 0) {
|
||||||
|
this.icon = "bwi-android";
|
||||||
|
this.image = null;
|
||||||
|
} else if (hostnameUri.indexOf("iosapp://") === 0) {
|
||||||
|
this.icon = "bwi-apple";
|
||||||
|
this.image = null;
|
||||||
|
} else if (
|
||||||
|
this.imageEnabled &&
|
||||||
|
hostnameUri.indexOf("://") === -1 &&
|
||||||
|
hostnameUri.indexOf(".") > -1
|
||||||
|
) {
|
||||||
|
hostnameUri = "http://" + hostnameUri;
|
||||||
|
isWebsite = true;
|
||||||
|
} else if (this.imageEnabled) {
|
||||||
|
isWebsite = hostnameUri.indexOf("http") === 0 && hostnameUri.indexOf(".") > -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.imageEnabled && isWebsite) {
|
||||||
|
try {
|
||||||
|
this.image = this.iconsUrl + "/" + Utils.getHostname(hostnameUri) + "/icon.png";
|
||||||
|
this.fallbackImage = "images/bwi-globe.png";
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore error since the fallback icon will be shown if image is null.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.image = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private setCardIcon() {
|
||||||
|
const brand = this.cipher.card.brand;
|
||||||
|
if (this.imageEnabled && brand in cardIcons) {
|
||||||
|
this.icon = "credit-card-icon " + cardIcons[brand];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import { ConfigurableFocusTrap, ConfigurableFocusTrapFactory } from "@angular/cdk/a11y";
|
||||||
|
import {
|
||||||
|
AfterViewInit,
|
||||||
|
ChangeDetectorRef,
|
||||||
|
Component,
|
||||||
|
ComponentRef,
|
||||||
|
ElementRef,
|
||||||
|
OnDestroy,
|
||||||
|
Type,
|
||||||
|
ViewChild,
|
||||||
|
ViewContainerRef,
|
||||||
|
} from "@angular/core";
|
||||||
|
|
||||||
|
import { ModalService } from "../../services/modal.service";
|
||||||
|
|
||||||
|
import { ModalRef } from "./modal.ref";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "app-modal",
|
||||||
|
template: "<ng-template #modalContent></ng-template>",
|
||||||
|
})
|
||||||
|
export class DynamicModalComponent implements AfterViewInit, OnDestroy {
|
||||||
|
componentRef: ComponentRef<any>;
|
||||||
|
|
||||||
|
@ViewChild("modalContent", { read: ViewContainerRef, static: true })
|
||||||
|
modalContentRef: ViewContainerRef;
|
||||||
|
|
||||||
|
childComponentType: Type<any>;
|
||||||
|
setComponentParameters: (component: any) => void;
|
||||||
|
|
||||||
|
private focusTrap: ConfigurableFocusTrap;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private modalService: ModalService,
|
||||||
|
private cd: ChangeDetectorRef,
|
||||||
|
private el: ElementRef<HTMLElement>,
|
||||||
|
private focusTrapFactory: ConfigurableFocusTrapFactory,
|
||||||
|
public modalRef: ModalRef
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngAfterViewInit() {
|
||||||
|
this.loadChildComponent(this.childComponentType);
|
||||||
|
if (this.setComponentParameters != null) {
|
||||||
|
this.setComponentParameters(this.componentRef.instance);
|
||||||
|
}
|
||||||
|
this.cd.detectChanges();
|
||||||
|
|
||||||
|
this.modalRef.created(this.el.nativeElement);
|
||||||
|
this.focusTrap = this.focusTrapFactory.create(
|
||||||
|
this.el.nativeElement.querySelector(".modal-dialog")
|
||||||
|
);
|
||||||
|
if (this.el.nativeElement.querySelector("[appAutoFocus]") == null) {
|
||||||
|
this.focusTrap.focusFirstTabbableElementWhenReady();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loadChildComponent(componentType: Type<any>) {
|
||||||
|
const componentFactory = this.modalService.resolveComponentFactory(componentType);
|
||||||
|
|
||||||
|
this.modalContentRef.clear();
|
||||||
|
this.componentRef = this.modalContentRef.createComponent(componentFactory);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
if (this.componentRef) {
|
||||||
|
this.componentRef.destroy();
|
||||||
|
}
|
||||||
|
this.focusTrap.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.modalRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
getFocus() {
|
||||||
|
const autoFocusEl = this.el.nativeElement.querySelector("[appAutoFocus]") as HTMLElement;
|
||||||
|
autoFocusEl?.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
18
jslib/angular/src/components/modal/modal-injector.ts
Normal file
18
jslib/angular/src/components/modal/modal-injector.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { InjectFlags, InjectOptions, Injector, ProviderToken } from "@angular/core";
|
||||||
|
|
||||||
|
export class ModalInjector implements Injector {
|
||||||
|
constructor(private _parentInjector: Injector, private _additionalTokens: WeakMap<any, any>) {}
|
||||||
|
|
||||||
|
get<T>(
|
||||||
|
token: ProviderToken<T>,
|
||||||
|
notFoundValue: undefined,
|
||||||
|
options: InjectOptions & { optional?: false }
|
||||||
|
): T;
|
||||||
|
get<T>(token: ProviderToken<T>, notFoundValue: null, options: InjectOptions): T;
|
||||||
|
get<T>(token: ProviderToken<T>, notFoundValue?: T, options?: InjectOptions | InjectFlags): T;
|
||||||
|
get<T>(token: ProviderToken<T>, notFoundValue?: T, flags?: InjectFlags): T;
|
||||||
|
get(token: any, notFoundValue?: any): any;
|
||||||
|
get(token: any, notFoundValue?: any, flags?: any): any {
|
||||||
|
return this._additionalTokens.get(token) ?? this._parentInjector.get<any>(token, notFoundValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
50
jslib/angular/src/components/modal/modal.ref.ts
Normal file
50
jslib/angular/src/components/modal/modal.ref.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { Observable, Subject } from "rxjs";
|
||||||
|
import { first } from "rxjs/operators";
|
||||||
|
|
||||||
|
export class ModalRef {
|
||||||
|
onCreated: Observable<HTMLElement>; // Modal added to the DOM.
|
||||||
|
onClose: Observable<any>; // Initiated close.
|
||||||
|
onClosed: Observable<any>; // Modal was closed (Remove element from DOM)
|
||||||
|
onShow: Observable<void>; // Start showing modal
|
||||||
|
onShown: Observable<void>; // Modal is fully visible
|
||||||
|
|
||||||
|
private readonly _onCreated = new Subject<HTMLElement>();
|
||||||
|
private readonly _onClose = new Subject<any>();
|
||||||
|
private readonly _onClosed = new Subject<any>();
|
||||||
|
private readonly _onShow = new Subject<void>();
|
||||||
|
private readonly _onShown = new Subject<void>();
|
||||||
|
private lastResult: any;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.onCreated = this._onCreated.asObservable();
|
||||||
|
this.onClose = this._onClose.asObservable();
|
||||||
|
this.onClosed = this._onClosed.asObservable();
|
||||||
|
this.onShow = this._onShow.asObservable();
|
||||||
|
this.onShown = this._onShow.asObservable();
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
this._onShow.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
shown() {
|
||||||
|
this._onShown.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
close(result?: any) {
|
||||||
|
this.lastResult = result;
|
||||||
|
this._onClose.next(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
closed() {
|
||||||
|
this._onClosed.next(this.lastResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
created(el: HTMLElement) {
|
||||||
|
this._onCreated.next(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
onClosedPromise(): Promise<any> {
|
||||||
|
return this.onClosed.pipe(first()).toPromise();
|
||||||
|
}
|
||||||
|
}
|
||||||
42
jslib/angular/src/components/password-reprompt.component.ts
Normal file
42
jslib/angular/src/components/password-reprompt.component.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import { Directive } from "@angular/core";
|
||||||
|
|
||||||
|
import { ModalRef } from "./modal/modal.ref";
|
||||||
|
|
||||||
|
import { CryptoService } from "@/jslib/common/src/abstractions/crypto.service";
|
||||||
|
import { I18nService } from "@/jslib/common/src/abstractions/i18n.service";
|
||||||
|
import { PlatformUtilsService } from "@/jslib/common/src/abstractions/platformUtils.service";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to verify the user's Master Password for the "Master Password Re-prompt" feature only.
|
||||||
|
* See UserVerificationComponent for any other situation where you need to verify the user's identity.
|
||||||
|
*/
|
||||||
|
@Directive()
|
||||||
|
export class PasswordRepromptComponent {
|
||||||
|
showPassword = false;
|
||||||
|
masterPassword = "";
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private modalRef: ModalRef,
|
||||||
|
private cryptoService: CryptoService,
|
||||||
|
private platformUtilsService: PlatformUtilsService,
|
||||||
|
private i18nService: I18nService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
togglePassword() {
|
||||||
|
this.showPassword = !this.showPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
async submit() {
|
||||||
|
if (!(await this.cryptoService.compareAndUpdateKeyHash(this.masterPassword, null))) {
|
||||||
|
this.platformUtilsService.showToast(
|
||||||
|
"error",
|
||||||
|
this.i18nService.t("errorOccurred"),
|
||||||
|
this.i18nService.t("invalidMasterPassword")
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.modalRef.close(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
95
jslib/angular/src/components/toastr.component.ts
Normal file
95
jslib/angular/src/components/toastr.component.ts
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
import { animate, state, style, transition, trigger } from "@angular/animations";
|
||||||
|
import { CommonModule } from "@angular/common";
|
||||||
|
import { Component, ModuleWithProviders, NgModule } from "@angular/core";
|
||||||
|
import {
|
||||||
|
DefaultNoComponentGlobalConfig,
|
||||||
|
GlobalConfig,
|
||||||
|
Toast as BaseToast,
|
||||||
|
ToastPackage,
|
||||||
|
ToastrService,
|
||||||
|
TOAST_CONFIG,
|
||||||
|
} from "ngx-toastr";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: "[toast-component2]",
|
||||||
|
template: `
|
||||||
|
<button
|
||||||
|
*ngIf="options.closeButton"
|
||||||
|
(click)="remove()"
|
||||||
|
type="button"
|
||||||
|
class="toast-close-button"
|
||||||
|
aria-label="Close"
|
||||||
|
>
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
<div class="icon">
|
||||||
|
<i></i>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div *ngIf="title" [class]="options.titleClass" [attr.aria-label]="title">
|
||||||
|
{{ title }} <ng-container *ngIf="duplicatesCount">[{{ duplicatesCount + 1 }}]</ng-container>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
*ngIf="message && options.enableHtml"
|
||||||
|
role="alertdialog"
|
||||||
|
aria-live="polite"
|
||||||
|
[class]="options.messageClass"
|
||||||
|
[innerHTML]="message"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
*ngIf="message && !options.enableHtml"
|
||||||
|
role="alertdialog"
|
||||||
|
aria-live="polite"
|
||||||
|
[class]="options.messageClass"
|
||||||
|
[attr.aria-label]="message"
|
||||||
|
>
|
||||||
|
{{ message }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="options.progressBar">
|
||||||
|
<div class="toast-progress" [style.width]="width + '%'"></div>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
animations: [
|
||||||
|
trigger("flyInOut", [
|
||||||
|
state("inactive", style({ opacity: 0 })),
|
||||||
|
state("active", style({ opacity: 1 })),
|
||||||
|
state("removed", style({ opacity: 0 })),
|
||||||
|
transition("inactive => active", animate("{{ easeTime }}ms {{ easing }}")),
|
||||||
|
transition("active => removed", animate("{{ easeTime }}ms {{ easing }}")),
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
preserveWhitespaces: false,
|
||||||
|
})
|
||||||
|
export class BitwardenToast extends BaseToast {
|
||||||
|
constructor(protected toastrService: ToastrService, public toastPackage: ToastPackage) {
|
||||||
|
super(toastrService, toastPackage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const BitwardenToastGlobalConfig: GlobalConfig = {
|
||||||
|
...DefaultNoComponentGlobalConfig,
|
||||||
|
toastComponent: BitwardenToast,
|
||||||
|
};
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [CommonModule],
|
||||||
|
declarations: [BitwardenToast],
|
||||||
|
exports: [BitwardenToast],
|
||||||
|
})
|
||||||
|
export class BitwardenToastModule {
|
||||||
|
static forRoot(config: Partial<GlobalConfig> = {}): ModuleWithProviders<BitwardenToastModule> {
|
||||||
|
return {
|
||||||
|
ngModule: BitwardenToastModule,
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: TOAST_CONFIG,
|
||||||
|
useValue: {
|
||||||
|
default: BitwardenToastGlobalConfig,
|
||||||
|
config: config,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
23
jslib/angular/src/directives/a11y-title.directive.ts
Normal file
23
jslib/angular/src/directives/a11y-title.directive.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { Directive, ElementRef, Input, Renderer2 } from "@angular/core";
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: "[appA11yTitle]",
|
||||||
|
})
|
||||||
|
export class A11yTitleDirective {
|
||||||
|
@Input() set appA11yTitle(title: string) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
private title: string;
|
||||||
|
|
||||||
|
constructor(private el: ElementRef, private renderer: Renderer2) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
if (!this.el.nativeElement.hasAttribute("title")) {
|
||||||
|
this.renderer.setAttribute(this.el.nativeElement, "title", this.title);
|
||||||
|
}
|
||||||
|
if (!this.el.nativeElement.hasAttribute("aria-label")) {
|
||||||
|
this.renderer.setAttribute(this.el.nativeElement, "aria-label", this.title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
50
jslib/angular/src/directives/api-action.directive.ts
Normal file
50
jslib/angular/src/directives/api-action.directive.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { Directive, ElementRef, Input, OnChanges } from "@angular/core";
|
||||||
|
|
||||||
|
import { ValidationService } from "../services/validation.service";
|
||||||
|
|
||||||
|
import { LogService } from "@/jslib/common/src/abstractions/log.service";
|
||||||
|
import { ErrorResponse } from "@/jslib/common/src/models/response/errorResponse";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides error handling, in particular for any error returned by the server in an api call.
|
||||||
|
* Attach it to a <form> element and provide the name of the class property that will hold the api call promise.
|
||||||
|
* e.g. <form [appApiAction]="this.formPromise">
|
||||||
|
* Any errors/rejections that occur will be intercepted and displayed as error toasts.
|
||||||
|
*/
|
||||||
|
@Directive({
|
||||||
|
selector: "[appApiAction]",
|
||||||
|
})
|
||||||
|
export class ApiActionDirective implements OnChanges {
|
||||||
|
@Input() appApiAction: Promise<any>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private el: ElementRef,
|
||||||
|
private validationService: ValidationService,
|
||||||
|
private logService: LogService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnChanges(changes: any) {
|
||||||
|
if (this.appApiAction == null || this.appApiAction.then == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.el.nativeElement.loading = true;
|
||||||
|
|
||||||
|
this.appApiAction.then(
|
||||||
|
(response: any) => {
|
||||||
|
this.el.nativeElement.loading = false;
|
||||||
|
},
|
||||||
|
(e: any) => {
|
||||||
|
this.el.nativeElement.loading = false;
|
||||||
|
|
||||||
|
if ((e as ErrorResponse).captchaRequired) {
|
||||||
|
this.logService.error("Captcha required error response: " + e.getSingleMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.logService?.error(`Received API exception: ${e}`);
|
||||||
|
this.validationService.showError(e);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
27
jslib/angular/src/directives/autofocus.directive.ts
Normal file
27
jslib/angular/src/directives/autofocus.directive.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { Directive, ElementRef, Input, NgZone } from "@angular/core";
|
||||||
|
import { take } from "rxjs/operators";
|
||||||
|
|
||||||
|
import { Utils } from "@/jslib/common/src/misc/utils";
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: "[appAutofocus]",
|
||||||
|
})
|
||||||
|
export class AutofocusDirective {
|
||||||
|
@Input() set appAutofocus(condition: boolean | string) {
|
||||||
|
this.autofocus = condition === "" || condition === true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private autofocus: boolean;
|
||||||
|
|
||||||
|
constructor(private el: ElementRef, private ngZone: NgZone) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
if (!Utils.isMobileBrowser && this.autofocus) {
|
||||||
|
if (this.ngZone.isStable) {
|
||||||
|
this.el.nativeElement.focus();
|
||||||
|
} else {
|
||||||
|
this.ngZone.onStable.pipe(take(1)).subscribe(() => this.el.nativeElement.focus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
jslib/angular/src/directives/blur-click.directive.ts
Normal file
12
jslib/angular/src/directives/blur-click.directive.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { Directive, ElementRef, HostListener } from "@angular/core";
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: "[appBlurClick]",
|
||||||
|
})
|
||||||
|
export class BlurClickDirective {
|
||||||
|
constructor(private el: ElementRef) {}
|
||||||
|
|
||||||
|
@HostListener("click") onClick() {
|
||||||
|
this.el.nativeElement.blur();
|
||||||
|
}
|
||||||
|
}
|
||||||
59
jslib/angular/src/directives/box-row.directive.ts
Normal file
59
jslib/angular/src/directives/box-row.directive.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { Directive, ElementRef, HostListener, OnInit } from "@angular/core";
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: "[appBoxRow]",
|
||||||
|
})
|
||||||
|
export class BoxRowDirective implements OnInit {
|
||||||
|
el: HTMLElement = null;
|
||||||
|
formEls: Element[];
|
||||||
|
|
||||||
|
constructor(elRef: ElementRef) {
|
||||||
|
this.el = elRef.nativeElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.formEls = Array.from(
|
||||||
|
this.el.querySelectorAll('input:not([type="hidden"]), select, textarea')
|
||||||
|
);
|
||||||
|
this.formEls.forEach((formEl) => {
|
||||||
|
formEl.addEventListener(
|
||||||
|
"focus",
|
||||||
|
() => {
|
||||||
|
this.el.classList.add("active");
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
formEl.addEventListener(
|
||||||
|
"blur",
|
||||||
|
() => {
|
||||||
|
this.el.classList.remove("active");
|
||||||
|
},
|
||||||
|
false
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@HostListener("click", ["$event"]) onClick(event: Event) {
|
||||||
|
const target = event.target as HTMLElement;
|
||||||
|
if (
|
||||||
|
target !== this.el &&
|
||||||
|
!target.classList.contains("progress") &&
|
||||||
|
!target.classList.contains("progress-bar")
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.formEls.length > 0) {
|
||||||
|
const formEl = this.formEls[0] as HTMLElement;
|
||||||
|
if (formEl.tagName.toLowerCase() === "input") {
|
||||||
|
const inputEl = formEl as HTMLInputElement;
|
||||||
|
if (inputEl.type != null && inputEl.type.toLowerCase() === "checkbox") {
|
||||||
|
inputEl.click();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
formEl.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
jslib/angular/src/directives/fallback-src.directive.ts
Normal file
14
jslib/angular/src/directives/fallback-src.directive.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { Directive, ElementRef, HostListener, Input } from "@angular/core";
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: "[appFallbackSrc]",
|
||||||
|
})
|
||||||
|
export class FallbackSrcDirective {
|
||||||
|
@Input("appFallbackSrc") appFallbackSrc: string;
|
||||||
|
|
||||||
|
constructor(private el: ElementRef) {}
|
||||||
|
|
||||||
|
@HostListener("error") onError() {
|
||||||
|
this.el.nativeElement.src = this.appFallbackSrc;
|
||||||
|
}
|
||||||
|
}
|
||||||
10
jslib/angular/src/directives/stop-click.directive.ts
Normal file
10
jslib/angular/src/directives/stop-click.directive.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { Directive, HostListener } from "@angular/core";
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: "[appStopClick]",
|
||||||
|
})
|
||||||
|
export class StopClickDirective {
|
||||||
|
@HostListener("click", ["$event"]) onClick($event: MouseEvent) {
|
||||||
|
$event.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
10
jslib/angular/src/directives/stop-prop.directive.ts
Normal file
10
jslib/angular/src/directives/stop-prop.directive.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { Directive, HostListener } from "@angular/core";
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: "[appStopProp]",
|
||||||
|
})
|
||||||
|
export class StopPropDirective {
|
||||||
|
@HostListener("click", ["$event"]) onClick($event: MouseEvent) {
|
||||||
|
$event.stopPropagation();
|
||||||
|
}
|
||||||
|
}
|
||||||
14
jslib/angular/src/pipes/i18n.pipe.ts
Normal file
14
jslib/angular/src/pipes/i18n.pipe.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { Pipe, PipeTransform } from "@angular/core";
|
||||||
|
|
||||||
|
import { I18nService } from "@/jslib/common/src/abstractions/i18n.service";
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: "i18n",
|
||||||
|
})
|
||||||
|
export class I18nPipe implements PipeTransform {
|
||||||
|
constructor(private i18nService: I18nService) {}
|
||||||
|
|
||||||
|
transform(id: string, p1?: string, p2?: string, p3?: string): string {
|
||||||
|
return this.i18nService.t(id, p1, p2, p3);
|
||||||
|
}
|
||||||
|
}
|
||||||
41
jslib/angular/src/pipes/search-ciphers.pipe.ts
Normal file
41
jslib/angular/src/pipes/search-ciphers.pipe.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { Pipe, PipeTransform } from "@angular/core";
|
||||||
|
|
||||||
|
import { CipherView } from "@/jslib/common/src/models/view/cipherView";
|
||||||
|
|
||||||
|
@Pipe({
|
||||||
|
name: "searchCiphers",
|
||||||
|
})
|
||||||
|
export class SearchCiphersPipe implements PipeTransform {
|
||||||
|
transform(ciphers: CipherView[], searchText: string, deleted = false): CipherView[] {
|
||||||
|
if (ciphers == null || ciphers.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchText == null || searchText.length < 2) {
|
||||||
|
return ciphers.filter((c) => {
|
||||||
|
return deleted !== c.isDeleted;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
searchText = searchText.trim().toLowerCase();
|
||||||
|
return ciphers.filter((c) => {
|
||||||
|
if (deleted !== c.isDeleted) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c.name != null && c.name.toLowerCase().indexOf(searchText) > -1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (searchText.length >= 8 && c.id.startsWith(searchText)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (c.subTitle != null && c.subTitle.toLowerCase().indexOf(searchText) > -1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (c.login && c.login.uri != null && c.login.uri.toLowerCase().indexOf(searchText) > -1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
170
jslib/angular/src/scss/bwicons/fonts/bwi-font.svg
Normal file
170
jslib/angular/src/scss/bwicons/fonts/bwi-font.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 262 KiB |
BIN
jslib/angular/src/scss/bwicons/fonts/bwi-font.ttf
Normal file
BIN
jslib/angular/src/scss/bwicons/fonts/bwi-font.ttf
Normal file
Binary file not shown.
BIN
jslib/angular/src/scss/bwicons/fonts/bwi-font.woff
Normal file
BIN
jslib/angular/src/scss/bwicons/fonts/bwi-font.woff
Normal file
Binary file not shown.
BIN
jslib/angular/src/scss/bwicons/fonts/bwi-font.woff2
Normal file
BIN
jslib/angular/src/scss/bwicons/fonts/bwi-font.woff2
Normal file
Binary file not shown.
250
jslib/angular/src/scss/bwicons/styles/style.scss
Normal file
250
jslib/angular/src/scss/bwicons/styles/style.scss
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
$icomoon-font-family: "bwi-font" !default;
|
||||||
|
$icomoon-font-path: "/jslib/angular/src/scss/bwicons/fonts/" !default;
|
||||||
|
|
||||||
|
// New font sheet? Update the font-face information below
|
||||||
|
@font-face {
|
||||||
|
font-family: "#{$icomoon-font-family}";
|
||||||
|
src: url($icomoon-font-path + "bwi-font.svg") format("svg"),
|
||||||
|
url($icomoon-font-path + "bwi-font.ttf") format("truetype"),
|
||||||
|
url($icomoon-font-path + "bwi-font.woff") format("woff"),
|
||||||
|
url($icomoon-font-path + "bwi-font.woff2") format("woff2");
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Base Class
|
||||||
|
.bwi {
|
||||||
|
/* use !important to prevent issues with browser extensions that change fonts */
|
||||||
|
font-family: "#{$icomoon-font-family}" !important;
|
||||||
|
speak: never;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
font-variant: normal;
|
||||||
|
text-transform: none;
|
||||||
|
line-height: 1;
|
||||||
|
display: inline-block;
|
||||||
|
/* Better Font Rendering */
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fixed Width Icons
|
||||||
|
.bwi-fw {
|
||||||
|
width: calc(18em / 14);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sizing Changes
|
||||||
|
.bwi-sm {
|
||||||
|
font-size: 0.875em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bwi-lg {
|
||||||
|
font-size: calc(4em / 3);
|
||||||
|
line-height: calc(3em / 4);
|
||||||
|
vertical-align: -15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bwi-2x {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bwi-3x {
|
||||||
|
font-size: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bwi-4x {
|
||||||
|
font-size: 4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spin Animations
|
||||||
|
.bwi-spin {
|
||||||
|
animation: bwi-spin 2s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes bwi-spin {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(359deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// List Icons
|
||||||
|
.bwi-ul {
|
||||||
|
padding-left: 0;
|
||||||
|
margin-left: calc(30em / 14);
|
||||||
|
list-style-type: none;
|
||||||
|
> li {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bwi-li {
|
||||||
|
position: absolute;
|
||||||
|
left: calc(-30em / 14);
|
||||||
|
width: calc(30em / 14);
|
||||||
|
top: calc(2em / 14);
|
||||||
|
text-align: center;
|
||||||
|
&.bwi-lg {
|
||||||
|
left: calc(-30em / 14) + calc(4em / 14);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotation
|
||||||
|
.bwi-rotate-270 {
|
||||||
|
transform: rotate(270deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For new icons - add their glyph name and value to the map below
|
||||||
|
$icons: (
|
||||||
|
"save-changes": "\e988",
|
||||||
|
"browser": "\e985",
|
||||||
|
"mobile": "\e986",
|
||||||
|
"cli": "\e987",
|
||||||
|
"providers": "\e983",
|
||||||
|
"vault": "\e984",
|
||||||
|
"folder-closed-f": "\e982",
|
||||||
|
"rocket": "\e9ee",
|
||||||
|
"ellipsis-h": "\e9ef",
|
||||||
|
"ellipsis-v": "\e9f0",
|
||||||
|
"safari": "\e974",
|
||||||
|
"opera": "\e975",
|
||||||
|
"firefox": "\e976",
|
||||||
|
"edge": "\e977",
|
||||||
|
"chrome": "\e978",
|
||||||
|
"star-f": "\e979",
|
||||||
|
"arrow-circle-up": "\e97a",
|
||||||
|
"arrow-circle-right": "\e97b",
|
||||||
|
"arrow-circle-left": "\e97c",
|
||||||
|
"arrow-circle-down": "\e97d",
|
||||||
|
"undo": "\e97e",
|
||||||
|
"bolt": "\e97f",
|
||||||
|
"puzzle": "\e980",
|
||||||
|
"rss": "\e973",
|
||||||
|
"dbl-angle-left": "\e970",
|
||||||
|
"dbl-angle-right": "\e971",
|
||||||
|
"hamburger": "\e972",
|
||||||
|
"bw-folder-open-f": "\e93e",
|
||||||
|
"desktop": "\e96a",
|
||||||
|
"angle-left": "\e96b",
|
||||||
|
"user": "\e900",
|
||||||
|
"user-f": "\e901",
|
||||||
|
"key": "\e902",
|
||||||
|
"share-square": "\e903",
|
||||||
|
"hashtag": "\e904",
|
||||||
|
"clone": "\e905",
|
||||||
|
"list-alt": "\e906",
|
||||||
|
"id-card": "\e907",
|
||||||
|
"credit-card": "\e908",
|
||||||
|
"globe": "\e909",
|
||||||
|
"sticky-note": "\e90a",
|
||||||
|
"folder": "\e90b",
|
||||||
|
"lock": "\e90c",
|
||||||
|
"lock-f": "\e90d",
|
||||||
|
"generate": "\e90e",
|
||||||
|
"generate-f": "\e90f",
|
||||||
|
"cog": "\e910",
|
||||||
|
"cog-f": "\e911",
|
||||||
|
"check-circle": "\e912",
|
||||||
|
"eye": "\e913",
|
||||||
|
"pencil-square": "\e914",
|
||||||
|
"bookmark": "\e915",
|
||||||
|
"files": "\e916",
|
||||||
|
"trash": "\e917",
|
||||||
|
"plus": "\e918",
|
||||||
|
"star": "\e919",
|
||||||
|
"list": "\e91a",
|
||||||
|
"angle-right": "\e91b",
|
||||||
|
"external-link": "\e91c",
|
||||||
|
"refresh": "\e91d",
|
||||||
|
"search": "\e91f",
|
||||||
|
"filter": "\e920",
|
||||||
|
"plus-circle": "\e921",
|
||||||
|
"user-circle": "\e922",
|
||||||
|
"question-circle": "\e923",
|
||||||
|
"cogs": "\e924",
|
||||||
|
"minus-circle": "\e925",
|
||||||
|
"send": "\e926",
|
||||||
|
"send-f": "\e927",
|
||||||
|
"download": "\e928",
|
||||||
|
"pencil": "\e929",
|
||||||
|
"sign-out": "\e92a",
|
||||||
|
"share": "\e92b",
|
||||||
|
"clock": "\e92c",
|
||||||
|
"angle-down": "\e92d",
|
||||||
|
"caret-down": "\e92e",
|
||||||
|
"square": "\e92f",
|
||||||
|
"collection": "\e930",
|
||||||
|
"bank": "\e931",
|
||||||
|
"shield": "\e932",
|
||||||
|
"stop": "\e933",
|
||||||
|
"plus-square": "\e934",
|
||||||
|
"save": "\e935",
|
||||||
|
"sign-in": "\e936",
|
||||||
|
"spinner": "\e937",
|
||||||
|
"dollar": "\e939",
|
||||||
|
"check": "\e93a",
|
||||||
|
"check-square": "\e93b",
|
||||||
|
"minus-square": "\e93c",
|
||||||
|
"close": "\e93d",
|
||||||
|
"share-arrow": "\e96c",
|
||||||
|
"paperclip": "\e93f",
|
||||||
|
"bitcoin": "\e940",
|
||||||
|
"cut": "\e941",
|
||||||
|
"frown": "\e942",
|
||||||
|
"folder-open": "\e943",
|
||||||
|
"bug": "\e946",
|
||||||
|
"chain-broken": "\e947",
|
||||||
|
"dashboard": "\e948",
|
||||||
|
"envelope": "\e949",
|
||||||
|
"exclamation-circle": "\e94a",
|
||||||
|
"exclamation-triangle": "\e94b",
|
||||||
|
"caret-right": "\e94c",
|
||||||
|
"file-pdf": "\e94e",
|
||||||
|
"file-text": "\e94f",
|
||||||
|
"info-circle": "\e952",
|
||||||
|
"lightbulb": "\e953",
|
||||||
|
"link": "\e954",
|
||||||
|
"linux": "\e956",
|
||||||
|
"long-arrow-right": "\e957",
|
||||||
|
"money": "\e958",
|
||||||
|
"play": "\e959",
|
||||||
|
"reddit": "\e95a",
|
||||||
|
"refresh-tab": "\e95b",
|
||||||
|
"sitemap": "\e95c",
|
||||||
|
"sliders": "\e95d",
|
||||||
|
"tag": "\e95e",
|
||||||
|
"thumb-tack": "\e95f",
|
||||||
|
"thumbs-up": "\e960",
|
||||||
|
"unlock": "\e962",
|
||||||
|
"users": "\e963",
|
||||||
|
"wrench": "\e965",
|
||||||
|
"ban": "\e967",
|
||||||
|
"camera": "\e968",
|
||||||
|
"chevron-up": "\e969",
|
||||||
|
"eye-slash": "\e96d",
|
||||||
|
"file": "\e96e",
|
||||||
|
"paste": "\e96f",
|
||||||
|
"github": "\e950",
|
||||||
|
"facebook": "\e94d",
|
||||||
|
"paypal": "\e938",
|
||||||
|
"google": "\e951",
|
||||||
|
"linkedin": "\e955",
|
||||||
|
"discourse": "\e91e",
|
||||||
|
"twitter": "\e961",
|
||||||
|
"youtube": "\e966",
|
||||||
|
"windows": "\e964",
|
||||||
|
"apple": "\e945",
|
||||||
|
"android": "\e944",
|
||||||
|
"error": "\e981",
|
||||||
|
"numbered-list": "\e989",
|
||||||
|
);
|
||||||
|
|
||||||
|
@each $name, $glyph in $icons {
|
||||||
|
.bwi-#{$name}:before {
|
||||||
|
content: $glyph;
|
||||||
|
}
|
||||||
|
}
|
||||||
44
jslib/angular/src/scss/icons.scss
Normal file
44
jslib/angular/src/scss/icons.scss
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
$card-icons-base: "~@bitwarden/jslib-angular/src/images/cards/";
|
||||||
|
$card-icons: (
|
||||||
|
"visa": $card-icons-base + "visa-light.png",
|
||||||
|
"amex": $card-icons-base + "amex-light.png",
|
||||||
|
"diners-club": $card-icons-base + "diners_club-light.png",
|
||||||
|
"discover": $card-icons-base + "discover-light.png",
|
||||||
|
"jcb": $card-icons-base + "jcb-light.png",
|
||||||
|
"maestro": $card-icons-base + "maestro-light.png",
|
||||||
|
"mastercard": $card-icons-base + "mastercard-light.png",
|
||||||
|
"union-pay": $card-icons-base + "union_pay-light.png",
|
||||||
|
);
|
||||||
|
|
||||||
|
$card-icons-dark: (
|
||||||
|
"visa": $card-icons-base + "visa-dark.png",
|
||||||
|
"amex": $card-icons-base + "amex-dark.png",
|
||||||
|
"diners-club": $card-icons-base + "diners_club-dark.png",
|
||||||
|
"discover": $card-icons-base + "discover-dark.png",
|
||||||
|
"jcb": $card-icons-base + "jcb-dark.png",
|
||||||
|
"maestro": $card-icons-base + "maestro-dark.png",
|
||||||
|
"mastercard": $card-icons-base + "mastercard-dark.png",
|
||||||
|
"union-pay": $card-icons-base + "union_pay-dark.png",
|
||||||
|
);
|
||||||
|
|
||||||
|
.credit-card-icon {
|
||||||
|
display: block; // Resolves the parent container being slighly to big
|
||||||
|
height: 19px;
|
||||||
|
width: 24px;
|
||||||
|
background-size: contain;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $name, $url in $card-icons {
|
||||||
|
.card-#{$name} {
|
||||||
|
background-image: url("#{$url}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $theme in $dark-icon-themes {
|
||||||
|
@each $name, $url in $card-icons-dark {
|
||||||
|
.#{$theme} .card-#{$name} {
|
||||||
|
background-image: url("#{$url}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
89
jslib/angular/src/scss/webfonts.css
Normal file
89
jslib/angular/src/scss/webfonts.css
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: auto;
|
||||||
|
src: url(webfonts/Open_Sans-italic-300.woff) format("woff");
|
||||||
|
unicode-range: U+0-10FFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: auto;
|
||||||
|
src: url(webfonts/Open_Sans-italic-400.woff) format("woff");
|
||||||
|
unicode-range: U+0-10FFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: auto;
|
||||||
|
src: url(webfonts/Open_Sans-italic-600.woff) format("woff");
|
||||||
|
unicode-range: U+0-10FFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: auto;
|
||||||
|
src: url(webfonts/Open_Sans-italic-700.woff) format("woff");
|
||||||
|
unicode-range: U+0-10FFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 800;
|
||||||
|
font-display: auto;
|
||||||
|
src: url(webfonts/Open_Sans-italic-800.woff) format("woff");
|
||||||
|
unicode-range: U+0-10FFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
font-display: auto;
|
||||||
|
src: url(webfonts/Open_Sans-normal-300.woff) format("woff");
|
||||||
|
unicode-range: U+0-10FFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
font-display: auto;
|
||||||
|
src: url(webfonts/Open_Sans-normal-400.woff) format("woff");
|
||||||
|
unicode-range: U+0-10FFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
font-display: auto;
|
||||||
|
src: url(webfonts/Open_Sans-normal-600.woff) format("woff");
|
||||||
|
unicode-range: U+0-10FFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
font-display: auto;
|
||||||
|
src: url(webfonts/Open_Sans-normal-700.woff) format("woff");
|
||||||
|
unicode-range: U+0-10FFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "Open Sans";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 800;
|
||||||
|
font-display: auto;
|
||||||
|
src: url(webfonts/Open_Sans-normal-800.woff) format("woff");
|
||||||
|
unicode-range: U+0-10FFFF;
|
||||||
|
}
|
||||||
BIN
jslib/angular/src/scss/webfonts/Open_Sans-italic-300.woff
Normal file
BIN
jslib/angular/src/scss/webfonts/Open_Sans-italic-300.woff
Normal file
Binary file not shown.
BIN
jslib/angular/src/scss/webfonts/Open_Sans-italic-400.woff
Normal file
BIN
jslib/angular/src/scss/webfonts/Open_Sans-italic-400.woff
Normal file
Binary file not shown.
BIN
jslib/angular/src/scss/webfonts/Open_Sans-italic-600.woff
Normal file
BIN
jslib/angular/src/scss/webfonts/Open_Sans-italic-600.woff
Normal file
Binary file not shown.
BIN
jslib/angular/src/scss/webfonts/Open_Sans-italic-700.woff
Normal file
BIN
jslib/angular/src/scss/webfonts/Open_Sans-italic-700.woff
Normal file
Binary file not shown.
BIN
jslib/angular/src/scss/webfonts/Open_Sans-italic-800.woff
Normal file
BIN
jslib/angular/src/scss/webfonts/Open_Sans-italic-800.woff
Normal file
Binary file not shown.
BIN
jslib/angular/src/scss/webfonts/Open_Sans-normal-300.woff
Normal file
BIN
jslib/angular/src/scss/webfonts/Open_Sans-normal-300.woff
Normal file
Binary file not shown.
BIN
jslib/angular/src/scss/webfonts/Open_Sans-normal-400.woff
Normal file
BIN
jslib/angular/src/scss/webfonts/Open_Sans-normal-400.woff
Normal file
Binary file not shown.
BIN
jslib/angular/src/scss/webfonts/Open_Sans-normal-600.woff
Normal file
BIN
jslib/angular/src/scss/webfonts/Open_Sans-normal-600.woff
Normal file
Binary file not shown.
BIN
jslib/angular/src/scss/webfonts/Open_Sans-normal-700.woff
Normal file
BIN
jslib/angular/src/scss/webfonts/Open_Sans-normal-700.woff
Normal file
Binary file not shown.
BIN
jslib/angular/src/scss/webfonts/Open_Sans-normal-800.woff
Normal file
BIN
jslib/angular/src/scss/webfonts/Open_Sans-normal-800.woff
Normal file
Binary file not shown.
45
jslib/angular/src/services/auth-guard.service.ts
Normal file
45
jslib/angular/src/services/auth-guard.service.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from "@angular/router";
|
||||||
|
|
||||||
|
import { KeyConnectorService } from "@/jslib/common/src/abstractions/keyConnector.service";
|
||||||
|
import { MessagingService } from "@/jslib/common/src/abstractions/messaging.service";
|
||||||
|
import { StateService } from "@/jslib/common/src/abstractions/state.service";
|
||||||
|
import { VaultTimeoutService } from "@/jslib/common/src/abstractions/vaultTimeout.service";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AuthGuardService {
|
||||||
|
constructor(
|
||||||
|
private vaultTimeoutService: VaultTimeoutService,
|
||||||
|
private router: Router,
|
||||||
|
private messagingService: MessagingService,
|
||||||
|
private keyConnectorService: KeyConnectorService,
|
||||||
|
private stateService: StateService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async canActivate(route: ActivatedRouteSnapshot, routerState: RouterStateSnapshot) {
|
||||||
|
const isAuthed = await this.stateService.getIsAuthenticated();
|
||||||
|
if (!isAuthed) {
|
||||||
|
this.messagingService.send("authBlocked");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const locked = await this.vaultTimeoutService.isLocked();
|
||||||
|
if (locked) {
|
||||||
|
if (routerState != null) {
|
||||||
|
this.messagingService.send("lockedUrl", { url: routerState.url });
|
||||||
|
}
|
||||||
|
this.router.navigate(["lock"], { queryParams: { promptBiometric: true } });
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!routerState.url.includes("remove-password") &&
|
||||||
|
(await this.keyConnectorService.getConvertAccountRequired())
|
||||||
|
) {
|
||||||
|
this.router.navigate(["/remove-password"]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
6
jslib/angular/src/services/broadcaster.service.ts
Normal file
6
jslib/angular/src/services/broadcaster.service.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
|
import { BroadcasterService as BaseBroadcasterService } from "@/jslib/common/src/services/broadcaster.service";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class BroadcasterService extends BaseBroadcasterService {}
|
||||||
493
jslib/angular/src/services/jslib-services.module.ts
Normal file
493
jslib/angular/src/services/jslib-services.module.ts
Normal file
@@ -0,0 +1,493 @@
|
|||||||
|
import { Injector, LOCALE_ID, NgModule } from "@angular/core";
|
||||||
|
|
||||||
|
import { AuthGuardService } from "./auth-guard.service";
|
||||||
|
import { BroadcasterService } from "./broadcaster.service";
|
||||||
|
import { LockGuardService } from "./lock-guard.service";
|
||||||
|
import { ModalService } from "./modal.service";
|
||||||
|
import { PasswordRepromptService } from "./passwordReprompt.service";
|
||||||
|
import { UnauthGuardService } from "./unauth-guard.service";
|
||||||
|
import { ValidationService } from "./validation.service";
|
||||||
|
|
||||||
|
import { ApiService as ApiServiceAbstraction } from "@/jslib/common/src/abstractions/api.service";
|
||||||
|
import { AppIdService as AppIdServiceAbstraction } from "@/jslib/common/src/abstractions/appId.service";
|
||||||
|
import { AuditService as AuditServiceAbstraction } from "@/jslib/common/src/abstractions/audit.service";
|
||||||
|
import { AuthService as AuthServiceAbstraction } from "@/jslib/common/src/abstractions/auth.service";
|
||||||
|
import { BroadcasterService as BroadcasterServiceAbstraction } from "@/jslib/common/src/abstractions/broadcaster.service";
|
||||||
|
import { CipherService as CipherServiceAbstraction } from "@/jslib/common/src/abstractions/cipher.service";
|
||||||
|
import { CollectionService as CollectionServiceAbstraction } from "@/jslib/common/src/abstractions/collection.service";
|
||||||
|
import { CryptoService as CryptoServiceAbstraction } from "@/jslib/common/src/abstractions/crypto.service";
|
||||||
|
import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@/jslib/common/src/abstractions/cryptoFunction.service";
|
||||||
|
import { EnvironmentService as EnvironmentServiceAbstraction } from "@/jslib/common/src/abstractions/environment.service";
|
||||||
|
import { EventService as EventServiceAbstraction } from "@/jslib/common/src/abstractions/event.service";
|
||||||
|
import { ExportService as ExportServiceAbstraction } from "@/jslib/common/src/abstractions/export.service";
|
||||||
|
import { FileUploadService as FileUploadServiceAbstraction } from "@/jslib/common/src/abstractions/fileUpload.service";
|
||||||
|
import { FolderService as FolderServiceAbstraction } from "@/jslib/common/src/abstractions/folder.service";
|
||||||
|
import { I18nService as I18nServiceAbstraction } from "@/jslib/common/src/abstractions/i18n.service";
|
||||||
|
import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@/jslib/common/src/abstractions/keyConnector.service";
|
||||||
|
import { LogService } from "@/jslib/common/src/abstractions/log.service";
|
||||||
|
import { MessagingService as MessagingServiceAbstraction } from "@/jslib/common/src/abstractions/messaging.service";
|
||||||
|
import { NotificationsService as NotificationsServiceAbstraction } from "@/jslib/common/src/abstractions/notifications.service";
|
||||||
|
import { OrganizationService as OrganizationServiceAbstraction } from "@/jslib/common/src/abstractions/organization.service";
|
||||||
|
import { PasswordGenerationService as PasswordGenerationServiceAbstraction } from "@/jslib/common/src/abstractions/passwordGeneration.service";
|
||||||
|
import { PasswordRepromptService as PasswordRepromptServiceAbstraction } from "@/jslib/common/src/abstractions/passwordReprompt.service";
|
||||||
|
import { PlatformUtilsService as PlatformUtilsServiceAbstraction } from "@/jslib/common/src/abstractions/platformUtils.service";
|
||||||
|
import { PolicyService as PolicyServiceAbstraction } from "@/jslib/common/src/abstractions/policy.service";
|
||||||
|
import { ProviderService as ProviderServiceAbstraction } from "@/jslib/common/src/abstractions/provider.service";
|
||||||
|
import { SearchService as SearchServiceAbstraction } from "@/jslib/common/src/abstractions/search.service";
|
||||||
|
import { SendService as SendServiceAbstraction } from "@/jslib/common/src/abstractions/send.service";
|
||||||
|
import { SettingsService as SettingsServiceAbstraction } from "@/jslib/common/src/abstractions/settings.service";
|
||||||
|
import { StateService as StateServiceAbstraction } from "@/jslib/common/src/abstractions/state.service";
|
||||||
|
import { StateMigrationService as StateMigrationServiceAbstraction } from "@/jslib/common/src/abstractions/stateMigration.service";
|
||||||
|
import { StorageService as StorageServiceAbstraction } from "@/jslib/common/src/abstractions/storage.service";
|
||||||
|
import { SyncService as SyncServiceAbstraction } from "@/jslib/common/src/abstractions/sync.service";
|
||||||
|
import { TokenService as TokenServiceAbstraction } from "@/jslib/common/src/abstractions/token.service";
|
||||||
|
import { TotpService as TotpServiceAbstraction } from "@/jslib/common/src/abstractions/totp.service";
|
||||||
|
import { TwoFactorService as TwoFactorServiceAbstraction } from "@/jslib/common/src/abstractions/twoFactor.service";
|
||||||
|
import { UserVerificationService as UserVerificationServiceAbstraction } from "@/jslib/common/src/abstractions/userVerification.service";
|
||||||
|
import { UsernameGenerationService as UsernameGenerationServiceAbstraction } from "@/jslib/common/src/abstractions/usernameGeneration.service";
|
||||||
|
import { VaultTimeoutService as VaultTimeoutServiceAbstraction } from "@/jslib/common/src/abstractions/vaultTimeout.service";
|
||||||
|
import { StateFactory } from "@/jslib/common/src/factories/stateFactory";
|
||||||
|
import { Account } from "@/jslib/common/src/models/domain/account";
|
||||||
|
import { GlobalState } from "@/jslib/common/src/models/domain/globalState";
|
||||||
|
import { ApiService } from "@/jslib/common/src/services/api.service";
|
||||||
|
import { AppIdService } from "@/jslib/common/src/services/appId.service";
|
||||||
|
import { AuditService } from "@/jslib/common/src/services/audit.service";
|
||||||
|
import { AuthService } from "@/jslib/common/src/services/auth.service";
|
||||||
|
import { CipherService } from "@/jslib/common/src/services/cipher.service";
|
||||||
|
import { CollectionService } from "@/jslib/common/src/services/collection.service";
|
||||||
|
import { ConsoleLogService } from "@/jslib/common/src/services/consoleLog.service";
|
||||||
|
import { CryptoService } from "@/jslib/common/src/services/crypto.service";
|
||||||
|
import { EnvironmentService } from "@/jslib/common/src/services/environment.service";
|
||||||
|
import { EventService } from "@/jslib/common/src/services/event.service";
|
||||||
|
import { ExportService } from "@/jslib/common/src/services/export.service";
|
||||||
|
import { FileUploadService } from "@/jslib/common/src/services/fileUpload.service";
|
||||||
|
import { FolderService } from "@/jslib/common/src/services/folder.service";
|
||||||
|
import { KeyConnectorService } from "@/jslib/common/src/services/keyConnector.service";
|
||||||
|
import { NotificationsService } from "@/jslib/common/src/services/notifications.service";
|
||||||
|
import { OrganizationService } from "@/jslib/common/src/services/organization.service";
|
||||||
|
import { PasswordGenerationService } from "@/jslib/common/src/services/passwordGeneration.service";
|
||||||
|
import { PolicyService } from "@/jslib/common/src/services/policy.service";
|
||||||
|
import { ProviderService } from "@/jslib/common/src/services/provider.service";
|
||||||
|
import { SearchService } from "@/jslib/common/src/services/search.service";
|
||||||
|
import { SendService } from "@/jslib/common/src/services/send.service";
|
||||||
|
import { SettingsService } from "@/jslib/common/src/services/settings.service";
|
||||||
|
import { StateService } from "@/jslib/common/src/services/state.service";
|
||||||
|
import { StateMigrationService } from "@/jslib/common/src/services/stateMigration.service";
|
||||||
|
import { SyncService } from "@/jslib/common/src/services/sync.service";
|
||||||
|
import { TokenService } from "@/jslib/common/src/services/token.service";
|
||||||
|
import { TotpService } from "@/jslib/common/src/services/totp.service";
|
||||||
|
import { TwoFactorService } from "@/jslib/common/src/services/twoFactor.service";
|
||||||
|
import { UserVerificationService } from "@/jslib/common/src/services/userVerification.service";
|
||||||
|
import { UsernameGenerationService } from "@/jslib/common/src/services/usernameGeneration.service";
|
||||||
|
import { VaultTimeoutService } from "@/jslib/common/src/services/vaultTimeout.service";
|
||||||
|
import { WebCryptoFunctionService } from "@/jslib/common/src/services/webCryptoFunction.service";
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [],
|
||||||
|
providers: [
|
||||||
|
{ provide: "WINDOW", useValue: window },
|
||||||
|
{
|
||||||
|
provide: LOCALE_ID,
|
||||||
|
useFactory: (i18nService: I18nServiceAbstraction) => i18nService.translationLocale,
|
||||||
|
deps: [I18nServiceAbstraction],
|
||||||
|
},
|
||||||
|
ValidationService,
|
||||||
|
AuthGuardService,
|
||||||
|
UnauthGuardService,
|
||||||
|
LockGuardService,
|
||||||
|
ModalService,
|
||||||
|
{
|
||||||
|
provide: AppIdServiceAbstraction,
|
||||||
|
useClass: AppIdService,
|
||||||
|
deps: [StorageServiceAbstraction],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: AuditServiceAbstraction,
|
||||||
|
useClass: AuditService,
|
||||||
|
deps: [CryptoFunctionServiceAbstraction, ApiServiceAbstraction],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: AuthServiceAbstraction,
|
||||||
|
useClass: AuthService,
|
||||||
|
deps: [
|
||||||
|
CryptoServiceAbstraction,
|
||||||
|
ApiServiceAbstraction,
|
||||||
|
TokenServiceAbstraction,
|
||||||
|
AppIdServiceAbstraction,
|
||||||
|
PlatformUtilsServiceAbstraction,
|
||||||
|
MessagingServiceAbstraction,
|
||||||
|
LogService,
|
||||||
|
KeyConnectorServiceAbstraction,
|
||||||
|
EnvironmentServiceAbstraction,
|
||||||
|
StateServiceAbstraction,
|
||||||
|
TwoFactorServiceAbstraction,
|
||||||
|
I18nServiceAbstraction,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: CipherServiceAbstraction,
|
||||||
|
useFactory: (
|
||||||
|
cryptoService: CryptoServiceAbstraction,
|
||||||
|
settingsService: SettingsServiceAbstraction,
|
||||||
|
apiService: ApiServiceAbstraction,
|
||||||
|
fileUploadService: FileUploadServiceAbstraction,
|
||||||
|
i18nService: I18nServiceAbstraction,
|
||||||
|
injector: Injector,
|
||||||
|
logService: LogService,
|
||||||
|
stateService: StateServiceAbstraction
|
||||||
|
) =>
|
||||||
|
new CipherService(
|
||||||
|
cryptoService,
|
||||||
|
settingsService,
|
||||||
|
apiService,
|
||||||
|
fileUploadService,
|
||||||
|
i18nService,
|
||||||
|
() => injector.get(SearchServiceAbstraction),
|
||||||
|
logService,
|
||||||
|
stateService
|
||||||
|
),
|
||||||
|
deps: [
|
||||||
|
CryptoServiceAbstraction,
|
||||||
|
SettingsServiceAbstraction,
|
||||||
|
ApiServiceAbstraction,
|
||||||
|
FileUploadServiceAbstraction,
|
||||||
|
I18nServiceAbstraction,
|
||||||
|
Injector, // TODO: Get rid of this circular dependency!
|
||||||
|
LogService,
|
||||||
|
StateServiceAbstraction,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: FolderServiceAbstraction,
|
||||||
|
useClass: FolderService,
|
||||||
|
deps: [
|
||||||
|
CryptoServiceAbstraction,
|
||||||
|
ApiServiceAbstraction,
|
||||||
|
I18nServiceAbstraction,
|
||||||
|
CipherServiceAbstraction,
|
||||||
|
StateServiceAbstraction,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ provide: LogService, useFactory: () => new ConsoleLogService(false) },
|
||||||
|
{
|
||||||
|
provide: CollectionServiceAbstraction,
|
||||||
|
useClass: CollectionService,
|
||||||
|
deps: [CryptoServiceAbstraction, I18nServiceAbstraction, StateServiceAbstraction],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: EnvironmentServiceAbstraction,
|
||||||
|
useClass: EnvironmentService,
|
||||||
|
deps: [StateServiceAbstraction],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: TotpServiceAbstraction,
|
||||||
|
useClass: TotpService,
|
||||||
|
deps: [CryptoFunctionServiceAbstraction, LogService, StateServiceAbstraction],
|
||||||
|
},
|
||||||
|
{ provide: TokenServiceAbstraction, useClass: TokenService, deps: [StateServiceAbstraction] },
|
||||||
|
{
|
||||||
|
provide: CryptoServiceAbstraction,
|
||||||
|
useClass: CryptoService,
|
||||||
|
deps: [
|
||||||
|
CryptoFunctionServiceAbstraction,
|
||||||
|
PlatformUtilsServiceAbstraction,
|
||||||
|
LogService,
|
||||||
|
StateServiceAbstraction,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: PasswordGenerationServiceAbstraction,
|
||||||
|
useClass: PasswordGenerationService,
|
||||||
|
deps: [CryptoServiceAbstraction, PolicyServiceAbstraction, StateServiceAbstraction],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: UsernameGenerationServiceAbstraction,
|
||||||
|
useClass: UsernameGenerationService,
|
||||||
|
deps: [CryptoServiceAbstraction, StateServiceAbstraction],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: ApiServiceAbstraction,
|
||||||
|
useFactory: (
|
||||||
|
tokenService: TokenServiceAbstraction,
|
||||||
|
platformUtilsService: PlatformUtilsServiceAbstraction,
|
||||||
|
environmentService: EnvironmentServiceAbstraction,
|
||||||
|
messagingService: MessagingServiceAbstraction,
|
||||||
|
appIdService: AppIdServiceAbstraction
|
||||||
|
) =>
|
||||||
|
new ApiService(
|
||||||
|
tokenService,
|
||||||
|
platformUtilsService,
|
||||||
|
environmentService,
|
||||||
|
appIdService,
|
||||||
|
async (expired: boolean) => messagingService.send("logout", { expired: expired })
|
||||||
|
),
|
||||||
|
deps: [
|
||||||
|
TokenServiceAbstraction,
|
||||||
|
PlatformUtilsServiceAbstraction,
|
||||||
|
EnvironmentServiceAbstraction,
|
||||||
|
MessagingServiceAbstraction,
|
||||||
|
AppIdServiceAbstraction,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: FileUploadServiceAbstraction,
|
||||||
|
useClass: FileUploadService,
|
||||||
|
deps: [LogService, ApiServiceAbstraction],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: SyncServiceAbstraction,
|
||||||
|
useFactory: (
|
||||||
|
apiService: ApiServiceAbstraction,
|
||||||
|
settingsService: SettingsServiceAbstraction,
|
||||||
|
folderService: FolderServiceAbstraction,
|
||||||
|
cipherService: CipherServiceAbstraction,
|
||||||
|
cryptoService: CryptoServiceAbstraction,
|
||||||
|
collectionService: CollectionServiceAbstraction,
|
||||||
|
messagingService: MessagingServiceAbstraction,
|
||||||
|
policyService: PolicyServiceAbstraction,
|
||||||
|
sendService: SendServiceAbstraction,
|
||||||
|
logService: LogService,
|
||||||
|
keyConnectorService: KeyConnectorServiceAbstraction,
|
||||||
|
stateService: StateServiceAbstraction,
|
||||||
|
organizationService: OrganizationServiceAbstraction,
|
||||||
|
providerService: ProviderServiceAbstraction
|
||||||
|
) =>
|
||||||
|
new SyncService(
|
||||||
|
apiService,
|
||||||
|
settingsService,
|
||||||
|
folderService,
|
||||||
|
cipherService,
|
||||||
|
cryptoService,
|
||||||
|
collectionService,
|
||||||
|
messagingService,
|
||||||
|
policyService,
|
||||||
|
sendService,
|
||||||
|
logService,
|
||||||
|
keyConnectorService,
|
||||||
|
stateService,
|
||||||
|
organizationService,
|
||||||
|
providerService,
|
||||||
|
async (expired: boolean) => messagingService.send("logout", { expired: expired })
|
||||||
|
),
|
||||||
|
deps: [
|
||||||
|
ApiServiceAbstraction,
|
||||||
|
SettingsServiceAbstraction,
|
||||||
|
FolderServiceAbstraction,
|
||||||
|
CipherServiceAbstraction,
|
||||||
|
CryptoServiceAbstraction,
|
||||||
|
CollectionServiceAbstraction,
|
||||||
|
MessagingServiceAbstraction,
|
||||||
|
PolicyServiceAbstraction,
|
||||||
|
SendServiceAbstraction,
|
||||||
|
LogService,
|
||||||
|
KeyConnectorServiceAbstraction,
|
||||||
|
StateServiceAbstraction,
|
||||||
|
OrganizationServiceAbstraction,
|
||||||
|
ProviderServiceAbstraction,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ provide: BroadcasterServiceAbstraction, useClass: BroadcasterService },
|
||||||
|
{
|
||||||
|
provide: SettingsServiceAbstraction,
|
||||||
|
useClass: SettingsService,
|
||||||
|
deps: [StateServiceAbstraction],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: VaultTimeoutServiceAbstraction,
|
||||||
|
useFactory: (
|
||||||
|
cipherService: CipherServiceAbstraction,
|
||||||
|
folderService: FolderServiceAbstraction,
|
||||||
|
collectionService: CollectionServiceAbstraction,
|
||||||
|
cryptoService: CryptoServiceAbstraction,
|
||||||
|
platformUtilsService: PlatformUtilsServiceAbstraction,
|
||||||
|
messagingService: MessagingServiceAbstraction,
|
||||||
|
searchService: SearchServiceAbstraction,
|
||||||
|
tokenService: TokenServiceAbstraction,
|
||||||
|
policyService: PolicyServiceAbstraction,
|
||||||
|
keyConnectorService: KeyConnectorServiceAbstraction,
|
||||||
|
stateService: StateServiceAbstraction
|
||||||
|
) =>
|
||||||
|
new VaultTimeoutService(
|
||||||
|
cipherService,
|
||||||
|
folderService,
|
||||||
|
collectionService,
|
||||||
|
cryptoService,
|
||||||
|
platformUtilsService,
|
||||||
|
messagingService,
|
||||||
|
searchService,
|
||||||
|
tokenService,
|
||||||
|
policyService,
|
||||||
|
keyConnectorService,
|
||||||
|
stateService,
|
||||||
|
null,
|
||||||
|
async (userId?: string) =>
|
||||||
|
messagingService.send("logout", { expired: false, userId: userId })
|
||||||
|
),
|
||||||
|
deps: [
|
||||||
|
CipherServiceAbstraction,
|
||||||
|
FolderServiceAbstraction,
|
||||||
|
CollectionServiceAbstraction,
|
||||||
|
CryptoServiceAbstraction,
|
||||||
|
PlatformUtilsServiceAbstraction,
|
||||||
|
MessagingServiceAbstraction,
|
||||||
|
SearchServiceAbstraction,
|
||||||
|
TokenServiceAbstraction,
|
||||||
|
PolicyServiceAbstraction,
|
||||||
|
KeyConnectorServiceAbstraction,
|
||||||
|
StateServiceAbstraction,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: StateServiceAbstraction,
|
||||||
|
useFactory: (
|
||||||
|
storageService: StorageServiceAbstraction,
|
||||||
|
secureStorageService: StorageServiceAbstraction,
|
||||||
|
logService: LogService,
|
||||||
|
stateMigrationService: StateMigrationServiceAbstraction
|
||||||
|
) =>
|
||||||
|
new StateService(
|
||||||
|
storageService,
|
||||||
|
secureStorageService,
|
||||||
|
logService,
|
||||||
|
stateMigrationService,
|
||||||
|
new StateFactory(GlobalState, Account)
|
||||||
|
),
|
||||||
|
deps: [
|
||||||
|
StorageServiceAbstraction,
|
||||||
|
"SECURE_STORAGE",
|
||||||
|
LogService,
|
||||||
|
StateMigrationServiceAbstraction,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: StateMigrationServiceAbstraction,
|
||||||
|
useFactory: (
|
||||||
|
storageService: StorageServiceAbstraction,
|
||||||
|
secureStorageService: StorageServiceAbstraction
|
||||||
|
) =>
|
||||||
|
new StateMigrationService(
|
||||||
|
storageService,
|
||||||
|
secureStorageService,
|
||||||
|
new StateFactory(GlobalState, Account)
|
||||||
|
),
|
||||||
|
deps: [StorageServiceAbstraction, "SECURE_STORAGE"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: ExportServiceAbstraction,
|
||||||
|
useClass: ExportService,
|
||||||
|
deps: [
|
||||||
|
FolderServiceAbstraction,
|
||||||
|
CipherServiceAbstraction,
|
||||||
|
ApiServiceAbstraction,
|
||||||
|
CryptoServiceAbstraction,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: SearchServiceAbstraction,
|
||||||
|
useClass: SearchService,
|
||||||
|
deps: [CipherServiceAbstraction, LogService, I18nServiceAbstraction],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: NotificationsServiceAbstraction,
|
||||||
|
useFactory: (
|
||||||
|
syncService: SyncServiceAbstraction,
|
||||||
|
appIdService: AppIdServiceAbstraction,
|
||||||
|
apiService: ApiServiceAbstraction,
|
||||||
|
vaultTimeoutService: VaultTimeoutServiceAbstraction,
|
||||||
|
environmentService: EnvironmentServiceAbstraction,
|
||||||
|
messagingService: MessagingServiceAbstraction,
|
||||||
|
logService: LogService,
|
||||||
|
stateService: StateServiceAbstraction
|
||||||
|
) =>
|
||||||
|
new NotificationsService(
|
||||||
|
syncService,
|
||||||
|
appIdService,
|
||||||
|
apiService,
|
||||||
|
vaultTimeoutService,
|
||||||
|
environmentService,
|
||||||
|
async () => messagingService.send("logout", { expired: true }),
|
||||||
|
logService,
|
||||||
|
stateService
|
||||||
|
),
|
||||||
|
deps: [
|
||||||
|
SyncServiceAbstraction,
|
||||||
|
AppIdServiceAbstraction,
|
||||||
|
ApiServiceAbstraction,
|
||||||
|
VaultTimeoutServiceAbstraction,
|
||||||
|
EnvironmentServiceAbstraction,
|
||||||
|
MessagingServiceAbstraction,
|
||||||
|
LogService,
|
||||||
|
StateServiceAbstraction,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: CryptoFunctionServiceAbstraction,
|
||||||
|
useClass: WebCryptoFunctionService,
|
||||||
|
deps: ["WINDOW"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: EventServiceAbstraction,
|
||||||
|
useClass: EventService,
|
||||||
|
deps: [
|
||||||
|
ApiServiceAbstraction,
|
||||||
|
CipherServiceAbstraction,
|
||||||
|
StateServiceAbstraction,
|
||||||
|
LogService,
|
||||||
|
OrganizationServiceAbstraction,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: PolicyServiceAbstraction,
|
||||||
|
useClass: PolicyService,
|
||||||
|
deps: [StateServiceAbstraction, OrganizationServiceAbstraction, ApiServiceAbstraction],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: SendServiceAbstraction,
|
||||||
|
useClass: SendService,
|
||||||
|
deps: [
|
||||||
|
CryptoServiceAbstraction,
|
||||||
|
ApiServiceAbstraction,
|
||||||
|
FileUploadServiceAbstraction,
|
||||||
|
I18nServiceAbstraction,
|
||||||
|
CryptoFunctionServiceAbstraction,
|
||||||
|
StateServiceAbstraction,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: KeyConnectorServiceAbstraction,
|
||||||
|
useClass: KeyConnectorService,
|
||||||
|
deps: [
|
||||||
|
StateServiceAbstraction,
|
||||||
|
CryptoServiceAbstraction,
|
||||||
|
ApiServiceAbstraction,
|
||||||
|
TokenServiceAbstraction,
|
||||||
|
LogService,
|
||||||
|
OrganizationServiceAbstraction,
|
||||||
|
CryptoFunctionServiceAbstraction,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: UserVerificationServiceAbstraction,
|
||||||
|
useClass: UserVerificationService,
|
||||||
|
deps: [CryptoServiceAbstraction, I18nServiceAbstraction, ApiServiceAbstraction],
|
||||||
|
},
|
||||||
|
{ provide: PasswordRepromptServiceAbstraction, useClass: PasswordRepromptService },
|
||||||
|
{
|
||||||
|
provide: OrganizationServiceAbstraction,
|
||||||
|
useClass: OrganizationService,
|
||||||
|
deps: [StateServiceAbstraction],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: ProviderServiceAbstraction,
|
||||||
|
useClass: ProviderService,
|
||||||
|
deps: [StateServiceAbstraction],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: TwoFactorServiceAbstraction,
|
||||||
|
useClass: TwoFactorService,
|
||||||
|
deps: [I18nServiceAbstraction, PlatformUtilsServiceAbstraction],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class JslibServicesModule {}
|
||||||
29
jslib/angular/src/services/lock-guard.service.ts
Normal file
29
jslib/angular/src/services/lock-guard.service.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
import { Router } from "@angular/router";
|
||||||
|
|
||||||
|
import { StateService } from "@/jslib/common/src/abstractions/state.service";
|
||||||
|
import { VaultTimeoutService } from "@/jslib/common/src/abstractions/vaultTimeout.service";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class LockGuardService {
|
||||||
|
protected homepage = "vault";
|
||||||
|
protected loginpage = "login";
|
||||||
|
constructor(
|
||||||
|
private vaultTimeoutService: VaultTimeoutService,
|
||||||
|
private router: Router,
|
||||||
|
private stateService: StateService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async canActivate() {
|
||||||
|
if (await this.vaultTimeoutService.isLocked()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const redirectUrl = (await this.stateService.getIsAuthenticated())
|
||||||
|
? [this.homepage]
|
||||||
|
: [this.loginpage];
|
||||||
|
|
||||||
|
this.router.navigate(redirectUrl);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
180
jslib/angular/src/services/modal.service.ts
Normal file
180
jslib/angular/src/services/modal.service.ts
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
import {
|
||||||
|
ApplicationRef,
|
||||||
|
ComponentFactory,
|
||||||
|
ComponentFactoryResolver,
|
||||||
|
ComponentRef,
|
||||||
|
EmbeddedViewRef,
|
||||||
|
Injectable,
|
||||||
|
Injector,
|
||||||
|
Type,
|
||||||
|
ViewContainerRef,
|
||||||
|
} from "@angular/core";
|
||||||
|
import { first } from "rxjs/operators";
|
||||||
|
|
||||||
|
import { DynamicModalComponent } from "../components/modal/dynamic-modal.component";
|
||||||
|
import { ModalInjector } from "../components/modal/modal-injector";
|
||||||
|
import { ModalRef } from "../components/modal/modal.ref";
|
||||||
|
|
||||||
|
export class ModalConfig<D = any> {
|
||||||
|
data?: D;
|
||||||
|
allowMultipleModals = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ModalService {
|
||||||
|
protected modalList: ComponentRef<DynamicModalComponent>[] = [];
|
||||||
|
|
||||||
|
// Lazy loaded modules are not available in componentFactoryResolver,
|
||||||
|
// therefore modules needs to manually initialize their resolvers.
|
||||||
|
private factoryResolvers: Map<Type<any>, ComponentFactoryResolver> = new Map();
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private componentFactoryResolver: ComponentFactoryResolver,
|
||||||
|
private applicationRef: ApplicationRef,
|
||||||
|
private injector: Injector
|
||||||
|
) {
|
||||||
|
document.addEventListener("keyup", (event) => {
|
||||||
|
if (event.key === "Escape" && this.modalCount > 0) {
|
||||||
|
this.topModal.instance.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get modalCount() {
|
||||||
|
return this.modalList.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
private get topModal() {
|
||||||
|
return this.modalList[this.modalCount - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
async openViewRef<T>(
|
||||||
|
componentType: Type<T>,
|
||||||
|
viewContainerRef: ViewContainerRef,
|
||||||
|
setComponentParameters: (component: T) => void = null
|
||||||
|
): Promise<[ModalRef, T]> {
|
||||||
|
const [modalRef, modalComponentRef] = this.openInternal(componentType, null, false);
|
||||||
|
modalComponentRef.instance.setComponentParameters = setComponentParameters;
|
||||||
|
|
||||||
|
viewContainerRef.insert(modalComponentRef.hostView);
|
||||||
|
|
||||||
|
await modalRef.onCreated.pipe(first()).toPromise();
|
||||||
|
|
||||||
|
return [modalRef, modalComponentRef.instance.componentRef.instance];
|
||||||
|
}
|
||||||
|
|
||||||
|
open(componentType: Type<any>, config?: ModalConfig) {
|
||||||
|
if (!(config?.allowMultipleModals ?? false) && this.modalCount > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line
|
||||||
|
const [modalRef, _] = this.openInternal(componentType, config, true);
|
||||||
|
|
||||||
|
return modalRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
registerComponentFactoryResolver<T>(
|
||||||
|
componentType: Type<T>,
|
||||||
|
componentFactoryResolver: ComponentFactoryResolver
|
||||||
|
): void {
|
||||||
|
this.factoryResolvers.set(componentType, componentFactoryResolver);
|
||||||
|
}
|
||||||
|
|
||||||
|
resolveComponentFactory<T>(componentType: Type<T>): ComponentFactory<T> {
|
||||||
|
if (this.factoryResolvers.has(componentType)) {
|
||||||
|
return this.factoryResolvers.get(componentType).resolveComponentFactory(componentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.componentFactoryResolver.resolveComponentFactory(componentType);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected openInternal(
|
||||||
|
componentType: Type<any>,
|
||||||
|
config?: ModalConfig,
|
||||||
|
attachToDom?: boolean
|
||||||
|
): [ModalRef, ComponentRef<DynamicModalComponent>] {
|
||||||
|
const [modalRef, componentRef] = this.createModalComponent(config);
|
||||||
|
componentRef.instance.childComponentType = componentType;
|
||||||
|
|
||||||
|
if (attachToDom) {
|
||||||
|
this.applicationRef.attachView(componentRef.hostView);
|
||||||
|
const domElem = (componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
|
||||||
|
document.body.appendChild(domElem);
|
||||||
|
}
|
||||||
|
|
||||||
|
modalRef.onClosed.pipe(first()).subscribe(() => {
|
||||||
|
if (attachToDom) {
|
||||||
|
this.applicationRef.detachView(componentRef.hostView);
|
||||||
|
}
|
||||||
|
componentRef.destroy();
|
||||||
|
|
||||||
|
this.modalList.pop();
|
||||||
|
if (this.modalCount > 0) {
|
||||||
|
this.topModal.instance.getFocus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setupHandlers(modalRef);
|
||||||
|
|
||||||
|
this.modalList.push(componentRef);
|
||||||
|
|
||||||
|
return [modalRef, componentRef];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected setupHandlers(modalRef: ModalRef) {
|
||||||
|
let backdrop: HTMLElement = null;
|
||||||
|
|
||||||
|
// Add backdrop, setup [data-dismiss] handler.
|
||||||
|
modalRef.onCreated.pipe(first()).subscribe((el) => {
|
||||||
|
document.body.classList.add("modal-open");
|
||||||
|
|
||||||
|
const modalEl: HTMLElement = el.querySelector(".modal");
|
||||||
|
const dialogEl = modalEl.querySelector(".modal-dialog") as HTMLElement;
|
||||||
|
|
||||||
|
backdrop = document.createElement("div");
|
||||||
|
backdrop.className = "modal-backdrop fade";
|
||||||
|
backdrop.style.zIndex = `${this.modalCount}040`;
|
||||||
|
modalEl.prepend(backdrop);
|
||||||
|
|
||||||
|
dialogEl.addEventListener("click", (e: Event) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
dialogEl.style.zIndex = `${this.modalCount}050`;
|
||||||
|
|
||||||
|
const modals = Array.from(
|
||||||
|
el.querySelectorAll('.modal-backdrop, .modal *[data-dismiss="modal"]')
|
||||||
|
);
|
||||||
|
for (const closeElement of modals) {
|
||||||
|
closeElement.addEventListener("click", () => {
|
||||||
|
modalRef.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// onClose is used in Web to hook into bootstrap. On other projects we pipe it directly to closed.
|
||||||
|
modalRef.onClose.pipe(first()).subscribe(() => {
|
||||||
|
modalRef.closed();
|
||||||
|
|
||||||
|
if (this.modalCount === 0) {
|
||||||
|
document.body.classList.remove("modal-open");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected createModalComponent(
|
||||||
|
config: ModalConfig
|
||||||
|
): [ModalRef, ComponentRef<DynamicModalComponent>] {
|
||||||
|
const modalRef = new ModalRef();
|
||||||
|
|
||||||
|
const map = new WeakMap();
|
||||||
|
map.set(ModalConfig, config);
|
||||||
|
map.set(ModalRef, modalRef);
|
||||||
|
|
||||||
|
const componentFactory =
|
||||||
|
this.componentFactoryResolver.resolveComponentFactory(DynamicModalComponent);
|
||||||
|
const componentRef = componentFactory.create(new ModalInjector(this.injector, map));
|
||||||
|
|
||||||
|
return [modalRef, componentRef];
|
||||||
|
}
|
||||||
|
}
|
||||||
47
jslib/angular/src/services/passwordReprompt.service.ts
Normal file
47
jslib/angular/src/services/passwordReprompt.service.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
|
import { PasswordRepromptComponent } from "../components/password-reprompt.component";
|
||||||
|
|
||||||
|
import { ModalService } from "./modal.service";
|
||||||
|
|
||||||
|
import { KeyConnectorService } from "@/jslib/common/src/abstractions/keyConnector.service";
|
||||||
|
import { PasswordRepromptService as PasswordRepromptServiceAbstraction } from "@/jslib/common/src/abstractions/passwordReprompt.service";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to verify the user's Master Password for the "Master Password Re-prompt" feature only.
|
||||||
|
* See UserVerificationService for any other situation where you need to verify the user's identity.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class PasswordRepromptService implements PasswordRepromptServiceAbstraction {
|
||||||
|
protected component = PasswordRepromptComponent;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private modalService: ModalService,
|
||||||
|
private keyConnectorService: KeyConnectorService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
protectedFields() {
|
||||||
|
return ["TOTP", "Password", "H_Field", "Card Number", "Security Code"];
|
||||||
|
}
|
||||||
|
|
||||||
|
async showPasswordPrompt() {
|
||||||
|
if (!(await this.enabled())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ref = this.modalService.open(this.component, { allowMultipleModals: true });
|
||||||
|
|
||||||
|
if (ref == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await ref.onClosedPromise();
|
||||||
|
return result === true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async enabled() {
|
||||||
|
return !(await this.keyConnectorService.getUsesKeyConnector());
|
||||||
|
}
|
||||||
|
}
|
||||||
29
jslib/angular/src/services/unauth-guard.service.ts
Normal file
29
jslib/angular/src/services/unauth-guard.service.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
import { Router } from "@angular/router";
|
||||||
|
|
||||||
|
import { StateService } from "@/jslib/common/src/abstractions/state.service";
|
||||||
|
import { VaultTimeoutService } from "@/jslib/common/src/abstractions/vaultTimeout.service";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UnauthGuardService {
|
||||||
|
protected homepage = "vault";
|
||||||
|
constructor(
|
||||||
|
private vaultTimeoutService: VaultTimeoutService,
|
||||||
|
private router: Router,
|
||||||
|
private stateService: StateService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async canActivate() {
|
||||||
|
const isAuthed = await this.stateService.getIsAuthenticated();
|
||||||
|
if (isAuthed) {
|
||||||
|
const locked = await this.vaultTimeoutService.isLocked();
|
||||||
|
if (locked) {
|
||||||
|
this.router.navigate(["lock"]);
|
||||||
|
} else {
|
||||||
|
this.router.navigate([this.homepage]);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
38
jslib/angular/src/services/validation.service.ts
Normal file
38
jslib/angular/src/services/validation.service.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { Injectable } from "@angular/core";
|
||||||
|
|
||||||
|
import { I18nService } from "@/jslib/common/src/abstractions/i18n.service";
|
||||||
|
import { PlatformUtilsService } from "@/jslib/common/src/abstractions/platformUtils.service";
|
||||||
|
import { ErrorResponse } from "@/jslib/common/src/models/response/errorResponse";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ValidationService {
|
||||||
|
constructor(
|
||||||
|
private i18nService: I18nService,
|
||||||
|
private platformUtilsService: PlatformUtilsService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
showError(data: any): string[] {
|
||||||
|
const defaultErrorMessage = this.i18nService.t("unexpectedError");
|
||||||
|
let errors: string[] = [];
|
||||||
|
|
||||||
|
if (data != null && typeof data === "string") {
|
||||||
|
errors.push(data);
|
||||||
|
} else if (data == null || typeof data !== "object") {
|
||||||
|
errors.push(defaultErrorMessage);
|
||||||
|
} else if (data.validationErrors != null) {
|
||||||
|
errors = errors.concat((data as ErrorResponse).getAllMessages());
|
||||||
|
} else {
|
||||||
|
errors.push(data.message ? data.message : defaultErrorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors.length === 1) {
|
||||||
|
this.platformUtilsService.showToast("error", this.i18nService.t("errorOccurred"), errors[0]);
|
||||||
|
} else if (errors.length > 1) {
|
||||||
|
this.platformUtilsService.showToast("error", this.i18nService.t("errorOccurred"), errors, {
|
||||||
|
timeout: 5000 * errors.length,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
}
|
||||||
679
jslib/common/src/abstractions/api.service.ts
Normal file
679
jslib/common/src/abstractions/api.service.ts
Normal file
@@ -0,0 +1,679 @@
|
|||||||
|
import { PolicyType } from "../enums/policyType";
|
||||||
|
import { SetKeyConnectorKeyRequest } from "../models/request/account/setKeyConnectorKeyRequest";
|
||||||
|
import { VerifyOTPRequest } from "../models/request/account/verifyOTPRequest";
|
||||||
|
import { AttachmentRequest } from "../models/request/attachmentRequest";
|
||||||
|
import { BitPayInvoiceRequest } from "../models/request/bitPayInvoiceRequest";
|
||||||
|
import { CipherBulkDeleteRequest } from "../models/request/cipherBulkDeleteRequest";
|
||||||
|
import { CipherBulkMoveRequest } from "../models/request/cipherBulkMoveRequest";
|
||||||
|
import { CipherBulkRestoreRequest } from "../models/request/cipherBulkRestoreRequest";
|
||||||
|
import { CipherBulkShareRequest } from "../models/request/cipherBulkShareRequest";
|
||||||
|
import { CipherCollectionsRequest } from "../models/request/cipherCollectionsRequest";
|
||||||
|
import { CipherCreateRequest } from "../models/request/cipherCreateRequest";
|
||||||
|
import { CipherRequest } from "../models/request/cipherRequest";
|
||||||
|
import { CipherShareRequest } from "../models/request/cipherShareRequest";
|
||||||
|
import { CollectionRequest } from "../models/request/collectionRequest";
|
||||||
|
import { DeleteRecoverRequest } from "../models/request/deleteRecoverRequest";
|
||||||
|
import { EmailRequest } from "../models/request/emailRequest";
|
||||||
|
import { EmailTokenRequest } from "../models/request/emailTokenRequest";
|
||||||
|
import { EmergencyAccessAcceptRequest } from "../models/request/emergencyAccessAcceptRequest";
|
||||||
|
import { EmergencyAccessConfirmRequest } from "../models/request/emergencyAccessConfirmRequest";
|
||||||
|
import { EmergencyAccessInviteRequest } from "../models/request/emergencyAccessInviteRequest";
|
||||||
|
import { EmergencyAccessPasswordRequest } from "../models/request/emergencyAccessPasswordRequest";
|
||||||
|
import { EmergencyAccessUpdateRequest } from "../models/request/emergencyAccessUpdateRequest";
|
||||||
|
import { EventRequest } from "../models/request/eventRequest";
|
||||||
|
import { FolderRequest } from "../models/request/folderRequest";
|
||||||
|
import { GroupRequest } from "../models/request/groupRequest";
|
||||||
|
import { IapCheckRequest } from "../models/request/iapCheckRequest";
|
||||||
|
import { ApiTokenRequest } from "../models/request/identityToken/apiTokenRequest";
|
||||||
|
import { PasswordTokenRequest } from "../models/request/identityToken/passwordTokenRequest";
|
||||||
|
import { SsoTokenRequest } from "../models/request/identityToken/ssoTokenRequest";
|
||||||
|
import { ImportCiphersRequest } from "../models/request/importCiphersRequest";
|
||||||
|
import { ImportDirectoryRequest } from "../models/request/importDirectoryRequest";
|
||||||
|
import { ImportOrganizationCiphersRequest } from "../models/request/importOrganizationCiphersRequest";
|
||||||
|
import { KdfRequest } from "../models/request/kdfRequest";
|
||||||
|
import { KeyConnectorUserKeyRequest } from "../models/request/keyConnectorUserKeyRequest";
|
||||||
|
import { KeysRequest } from "../models/request/keysRequest";
|
||||||
|
import { OrganizationSponsorshipCreateRequest } from "../models/request/organization/organizationSponsorshipCreateRequest";
|
||||||
|
import { OrganizationSponsorshipRedeemRequest } from "../models/request/organization/organizationSponsorshipRedeemRequest";
|
||||||
|
import { OrganizationSsoRequest } from "../models/request/organization/organizationSsoRequest";
|
||||||
|
import { OrganizationCreateRequest } from "../models/request/organizationCreateRequest";
|
||||||
|
import { OrganizationImportRequest } from "../models/request/organizationImportRequest";
|
||||||
|
import { OrganizationKeysRequest } from "../models/request/organizationKeysRequest";
|
||||||
|
import { OrganizationSubscriptionUpdateRequest } from "../models/request/organizationSubscriptionUpdateRequest";
|
||||||
|
import { OrganizationTaxInfoUpdateRequest } from "../models/request/organizationTaxInfoUpdateRequest";
|
||||||
|
import { OrganizationUpdateRequest } from "../models/request/organizationUpdateRequest";
|
||||||
|
import { OrganizationUpgradeRequest } from "../models/request/organizationUpgradeRequest";
|
||||||
|
import { OrganizationUserAcceptRequest } from "../models/request/organizationUserAcceptRequest";
|
||||||
|
import { OrganizationUserBulkConfirmRequest } from "../models/request/organizationUserBulkConfirmRequest";
|
||||||
|
import { OrganizationUserBulkRequest } from "../models/request/organizationUserBulkRequest";
|
||||||
|
import { OrganizationUserConfirmRequest } from "../models/request/organizationUserConfirmRequest";
|
||||||
|
import { OrganizationUserInviteRequest } from "../models/request/organizationUserInviteRequest";
|
||||||
|
import { OrganizationUserResetPasswordEnrollmentRequest } from "../models/request/organizationUserResetPasswordEnrollmentRequest";
|
||||||
|
import { OrganizationUserResetPasswordRequest } from "../models/request/organizationUserResetPasswordRequest";
|
||||||
|
import { OrganizationUserUpdateGroupsRequest } from "../models/request/organizationUserUpdateGroupsRequest";
|
||||||
|
import { OrganizationUserUpdateRequest } from "../models/request/organizationUserUpdateRequest";
|
||||||
|
import { PasswordHintRequest } from "../models/request/passwordHintRequest";
|
||||||
|
import { PasswordRequest } from "../models/request/passwordRequest";
|
||||||
|
import { PaymentRequest } from "../models/request/paymentRequest";
|
||||||
|
import { PolicyRequest } from "../models/request/policyRequest";
|
||||||
|
import { PreloginRequest } from "../models/request/preloginRequest";
|
||||||
|
import { ProviderAddOrganizationRequest } from "../models/request/provider/providerAddOrganizationRequest";
|
||||||
|
import { ProviderOrganizationCreateRequest } from "../models/request/provider/providerOrganizationCreateRequest";
|
||||||
|
import { ProviderSetupRequest } from "../models/request/provider/providerSetupRequest";
|
||||||
|
import { ProviderUpdateRequest } from "../models/request/provider/providerUpdateRequest";
|
||||||
|
import { ProviderUserAcceptRequest } from "../models/request/provider/providerUserAcceptRequest";
|
||||||
|
import { ProviderUserBulkConfirmRequest } from "../models/request/provider/providerUserBulkConfirmRequest";
|
||||||
|
import { ProviderUserBulkRequest } from "../models/request/provider/providerUserBulkRequest";
|
||||||
|
import { ProviderUserConfirmRequest } from "../models/request/provider/providerUserConfirmRequest";
|
||||||
|
import { ProviderUserInviteRequest } from "../models/request/provider/providerUserInviteRequest";
|
||||||
|
import { ProviderUserUpdateRequest } from "../models/request/provider/providerUserUpdateRequest";
|
||||||
|
import { RegisterRequest } from "../models/request/registerRequest";
|
||||||
|
import { SeatRequest } from "../models/request/seatRequest";
|
||||||
|
import { SecretVerificationRequest } from "../models/request/secretVerificationRequest";
|
||||||
|
import { SelectionReadOnlyRequest } from "../models/request/selectionReadOnlyRequest";
|
||||||
|
import { SendAccessRequest } from "../models/request/sendAccessRequest";
|
||||||
|
import { SendRequest } from "../models/request/sendRequest";
|
||||||
|
import { SetPasswordRequest } from "../models/request/setPasswordRequest";
|
||||||
|
import { StorageRequest } from "../models/request/storageRequest";
|
||||||
|
import { TaxInfoUpdateRequest } from "../models/request/taxInfoUpdateRequest";
|
||||||
|
import { TwoFactorEmailRequest } from "../models/request/twoFactorEmailRequest";
|
||||||
|
import { TwoFactorProviderRequest } from "../models/request/twoFactorProviderRequest";
|
||||||
|
import { TwoFactorRecoveryRequest } from "../models/request/twoFactorRecoveryRequest";
|
||||||
|
import { UpdateDomainsRequest } from "../models/request/updateDomainsRequest";
|
||||||
|
import { UpdateKeyRequest } from "../models/request/updateKeyRequest";
|
||||||
|
import { UpdateProfileRequest } from "../models/request/updateProfileRequest";
|
||||||
|
import { UpdateTempPasswordRequest } from "../models/request/updateTempPasswordRequest";
|
||||||
|
import { UpdateTwoFactorAuthenticatorRequest } from "../models/request/updateTwoFactorAuthenticatorRequest";
|
||||||
|
import { UpdateTwoFactorDuoRequest } from "../models/request/updateTwoFactorDuoRequest";
|
||||||
|
import { UpdateTwoFactorEmailRequest } from "../models/request/updateTwoFactorEmailRequest";
|
||||||
|
import { UpdateTwoFactorWebAuthnDeleteRequest } from "../models/request/updateTwoFactorWebAuthnDeleteRequest";
|
||||||
|
import { UpdateTwoFactorWebAuthnRequest } from "../models/request/updateTwoFactorWebAuthnRequest";
|
||||||
|
import { UpdateTwoFactorYubioOtpRequest } from "../models/request/updateTwoFactorYubioOtpRequest";
|
||||||
|
import { VerifyBankRequest } from "../models/request/verifyBankRequest";
|
||||||
|
import { VerifyDeleteRecoverRequest } from "../models/request/verifyDeleteRecoverRequest";
|
||||||
|
import { VerifyEmailRequest } from "../models/request/verifyEmailRequest";
|
||||||
|
import { ApiKeyResponse } from "../models/response/apiKeyResponse";
|
||||||
|
import { AttachmentResponse } from "../models/response/attachmentResponse";
|
||||||
|
import { AttachmentUploadDataResponse } from "../models/response/attachmentUploadDataResponse";
|
||||||
|
import { BillingResponse } from "../models/response/billingResponse";
|
||||||
|
import { BreachAccountResponse } from "../models/response/breachAccountResponse";
|
||||||
|
import { CipherResponse } from "../models/response/cipherResponse";
|
||||||
|
import {
|
||||||
|
CollectionGroupDetailsResponse,
|
||||||
|
CollectionResponse,
|
||||||
|
} from "../models/response/collectionResponse";
|
||||||
|
import { DomainsResponse } from "../models/response/domainsResponse";
|
||||||
|
import {
|
||||||
|
EmergencyAccessGranteeDetailsResponse,
|
||||||
|
EmergencyAccessGrantorDetailsResponse,
|
||||||
|
EmergencyAccessTakeoverResponse,
|
||||||
|
EmergencyAccessViewResponse,
|
||||||
|
} from "../models/response/emergencyAccessResponse";
|
||||||
|
import { EventResponse } from "../models/response/eventResponse";
|
||||||
|
import { FolderResponse } from "../models/response/folderResponse";
|
||||||
|
import { GroupDetailsResponse, GroupResponse } from "../models/response/groupResponse";
|
||||||
|
import { IdentityCaptchaResponse } from "../models/response/identityCaptchaResponse";
|
||||||
|
import { IdentityTokenResponse } from "../models/response/identityTokenResponse";
|
||||||
|
import { IdentityTwoFactorResponse } from "../models/response/identityTwoFactorResponse";
|
||||||
|
import { KeyConnectorUserKeyResponse } from "../models/response/keyConnectorUserKeyResponse";
|
||||||
|
import { ListResponse } from "../models/response/listResponse";
|
||||||
|
import { OrganizationSsoResponse } from "../models/response/organization/organizationSsoResponse";
|
||||||
|
import { OrganizationAutoEnrollStatusResponse } from "../models/response/organizationAutoEnrollStatusResponse";
|
||||||
|
import { OrganizationKeysResponse } from "../models/response/organizationKeysResponse";
|
||||||
|
import { OrganizationResponse } from "../models/response/organizationResponse";
|
||||||
|
import { OrganizationSubscriptionResponse } from "../models/response/organizationSubscriptionResponse";
|
||||||
|
import { OrganizationUserBulkPublicKeyResponse } from "../models/response/organizationUserBulkPublicKeyResponse";
|
||||||
|
import { OrganizationUserBulkResponse } from "../models/response/organizationUserBulkResponse";
|
||||||
|
import {
|
||||||
|
OrganizationUserDetailsResponse,
|
||||||
|
OrganizationUserResetPasswordDetailsReponse,
|
||||||
|
OrganizationUserUserDetailsResponse,
|
||||||
|
} from "../models/response/organizationUserResponse";
|
||||||
|
import { PaymentResponse } from "../models/response/paymentResponse";
|
||||||
|
import { PlanResponse } from "../models/response/planResponse";
|
||||||
|
import { PolicyResponse } from "../models/response/policyResponse";
|
||||||
|
import { PreloginResponse } from "../models/response/preloginResponse";
|
||||||
|
import { ProfileResponse } from "../models/response/profileResponse";
|
||||||
|
import {
|
||||||
|
ProviderOrganizationOrganizationDetailsResponse,
|
||||||
|
ProviderOrganizationResponse,
|
||||||
|
} from "../models/response/provider/providerOrganizationResponse";
|
||||||
|
import { ProviderResponse } from "../models/response/provider/providerResponse";
|
||||||
|
import { ProviderUserBulkPublicKeyResponse } from "../models/response/provider/providerUserBulkPublicKeyResponse";
|
||||||
|
import { ProviderUserBulkResponse } from "../models/response/provider/providerUserBulkResponse";
|
||||||
|
import {
|
||||||
|
ProviderUserResponse,
|
||||||
|
ProviderUserUserDetailsResponse,
|
||||||
|
} from "../models/response/provider/providerUserResponse";
|
||||||
|
import { SelectionReadOnlyResponse } from "../models/response/selectionReadOnlyResponse";
|
||||||
|
import { SendAccessResponse } from "../models/response/sendAccessResponse";
|
||||||
|
import { SendFileDownloadDataResponse } from "../models/response/sendFileDownloadDataResponse";
|
||||||
|
import { SendFileUploadDataResponse } from "../models/response/sendFileUploadDataResponse";
|
||||||
|
import { SendResponse } from "../models/response/sendResponse";
|
||||||
|
import { SubscriptionResponse } from "../models/response/subscriptionResponse";
|
||||||
|
import { SyncResponse } from "../models/response/syncResponse";
|
||||||
|
import { TaxInfoResponse } from "../models/response/taxInfoResponse";
|
||||||
|
import { TaxRateResponse } from "../models/response/taxRateResponse";
|
||||||
|
import { TwoFactorAuthenticatorResponse } from "../models/response/twoFactorAuthenticatorResponse";
|
||||||
|
import { TwoFactorDuoResponse } from "../models/response/twoFactorDuoResponse";
|
||||||
|
import { TwoFactorEmailResponse } from "../models/response/twoFactorEmailResponse";
|
||||||
|
import { TwoFactorProviderResponse } from "../models/response/twoFactorProviderResponse";
|
||||||
|
import { TwoFactorRecoverResponse } from "../models/response/twoFactorRescoverResponse";
|
||||||
|
import {
|
||||||
|
ChallengeResponse,
|
||||||
|
TwoFactorWebAuthnResponse,
|
||||||
|
} from "../models/response/twoFactorWebAuthnResponse";
|
||||||
|
import { TwoFactorYubiKeyResponse } from "../models/response/twoFactorYubiKeyResponse";
|
||||||
|
import { UserKeyResponse } from "../models/response/userKeyResponse";
|
||||||
|
import { SendAccessView } from "../models/view/sendAccessView";
|
||||||
|
|
||||||
|
export abstract class ApiService {
|
||||||
|
postIdentityToken: (
|
||||||
|
request: PasswordTokenRequest | SsoTokenRequest | ApiTokenRequest
|
||||||
|
) => Promise<IdentityTokenResponse | IdentityTwoFactorResponse | IdentityCaptchaResponse>;
|
||||||
|
refreshIdentityToken: () => Promise<any>;
|
||||||
|
|
||||||
|
getProfile: () => Promise<ProfileResponse>;
|
||||||
|
getUserBilling: () => Promise<BillingResponse>;
|
||||||
|
getUserSubscription: () => Promise<SubscriptionResponse>;
|
||||||
|
getTaxInfo: () => Promise<TaxInfoResponse>;
|
||||||
|
putProfile: (request: UpdateProfileRequest) => Promise<ProfileResponse>;
|
||||||
|
putTaxInfo: (request: TaxInfoUpdateRequest) => Promise<any>;
|
||||||
|
postPrelogin: (request: PreloginRequest) => Promise<PreloginResponse>;
|
||||||
|
postEmailToken: (request: EmailTokenRequest) => Promise<any>;
|
||||||
|
postEmail: (request: EmailRequest) => Promise<any>;
|
||||||
|
postPassword: (request: PasswordRequest) => Promise<any>;
|
||||||
|
setPassword: (request: SetPasswordRequest) => Promise<any>;
|
||||||
|
postSetKeyConnectorKey: (request: SetKeyConnectorKeyRequest) => Promise<any>;
|
||||||
|
postSecurityStamp: (request: SecretVerificationRequest) => Promise<any>;
|
||||||
|
deleteAccount: (request: SecretVerificationRequest) => Promise<any>;
|
||||||
|
getAccountRevisionDate: () => Promise<number>;
|
||||||
|
postPasswordHint: (request: PasswordHintRequest) => Promise<any>;
|
||||||
|
postRegister: (request: RegisterRequest) => Promise<any>;
|
||||||
|
postPremium: (data: FormData) => Promise<PaymentResponse>;
|
||||||
|
postIapCheck: (request: IapCheckRequest) => Promise<any>;
|
||||||
|
postReinstatePremium: () => Promise<any>;
|
||||||
|
postCancelPremium: () => Promise<any>;
|
||||||
|
postAccountStorage: (request: StorageRequest) => Promise<PaymentResponse>;
|
||||||
|
postAccountPayment: (request: PaymentRequest) => Promise<any>;
|
||||||
|
postAccountLicense: (data: FormData) => Promise<any>;
|
||||||
|
postAccountKey: (request: UpdateKeyRequest) => Promise<any>;
|
||||||
|
postAccountKeys: (request: KeysRequest) => Promise<any>;
|
||||||
|
postAccountVerifyEmail: () => Promise<any>;
|
||||||
|
postAccountVerifyEmailToken: (request: VerifyEmailRequest) => Promise<any>;
|
||||||
|
postAccountVerifyPassword: (request: SecretVerificationRequest) => Promise<any>;
|
||||||
|
postAccountRecoverDelete: (request: DeleteRecoverRequest) => Promise<any>;
|
||||||
|
postAccountRecoverDeleteToken: (request: VerifyDeleteRecoverRequest) => Promise<any>;
|
||||||
|
postAccountKdf: (request: KdfRequest) => Promise<any>;
|
||||||
|
postUserApiKey: (id: string, request: SecretVerificationRequest) => Promise<ApiKeyResponse>;
|
||||||
|
postUserRotateApiKey: (id: string, request: SecretVerificationRequest) => Promise<ApiKeyResponse>;
|
||||||
|
putUpdateTempPassword: (request: UpdateTempPasswordRequest) => Promise<any>;
|
||||||
|
postAccountRequestOTP: () => Promise<void>;
|
||||||
|
postAccountVerifyOTP: (request: VerifyOTPRequest) => Promise<void>;
|
||||||
|
postConvertToKeyConnector: () => Promise<void>;
|
||||||
|
|
||||||
|
getFolder: (id: string) => Promise<FolderResponse>;
|
||||||
|
postFolder: (request: FolderRequest) => Promise<FolderResponse>;
|
||||||
|
putFolder: (id: string, request: FolderRequest) => Promise<FolderResponse>;
|
||||||
|
deleteFolder: (id: string) => Promise<any>;
|
||||||
|
|
||||||
|
getSend: (id: string) => Promise<SendResponse>;
|
||||||
|
postSendAccess: (
|
||||||
|
id: string,
|
||||||
|
request: SendAccessRequest,
|
||||||
|
apiUrl?: string
|
||||||
|
) => Promise<SendAccessResponse>;
|
||||||
|
getSends: () => Promise<ListResponse<SendResponse>>;
|
||||||
|
postSend: (request: SendRequest) => Promise<SendResponse>;
|
||||||
|
postFileTypeSend: (request: SendRequest) => Promise<SendFileUploadDataResponse>;
|
||||||
|
postSendFile: (sendId: string, fileId: string, data: FormData) => Promise<any>;
|
||||||
|
/**
|
||||||
|
* @deprecated Mar 25 2021: This method has been deprecated in favor of direct uploads.
|
||||||
|
* This method still exists for backward compatibility with old server versions.
|
||||||
|
*/
|
||||||
|
postSendFileLegacy: (data: FormData) => Promise<SendResponse>;
|
||||||
|
putSend: (id: string, request: SendRequest) => Promise<SendResponse>;
|
||||||
|
putSendRemovePassword: (id: string) => Promise<SendResponse>;
|
||||||
|
deleteSend: (id: string) => Promise<any>;
|
||||||
|
getSendFileDownloadData: (
|
||||||
|
send: SendAccessView,
|
||||||
|
request: SendAccessRequest,
|
||||||
|
apiUrl?: string
|
||||||
|
) => Promise<SendFileDownloadDataResponse>;
|
||||||
|
renewSendFileUploadUrl: (sendId: string, fileId: string) => Promise<SendFileUploadDataResponse>;
|
||||||
|
|
||||||
|
getCipher: (id: string) => Promise<CipherResponse>;
|
||||||
|
getCipherAdmin: (id: string) => Promise<CipherResponse>;
|
||||||
|
getAttachmentData: (
|
||||||
|
cipherId: string,
|
||||||
|
attachmentId: string,
|
||||||
|
emergencyAccessId?: string
|
||||||
|
) => Promise<AttachmentResponse>;
|
||||||
|
getCiphersOrganization: (organizationId: string) => Promise<ListResponse<CipherResponse>>;
|
||||||
|
postCipher: (request: CipherRequest) => Promise<CipherResponse>;
|
||||||
|
postCipherCreate: (request: CipherCreateRequest) => Promise<CipherResponse>;
|
||||||
|
postCipherAdmin: (request: CipherCreateRequest) => Promise<CipherResponse>;
|
||||||
|
putCipher: (id: string, request: CipherRequest) => Promise<CipherResponse>;
|
||||||
|
putCipherAdmin: (id: string, request: CipherRequest) => Promise<CipherResponse>;
|
||||||
|
deleteCipher: (id: string) => Promise<any>;
|
||||||
|
deleteCipherAdmin: (id: string) => Promise<any>;
|
||||||
|
deleteManyCiphers: (request: CipherBulkDeleteRequest) => Promise<any>;
|
||||||
|
deleteManyCiphersAdmin: (request: CipherBulkDeleteRequest) => Promise<any>;
|
||||||
|
putMoveCiphers: (request: CipherBulkMoveRequest) => Promise<any>;
|
||||||
|
putShareCipher: (id: string, request: CipherShareRequest) => Promise<CipherResponse>;
|
||||||
|
putShareCiphers: (request: CipherBulkShareRequest) => Promise<any>;
|
||||||
|
putCipherCollections: (id: string, request: CipherCollectionsRequest) => Promise<any>;
|
||||||
|
putCipherCollectionsAdmin: (id: string, request: CipherCollectionsRequest) => Promise<any>;
|
||||||
|
postPurgeCiphers: (request: SecretVerificationRequest, organizationId?: string) => Promise<any>;
|
||||||
|
postImportCiphers: (request: ImportCiphersRequest) => Promise<any>;
|
||||||
|
postImportOrganizationCiphers: (
|
||||||
|
organizationId: string,
|
||||||
|
request: ImportOrganizationCiphersRequest
|
||||||
|
) => Promise<any>;
|
||||||
|
putDeleteCipher: (id: string) => Promise<any>;
|
||||||
|
putDeleteCipherAdmin: (id: string) => Promise<any>;
|
||||||
|
putDeleteManyCiphers: (request: CipherBulkDeleteRequest) => Promise<any>;
|
||||||
|
putDeleteManyCiphersAdmin: (request: CipherBulkDeleteRequest) => Promise<any>;
|
||||||
|
putRestoreCipher: (id: string) => Promise<CipherResponse>;
|
||||||
|
putRestoreCipherAdmin: (id: string) => Promise<CipherResponse>;
|
||||||
|
putRestoreManyCiphers: (
|
||||||
|
request: CipherBulkRestoreRequest
|
||||||
|
) => Promise<ListResponse<CipherResponse>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Mar 25 2021: This method has been deprecated in favor of direct uploads.
|
||||||
|
* This method still exists for backward compatibility with old server versions.
|
||||||
|
*/
|
||||||
|
postCipherAttachmentLegacy: (id: string, data: FormData) => Promise<CipherResponse>;
|
||||||
|
/**
|
||||||
|
* @deprecated Mar 25 2021: This method has been deprecated in favor of direct uploads.
|
||||||
|
* This method still exists for backward compatibility with old server versions.
|
||||||
|
*/
|
||||||
|
postCipherAttachmentAdminLegacy: (id: string, data: FormData) => Promise<CipherResponse>;
|
||||||
|
postCipherAttachment: (
|
||||||
|
id: string,
|
||||||
|
request: AttachmentRequest
|
||||||
|
) => Promise<AttachmentUploadDataResponse>;
|
||||||
|
deleteCipherAttachment: (id: string, attachmentId: string) => Promise<any>;
|
||||||
|
deleteCipherAttachmentAdmin: (id: string, attachmentId: string) => Promise<any>;
|
||||||
|
postShareCipherAttachment: (
|
||||||
|
id: string,
|
||||||
|
attachmentId: string,
|
||||||
|
data: FormData,
|
||||||
|
organizationId: string
|
||||||
|
) => Promise<any>;
|
||||||
|
renewAttachmentUploadUrl: (
|
||||||
|
id: string,
|
||||||
|
attachmentId: string
|
||||||
|
) => Promise<AttachmentUploadDataResponse>;
|
||||||
|
postAttachmentFile: (id: string, attachmentId: string, data: FormData) => Promise<any>;
|
||||||
|
|
||||||
|
getCollectionDetails: (
|
||||||
|
organizationId: string,
|
||||||
|
id: string
|
||||||
|
) => Promise<CollectionGroupDetailsResponse>;
|
||||||
|
getUserCollections: () => Promise<ListResponse<CollectionResponse>>;
|
||||||
|
getCollections: (organizationId: string) => Promise<ListResponse<CollectionResponse>>;
|
||||||
|
getCollectionUsers: (organizationId: string, id: string) => Promise<SelectionReadOnlyResponse[]>;
|
||||||
|
postCollection: (
|
||||||
|
organizationId: string,
|
||||||
|
request: CollectionRequest
|
||||||
|
) => Promise<CollectionResponse>;
|
||||||
|
putCollectionUsers: (
|
||||||
|
organizationId: string,
|
||||||
|
id: string,
|
||||||
|
request: SelectionReadOnlyRequest[]
|
||||||
|
) => Promise<any>;
|
||||||
|
putCollection: (
|
||||||
|
organizationId: string,
|
||||||
|
id: string,
|
||||||
|
request: CollectionRequest
|
||||||
|
) => Promise<CollectionResponse>;
|
||||||
|
deleteCollection: (organizationId: string, id: string) => Promise<any>;
|
||||||
|
deleteCollectionUser: (
|
||||||
|
organizationId: string,
|
||||||
|
id: string,
|
||||||
|
organizationUserId: string
|
||||||
|
) => Promise<any>;
|
||||||
|
|
||||||
|
getGroupDetails: (organizationId: string, id: string) => Promise<GroupDetailsResponse>;
|
||||||
|
getGroups: (organizationId: string) => Promise<ListResponse<GroupResponse>>;
|
||||||
|
getGroupUsers: (organizationId: string, id: string) => Promise<string[]>;
|
||||||
|
postGroup: (organizationId: string, request: GroupRequest) => Promise<GroupResponse>;
|
||||||
|
putGroup: (organizationId: string, id: string, request: GroupRequest) => Promise<GroupResponse>;
|
||||||
|
putGroupUsers: (organizationId: string, id: string, request: string[]) => Promise<any>;
|
||||||
|
deleteGroup: (organizationId: string, id: string) => Promise<any>;
|
||||||
|
deleteGroupUser: (organizationId: string, id: string, organizationUserId: string) => Promise<any>;
|
||||||
|
|
||||||
|
getPolicy: (organizationId: string, type: PolicyType) => Promise<PolicyResponse>;
|
||||||
|
getPolicies: (organizationId: string) => Promise<ListResponse<PolicyResponse>>;
|
||||||
|
getPoliciesByToken: (
|
||||||
|
organizationId: string,
|
||||||
|
token: string,
|
||||||
|
email: string,
|
||||||
|
organizationUserId: string
|
||||||
|
) => Promise<ListResponse<PolicyResponse>>;
|
||||||
|
getPoliciesByInvitedUser: (
|
||||||
|
organizationId: string,
|
||||||
|
userId: string
|
||||||
|
) => Promise<ListResponse<PolicyResponse>>;
|
||||||
|
putPolicy: (
|
||||||
|
organizationId: string,
|
||||||
|
type: PolicyType,
|
||||||
|
request: PolicyRequest
|
||||||
|
) => Promise<PolicyResponse>;
|
||||||
|
|
||||||
|
getOrganizationUser: (
|
||||||
|
organizationId: string,
|
||||||
|
id: string
|
||||||
|
) => Promise<OrganizationUserDetailsResponse>;
|
||||||
|
getOrganizationUserGroups: (organizationId: string, id: string) => Promise<string[]>;
|
||||||
|
getOrganizationUsers: (
|
||||||
|
organizationId: string
|
||||||
|
) => Promise<ListResponse<OrganizationUserUserDetailsResponse>>;
|
||||||
|
getOrganizationUserResetPasswordDetails: (
|
||||||
|
organizationId: string,
|
||||||
|
id: string
|
||||||
|
) => Promise<OrganizationUserResetPasswordDetailsReponse>;
|
||||||
|
postOrganizationUserInvite: (
|
||||||
|
organizationId: string,
|
||||||
|
request: OrganizationUserInviteRequest
|
||||||
|
) => Promise<any>;
|
||||||
|
postOrganizationUserReinvite: (organizationId: string, id: string) => Promise<any>;
|
||||||
|
postManyOrganizationUserReinvite: (
|
||||||
|
organizationId: string,
|
||||||
|
request: OrganizationUserBulkRequest
|
||||||
|
) => Promise<ListResponse<OrganizationUserBulkResponse>>;
|
||||||
|
postOrganizationUserAccept: (
|
||||||
|
organizationId: string,
|
||||||
|
id: string,
|
||||||
|
request: OrganizationUserAcceptRequest
|
||||||
|
) => Promise<any>;
|
||||||
|
postOrganizationUserConfirm: (
|
||||||
|
organizationId: string,
|
||||||
|
id: string,
|
||||||
|
request: OrganizationUserConfirmRequest
|
||||||
|
) => Promise<any>;
|
||||||
|
postOrganizationUsersPublicKey: (
|
||||||
|
organizationId: string,
|
||||||
|
request: OrganizationUserBulkRequest
|
||||||
|
) => Promise<ListResponse<OrganizationUserBulkPublicKeyResponse>>;
|
||||||
|
postOrganizationUserBulkConfirm: (
|
||||||
|
organizationId: string,
|
||||||
|
request: OrganizationUserBulkConfirmRequest
|
||||||
|
) => Promise<ListResponse<OrganizationUserBulkResponse>>;
|
||||||
|
|
||||||
|
putOrganizationUser: (
|
||||||
|
organizationId: string,
|
||||||
|
id: string,
|
||||||
|
request: OrganizationUserUpdateRequest
|
||||||
|
) => Promise<any>;
|
||||||
|
putOrganizationUserGroups: (
|
||||||
|
organizationId: string,
|
||||||
|
id: string,
|
||||||
|
request: OrganizationUserUpdateGroupsRequest
|
||||||
|
) => Promise<any>;
|
||||||
|
putOrganizationUserResetPasswordEnrollment: (
|
||||||
|
organizationId: string,
|
||||||
|
userId: string,
|
||||||
|
request: OrganizationUserResetPasswordEnrollmentRequest
|
||||||
|
) => Promise<any>;
|
||||||
|
putOrganizationUserResetPassword: (
|
||||||
|
organizationId: string,
|
||||||
|
id: string,
|
||||||
|
request: OrganizationUserResetPasswordRequest
|
||||||
|
) => Promise<any>;
|
||||||
|
deleteOrganizationUser: (organizationId: string, id: string) => Promise<any>;
|
||||||
|
deleteManyOrganizationUsers: (
|
||||||
|
organizationId: string,
|
||||||
|
request: OrganizationUserBulkRequest
|
||||||
|
) => Promise<ListResponse<OrganizationUserBulkResponse>>;
|
||||||
|
|
||||||
|
getSync: () => Promise<SyncResponse>;
|
||||||
|
postImportDirectory: (organizationId: string, request: ImportDirectoryRequest) => Promise<any>;
|
||||||
|
postPublicImportDirectory: (request: OrganizationImportRequest) => Promise<any>;
|
||||||
|
|
||||||
|
getSettingsDomains: () => Promise<DomainsResponse>;
|
||||||
|
putSettingsDomains: (request: UpdateDomainsRequest) => Promise<DomainsResponse>;
|
||||||
|
|
||||||
|
getTwoFactorProviders: () => Promise<ListResponse<TwoFactorProviderResponse>>;
|
||||||
|
getTwoFactorOrganizationProviders: (
|
||||||
|
organizationId: string
|
||||||
|
) => Promise<ListResponse<TwoFactorProviderResponse>>;
|
||||||
|
getTwoFactorAuthenticator: (
|
||||||
|
request: SecretVerificationRequest
|
||||||
|
) => Promise<TwoFactorAuthenticatorResponse>;
|
||||||
|
getTwoFactorEmail: (request: SecretVerificationRequest) => Promise<TwoFactorEmailResponse>;
|
||||||
|
getTwoFactorDuo: (request: SecretVerificationRequest) => Promise<TwoFactorDuoResponse>;
|
||||||
|
getTwoFactorOrganizationDuo: (
|
||||||
|
organizationId: string,
|
||||||
|
request: SecretVerificationRequest
|
||||||
|
) => Promise<TwoFactorDuoResponse>;
|
||||||
|
getTwoFactorYubiKey: (request: SecretVerificationRequest) => Promise<TwoFactorYubiKeyResponse>;
|
||||||
|
getTwoFactorWebAuthn: (request: SecretVerificationRequest) => Promise<TwoFactorWebAuthnResponse>;
|
||||||
|
getTwoFactorWebAuthnChallenge: (request: SecretVerificationRequest) => Promise<ChallengeResponse>;
|
||||||
|
getTwoFactorRecover: (request: SecretVerificationRequest) => Promise<TwoFactorRecoverResponse>;
|
||||||
|
putTwoFactorAuthenticator: (
|
||||||
|
request: UpdateTwoFactorAuthenticatorRequest
|
||||||
|
) => Promise<TwoFactorAuthenticatorResponse>;
|
||||||
|
putTwoFactorEmail: (request: UpdateTwoFactorEmailRequest) => Promise<TwoFactorEmailResponse>;
|
||||||
|
putTwoFactorDuo: (request: UpdateTwoFactorDuoRequest) => Promise<TwoFactorDuoResponse>;
|
||||||
|
putTwoFactorOrganizationDuo: (
|
||||||
|
organizationId: string,
|
||||||
|
request: UpdateTwoFactorDuoRequest
|
||||||
|
) => Promise<TwoFactorDuoResponse>;
|
||||||
|
putTwoFactorYubiKey: (
|
||||||
|
request: UpdateTwoFactorYubioOtpRequest
|
||||||
|
) => Promise<TwoFactorYubiKeyResponse>;
|
||||||
|
putTwoFactorWebAuthn: (
|
||||||
|
request: UpdateTwoFactorWebAuthnRequest
|
||||||
|
) => Promise<TwoFactorWebAuthnResponse>;
|
||||||
|
deleteTwoFactorWebAuthn: (
|
||||||
|
request: UpdateTwoFactorWebAuthnDeleteRequest
|
||||||
|
) => Promise<TwoFactorWebAuthnResponse>;
|
||||||
|
putTwoFactorDisable: (request: TwoFactorProviderRequest) => Promise<TwoFactorProviderResponse>;
|
||||||
|
putTwoFactorOrganizationDisable: (
|
||||||
|
organizationId: string,
|
||||||
|
request: TwoFactorProviderRequest
|
||||||
|
) => Promise<TwoFactorProviderResponse>;
|
||||||
|
postTwoFactorRecover: (request: TwoFactorRecoveryRequest) => Promise<any>;
|
||||||
|
postTwoFactorEmailSetup: (request: TwoFactorEmailRequest) => Promise<any>;
|
||||||
|
postTwoFactorEmail: (request: TwoFactorEmailRequest) => Promise<any>;
|
||||||
|
|
||||||
|
getEmergencyAccessTrusted: () => Promise<ListResponse<EmergencyAccessGranteeDetailsResponse>>;
|
||||||
|
getEmergencyAccessGranted: () => Promise<ListResponse<EmergencyAccessGrantorDetailsResponse>>;
|
||||||
|
getEmergencyAccess: (id: string) => Promise<EmergencyAccessGranteeDetailsResponse>;
|
||||||
|
getEmergencyGrantorPolicies: (id: string) => Promise<ListResponse<PolicyResponse>>;
|
||||||
|
putEmergencyAccess: (id: string, request: EmergencyAccessUpdateRequest) => Promise<any>;
|
||||||
|
deleteEmergencyAccess: (id: string) => Promise<any>;
|
||||||
|
postEmergencyAccessInvite: (request: EmergencyAccessInviteRequest) => Promise<any>;
|
||||||
|
postEmergencyAccessReinvite: (id: string) => Promise<any>;
|
||||||
|
postEmergencyAccessAccept: (id: string, request: EmergencyAccessAcceptRequest) => Promise<any>;
|
||||||
|
postEmergencyAccessConfirm: (id: string, request: EmergencyAccessConfirmRequest) => Promise<any>;
|
||||||
|
postEmergencyAccessInitiate: (id: string) => Promise<any>;
|
||||||
|
postEmergencyAccessApprove: (id: string) => Promise<any>;
|
||||||
|
postEmergencyAccessReject: (id: string) => Promise<any>;
|
||||||
|
postEmergencyAccessTakeover: (id: string) => Promise<EmergencyAccessTakeoverResponse>;
|
||||||
|
postEmergencyAccessPassword: (
|
||||||
|
id: string,
|
||||||
|
request: EmergencyAccessPasswordRequest
|
||||||
|
) => Promise<any>;
|
||||||
|
postEmergencyAccessView: (id: string) => Promise<EmergencyAccessViewResponse>;
|
||||||
|
|
||||||
|
getOrganization: (id: string) => Promise<OrganizationResponse>;
|
||||||
|
getOrganizationBilling: (id: string) => Promise<BillingResponse>;
|
||||||
|
getOrganizationSubscription: (id: string) => Promise<OrganizationSubscriptionResponse>;
|
||||||
|
getOrganizationLicense: (id: string, installationId: string) => Promise<any>;
|
||||||
|
getOrganizationTaxInfo: (id: string) => Promise<TaxInfoResponse>;
|
||||||
|
getOrganizationAutoEnrollStatus: (
|
||||||
|
identifier: string
|
||||||
|
) => Promise<OrganizationAutoEnrollStatusResponse>;
|
||||||
|
getOrganizationSso: (id: string) => Promise<OrganizationSsoResponse>;
|
||||||
|
postOrganization: (request: OrganizationCreateRequest) => Promise<OrganizationResponse>;
|
||||||
|
putOrganization: (
|
||||||
|
id: string,
|
||||||
|
request: OrganizationUpdateRequest
|
||||||
|
) => Promise<OrganizationResponse>;
|
||||||
|
putOrganizationTaxInfo: (id: string, request: OrganizationTaxInfoUpdateRequest) => Promise<any>;
|
||||||
|
postLeaveOrganization: (id: string) => Promise<any>;
|
||||||
|
postOrganizationLicense: (data: FormData) => Promise<OrganizationResponse>;
|
||||||
|
postOrganizationLicenseUpdate: (id: string, data: FormData) => Promise<any>;
|
||||||
|
postOrganizationApiKey: (
|
||||||
|
id: string,
|
||||||
|
request: SecretVerificationRequest
|
||||||
|
) => Promise<ApiKeyResponse>;
|
||||||
|
postOrganizationRotateApiKey: (
|
||||||
|
id: string,
|
||||||
|
request: SecretVerificationRequest
|
||||||
|
) => Promise<ApiKeyResponse>;
|
||||||
|
postOrganizationSso: (
|
||||||
|
id: string,
|
||||||
|
request: OrganizationSsoRequest
|
||||||
|
) => Promise<OrganizationSsoResponse>;
|
||||||
|
postOrganizationUpgrade: (
|
||||||
|
id: string,
|
||||||
|
request: OrganizationUpgradeRequest
|
||||||
|
) => Promise<PaymentResponse>;
|
||||||
|
postOrganizationUpdateSubscription: (
|
||||||
|
id: string,
|
||||||
|
request: OrganizationSubscriptionUpdateRequest
|
||||||
|
) => Promise<void>;
|
||||||
|
postOrganizationSeat: (id: string, request: SeatRequest) => Promise<PaymentResponse>;
|
||||||
|
postOrganizationStorage: (id: string, request: StorageRequest) => Promise<any>;
|
||||||
|
postOrganizationPayment: (id: string, request: PaymentRequest) => Promise<any>;
|
||||||
|
postOrganizationVerifyBank: (id: string, request: VerifyBankRequest) => Promise<any>;
|
||||||
|
postOrganizationCancel: (id: string) => Promise<any>;
|
||||||
|
postOrganizationReinstate: (id: string) => Promise<any>;
|
||||||
|
deleteOrganization: (id: string, request: SecretVerificationRequest) => Promise<any>;
|
||||||
|
getPlans: () => Promise<ListResponse<PlanResponse>>;
|
||||||
|
getTaxRates: () => Promise<ListResponse<TaxRateResponse>>;
|
||||||
|
getOrganizationKeys: (id: string) => Promise<OrganizationKeysResponse>;
|
||||||
|
postOrganizationKeys: (
|
||||||
|
id: string,
|
||||||
|
request: OrganizationKeysRequest
|
||||||
|
) => Promise<OrganizationKeysResponse>;
|
||||||
|
|
||||||
|
postProviderSetup: (id: string, request: ProviderSetupRequest) => Promise<ProviderResponse>;
|
||||||
|
getProvider: (id: string) => Promise<ProviderResponse>;
|
||||||
|
putProvider: (id: string, request: ProviderUpdateRequest) => Promise<ProviderResponse>;
|
||||||
|
|
||||||
|
getProviderUsers: (providerId: string) => Promise<ListResponse<ProviderUserUserDetailsResponse>>;
|
||||||
|
getProviderUser: (providerId: string, id: string) => Promise<ProviderUserResponse>;
|
||||||
|
postProviderUserInvite: (providerId: string, request: ProviderUserInviteRequest) => Promise<any>;
|
||||||
|
postProviderUserReinvite: (providerId: string, id: string) => Promise<any>;
|
||||||
|
postManyProviderUserReinvite: (
|
||||||
|
providerId: string,
|
||||||
|
request: ProviderUserBulkRequest
|
||||||
|
) => Promise<ListResponse<ProviderUserBulkResponse>>;
|
||||||
|
postProviderUserAccept: (
|
||||||
|
providerId: string,
|
||||||
|
id: string,
|
||||||
|
request: ProviderUserAcceptRequest
|
||||||
|
) => Promise<any>;
|
||||||
|
postProviderUserConfirm: (
|
||||||
|
providerId: string,
|
||||||
|
id: string,
|
||||||
|
request: ProviderUserConfirmRequest
|
||||||
|
) => Promise<any>;
|
||||||
|
postProviderUsersPublicKey: (
|
||||||
|
providerId: string,
|
||||||
|
request: ProviderUserBulkRequest
|
||||||
|
) => Promise<ListResponse<ProviderUserBulkPublicKeyResponse>>;
|
||||||
|
postProviderUserBulkConfirm: (
|
||||||
|
providerId: string,
|
||||||
|
request: ProviderUserBulkConfirmRequest
|
||||||
|
) => Promise<ListResponse<ProviderUserBulkResponse>>;
|
||||||
|
putProviderUser: (
|
||||||
|
providerId: string,
|
||||||
|
id: string,
|
||||||
|
request: ProviderUserUpdateRequest
|
||||||
|
) => Promise<any>;
|
||||||
|
deleteProviderUser: (organizationId: string, id: string) => Promise<any>;
|
||||||
|
deleteManyProviderUsers: (
|
||||||
|
providerId: string,
|
||||||
|
request: ProviderUserBulkRequest
|
||||||
|
) => Promise<ListResponse<ProviderUserBulkResponse>>;
|
||||||
|
getProviderClients: (
|
||||||
|
providerId: string
|
||||||
|
) => Promise<ListResponse<ProviderOrganizationOrganizationDetailsResponse>>;
|
||||||
|
postProviderAddOrganization: (
|
||||||
|
providerId: string,
|
||||||
|
request: ProviderAddOrganizationRequest
|
||||||
|
) => Promise<any>;
|
||||||
|
postProviderCreateOrganization: (
|
||||||
|
providerId: string,
|
||||||
|
request: ProviderOrganizationCreateRequest
|
||||||
|
) => Promise<ProviderOrganizationResponse>;
|
||||||
|
deleteProviderOrganization: (providerId: string, organizationId: string) => Promise<any>;
|
||||||
|
|
||||||
|
getEvents: (start: string, end: string, token: string) => Promise<ListResponse<EventResponse>>;
|
||||||
|
getEventsCipher: (
|
||||||
|
id: string,
|
||||||
|
start: string,
|
||||||
|
end: string,
|
||||||
|
token: string
|
||||||
|
) => Promise<ListResponse<EventResponse>>;
|
||||||
|
getEventsOrganization: (
|
||||||
|
id: string,
|
||||||
|
start: string,
|
||||||
|
end: string,
|
||||||
|
token: string
|
||||||
|
) => Promise<ListResponse<EventResponse>>;
|
||||||
|
getEventsOrganizationUser: (
|
||||||
|
organizationId: string,
|
||||||
|
id: string,
|
||||||
|
start: string,
|
||||||
|
end: string,
|
||||||
|
token: string
|
||||||
|
) => Promise<ListResponse<EventResponse>>;
|
||||||
|
getEventsProvider: (
|
||||||
|
id: string,
|
||||||
|
start: string,
|
||||||
|
end: string,
|
||||||
|
token: string
|
||||||
|
) => Promise<ListResponse<EventResponse>>;
|
||||||
|
getEventsProviderUser: (
|
||||||
|
providerId: string,
|
||||||
|
id: string,
|
||||||
|
start: string,
|
||||||
|
end: string,
|
||||||
|
token: string
|
||||||
|
) => Promise<ListResponse<EventResponse>>;
|
||||||
|
postEventsCollect: (request: EventRequest[]) => Promise<any>;
|
||||||
|
|
||||||
|
deleteSsoUser: (organizationId: string) => Promise<any>;
|
||||||
|
getSsoUserIdentifier: () => Promise<string>;
|
||||||
|
|
||||||
|
getUserPublicKey: (id: string) => Promise<UserKeyResponse>;
|
||||||
|
|
||||||
|
getHibpBreach: (username: string) => Promise<BreachAccountResponse[]>;
|
||||||
|
|
||||||
|
postBitPayInvoice: (request: BitPayInvoiceRequest) => Promise<string>;
|
||||||
|
postSetupPayment: () => Promise<string>;
|
||||||
|
|
||||||
|
getActiveBearerToken: () => Promise<string>;
|
||||||
|
fetch: (request: Request) => Promise<Response>;
|
||||||
|
nativeFetch: (request: Request) => Promise<Response>;
|
||||||
|
|
||||||
|
preValidateSso: (identifier: string) => Promise<boolean>;
|
||||||
|
|
||||||
|
postCreateSponsorship: (
|
||||||
|
sponsorshipOrgId: string,
|
||||||
|
request: OrganizationSponsorshipCreateRequest
|
||||||
|
) => Promise<void>;
|
||||||
|
deleteRevokeSponsorship: (sponsoringOrganizationId: string) => Promise<void>;
|
||||||
|
deleteRemoveSponsorship: (sponsoringOrgId: string) => Promise<void>;
|
||||||
|
postPreValidateSponsorshipToken: (sponsorshipToken: string) => Promise<boolean>;
|
||||||
|
postRedeemSponsorship: (
|
||||||
|
sponsorshipToken: string,
|
||||||
|
request: OrganizationSponsorshipRedeemRequest
|
||||||
|
) => Promise<void>;
|
||||||
|
postResendSponsorshipOffer: (sponsoringOrgId: string) => Promise<void>;
|
||||||
|
|
||||||
|
getUserKeyFromKeyConnector: (keyConnectorUrl: string) => Promise<KeyConnectorUserKeyResponse>;
|
||||||
|
postUserKeyToKeyConnector: (
|
||||||
|
keyConnectorUrl: string,
|
||||||
|
request: KeyConnectorUserKeyRequest
|
||||||
|
) => Promise<void>;
|
||||||
|
getKeyConnectorAlive: (keyConnectorUrl: string) => Promise<void>;
|
||||||
|
}
|
||||||
4
jslib/common/src/abstractions/appId.service.ts
Normal file
4
jslib/common/src/abstractions/appId.service.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export abstract class AppIdService {
|
||||||
|
getAppId: () => Promise<string>;
|
||||||
|
getAnonymousAppId: () => Promise<string>;
|
||||||
|
}
|
||||||
6
jslib/common/src/abstractions/audit.service.ts
Normal file
6
jslib/common/src/abstractions/audit.service.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { BreachAccountResponse } from "../models/response/breachAccountResponse";
|
||||||
|
|
||||||
|
export abstract class AuditService {
|
||||||
|
passwordLeaked: (password: string) => Promise<number>;
|
||||||
|
breachedAccounts: (username: string) => Promise<BreachAccountResponse[]>;
|
||||||
|
}
|
||||||
25
jslib/common/src/abstractions/auth.service.ts
Normal file
25
jslib/common/src/abstractions/auth.service.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { AuthResult } from "../models/domain/authResult";
|
||||||
|
import {
|
||||||
|
ApiLogInCredentials,
|
||||||
|
PasswordLogInCredentials,
|
||||||
|
SsoLogInCredentials,
|
||||||
|
} from "../models/domain/logInCredentials";
|
||||||
|
import { SymmetricCryptoKey } from "../models/domain/symmetricCryptoKey";
|
||||||
|
import { TokenRequestTwoFactor } from "../models/request/identityToken/tokenRequestTwoFactor";
|
||||||
|
|
||||||
|
export abstract class AuthService {
|
||||||
|
masterPasswordHash: string;
|
||||||
|
email: string;
|
||||||
|
logIn: (
|
||||||
|
credentials: ApiLogInCredentials | PasswordLogInCredentials | SsoLogInCredentials
|
||||||
|
) => Promise<AuthResult>;
|
||||||
|
logInTwoFactor: (
|
||||||
|
twoFactor: TokenRequestTwoFactor,
|
||||||
|
captchaResponse: string
|
||||||
|
) => Promise<AuthResult>;
|
||||||
|
logOut: (callback: () => void) => void;
|
||||||
|
makePreloginKey: (masterPassword: string, email: string) => Promise<SymmetricCryptoKey>;
|
||||||
|
authingWithApiKey: () => boolean;
|
||||||
|
authingWithSso: () => boolean;
|
||||||
|
authingWithPassword: () => boolean;
|
||||||
|
}
|
||||||
5
jslib/common/src/abstractions/broadcaster.service.ts
Normal file
5
jslib/common/src/abstractions/broadcaster.service.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export abstract class BroadcasterService {
|
||||||
|
send: (message: any, id?: string) => void;
|
||||||
|
subscribe: (id: string, messageCallback: (message: any) => any) => void;
|
||||||
|
unsubscribe: (id: string) => void;
|
||||||
|
}
|
||||||
79
jslib/common/src/abstractions/cipher.service.ts
Normal file
79
jslib/common/src/abstractions/cipher.service.ts
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import { CipherType } from "../enums/cipherType";
|
||||||
|
import { UriMatchType } from "../enums/uriMatchType";
|
||||||
|
import { CipherData } from "../models/data/cipherData";
|
||||||
|
import { Cipher } from "../models/domain/cipher";
|
||||||
|
import { Field } from "../models/domain/field";
|
||||||
|
import { SymmetricCryptoKey } from "../models/domain/symmetricCryptoKey";
|
||||||
|
import { CipherView } from "../models/view/cipherView";
|
||||||
|
import { FieldView } from "../models/view/fieldView";
|
||||||
|
|
||||||
|
export abstract class CipherService {
|
||||||
|
clearCache: (userId?: string) => Promise<void>;
|
||||||
|
encrypt: (
|
||||||
|
model: CipherView,
|
||||||
|
key?: SymmetricCryptoKey,
|
||||||
|
originalCipher?: Cipher
|
||||||
|
) => Promise<Cipher>;
|
||||||
|
encryptFields: (fieldsModel: FieldView[], key: SymmetricCryptoKey) => Promise<Field[]>;
|
||||||
|
encryptField: (fieldModel: FieldView, key: SymmetricCryptoKey) => Promise<Field>;
|
||||||
|
get: (id: string) => Promise<Cipher>;
|
||||||
|
getAll: () => Promise<Cipher[]>;
|
||||||
|
getAllDecrypted: () => Promise<CipherView[]>;
|
||||||
|
getAllDecryptedForGrouping: (groupingId: string, folder?: boolean) => Promise<CipherView[]>;
|
||||||
|
getAllDecryptedForUrl: (
|
||||||
|
url: string,
|
||||||
|
includeOtherTypes?: CipherType[],
|
||||||
|
defaultMatch?: UriMatchType
|
||||||
|
) => Promise<CipherView[]>;
|
||||||
|
getAllFromApiForOrganization: (organizationId: string) => Promise<CipherView[]>;
|
||||||
|
getLastUsedForUrl: (url: string, autofillOnPageLoad: boolean) => Promise<CipherView>;
|
||||||
|
getLastLaunchedForUrl: (url: string, autofillOnPageLoad: boolean) => Promise<CipherView>;
|
||||||
|
getNextCipherForUrl: (url: string) => Promise<CipherView>;
|
||||||
|
updateLastUsedIndexForUrl: (url: string) => void;
|
||||||
|
updateLastUsedDate: (id: string) => Promise<void>;
|
||||||
|
updateLastLaunchedDate: (id: string) => Promise<void>;
|
||||||
|
saveNeverDomain: (domain: string) => Promise<void>;
|
||||||
|
saveWithServer: (cipher: Cipher) => Promise<any>;
|
||||||
|
shareWithServer: (
|
||||||
|
cipher: CipherView,
|
||||||
|
organizationId: string,
|
||||||
|
collectionIds: string[]
|
||||||
|
) => Promise<any>;
|
||||||
|
shareManyWithServer: (
|
||||||
|
ciphers: CipherView[],
|
||||||
|
organizationId: string,
|
||||||
|
collectionIds: string[]
|
||||||
|
) => Promise<any>;
|
||||||
|
saveAttachmentWithServer: (
|
||||||
|
cipher: Cipher,
|
||||||
|
unencryptedFile: any,
|
||||||
|
admin?: boolean
|
||||||
|
) => Promise<Cipher>;
|
||||||
|
saveAttachmentRawWithServer: (
|
||||||
|
cipher: Cipher,
|
||||||
|
filename: string,
|
||||||
|
data: ArrayBuffer,
|
||||||
|
admin?: boolean
|
||||||
|
) => Promise<Cipher>;
|
||||||
|
saveCollectionsWithServer: (cipher: Cipher) => Promise<any>;
|
||||||
|
upsert: (cipher: CipherData | CipherData[]) => Promise<any>;
|
||||||
|
replace: (ciphers: { [id: string]: CipherData }) => Promise<any>;
|
||||||
|
clear: (userId: string) => Promise<any>;
|
||||||
|
moveManyWithServer: (ids: string[], folderId: string) => Promise<any>;
|
||||||
|
delete: (id: string | string[]) => Promise<any>;
|
||||||
|
deleteWithServer: (id: string) => Promise<any>;
|
||||||
|
deleteManyWithServer: (ids: string[]) => Promise<any>;
|
||||||
|
deleteAttachment: (id: string, attachmentId: string) => Promise<void>;
|
||||||
|
deleteAttachmentWithServer: (id: string, attachmentId: string) => Promise<void>;
|
||||||
|
sortCiphersByLastUsed: (a: any, b: any) => number;
|
||||||
|
sortCiphersByLastUsedThenName: (a: any, b: any) => number;
|
||||||
|
getLocaleSortingFunction: () => (a: CipherView, b: CipherView) => number;
|
||||||
|
softDelete: (id: string | string[]) => Promise<any>;
|
||||||
|
softDeleteWithServer: (id: string) => Promise<any>;
|
||||||
|
softDeleteManyWithServer: (ids: string[]) => Promise<any>;
|
||||||
|
restore: (
|
||||||
|
cipher: { id: string; revisionDate: string } | { id: string; revisionDate: string }[]
|
||||||
|
) => Promise<any>;
|
||||||
|
restoreWithServer: (id: string) => Promise<any>;
|
||||||
|
restoreManyWithServer: (ids: string[]) => Promise<any>;
|
||||||
|
}
|
||||||
19
jslib/common/src/abstractions/collection.service.ts
Normal file
19
jslib/common/src/abstractions/collection.service.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { CollectionData } from "../models/data/collectionData";
|
||||||
|
import { Collection } from "../models/domain/collection";
|
||||||
|
import { TreeNode } from "../models/domain/treeNode";
|
||||||
|
import { CollectionView } from "../models/view/collectionView";
|
||||||
|
|
||||||
|
export abstract class CollectionService {
|
||||||
|
clearCache: (userId?: string) => Promise<void>;
|
||||||
|
encrypt: (model: CollectionView) => Promise<Collection>;
|
||||||
|
decryptMany: (collections: Collection[]) => Promise<CollectionView[]>;
|
||||||
|
get: (id: string) => Promise<Collection>;
|
||||||
|
getAll: () => Promise<Collection[]>;
|
||||||
|
getAllDecrypted: () => Promise<CollectionView[]>;
|
||||||
|
getAllNested: (collections?: CollectionView[]) => Promise<TreeNode<CollectionView>[]>;
|
||||||
|
getNested: (id: string) => Promise<TreeNode<CollectionView>>;
|
||||||
|
upsert: (collection: CollectionData | CollectionData[]) => Promise<any>;
|
||||||
|
replace: (collections: { [id: string]: CollectionData }) => Promise<any>;
|
||||||
|
clear: (userId: string) => Promise<any>;
|
||||||
|
delete: (id: string | string[]) => Promise<any>;
|
||||||
|
}
|
||||||
86
jslib/common/src/abstractions/crypto.service.ts
Normal file
86
jslib/common/src/abstractions/crypto.service.ts
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import { HashPurpose } from "../enums/hashPurpose";
|
||||||
|
import { KdfType } from "../enums/kdfType";
|
||||||
|
import { KeySuffixOptions } from "../enums/keySuffixOptions";
|
||||||
|
import { EncArrayBuffer } from "../models/domain/encArrayBuffer";
|
||||||
|
import { EncString } from "../models/domain/encString";
|
||||||
|
import { SymmetricCryptoKey } from "../models/domain/symmetricCryptoKey";
|
||||||
|
import { ProfileOrganizationResponse } from "../models/response/profileOrganizationResponse";
|
||||||
|
import { ProfileProviderOrganizationResponse } from "../models/response/profileProviderOrganizationResponse";
|
||||||
|
import { ProfileProviderResponse } from "../models/response/profileProviderResponse";
|
||||||
|
|
||||||
|
export abstract class CryptoService {
|
||||||
|
setKey: (key: SymmetricCryptoKey) => Promise<any>;
|
||||||
|
setKeyHash: (keyHash: string) => Promise<void>;
|
||||||
|
setEncKey: (encKey: string) => Promise<void>;
|
||||||
|
setEncPrivateKey: (encPrivateKey: string) => Promise<void>;
|
||||||
|
setOrgKeys: (
|
||||||
|
orgs: ProfileOrganizationResponse[],
|
||||||
|
providerOrgs: ProfileProviderOrganizationResponse[]
|
||||||
|
) => Promise<void>;
|
||||||
|
setProviderKeys: (orgs: ProfileProviderResponse[]) => Promise<void>;
|
||||||
|
getKey: (keySuffix?: KeySuffixOptions, userId?: string) => Promise<SymmetricCryptoKey>;
|
||||||
|
getKeyFromStorage: (keySuffix: KeySuffixOptions, userId?: string) => Promise<SymmetricCryptoKey>;
|
||||||
|
getKeyHash: () => Promise<string>;
|
||||||
|
compareAndUpdateKeyHash: (masterPassword: string, key: SymmetricCryptoKey) => Promise<boolean>;
|
||||||
|
getEncKey: (key?: SymmetricCryptoKey) => Promise<SymmetricCryptoKey>;
|
||||||
|
getPublicKey: () => Promise<ArrayBuffer>;
|
||||||
|
getPrivateKey: () => Promise<ArrayBuffer>;
|
||||||
|
getFingerprint: (userId: string, publicKey?: ArrayBuffer) => Promise<string[]>;
|
||||||
|
getOrgKeys: () => Promise<Map<string, SymmetricCryptoKey>>;
|
||||||
|
getOrgKey: (orgId: string) => Promise<SymmetricCryptoKey>;
|
||||||
|
getProviderKey: (providerId: string) => Promise<SymmetricCryptoKey>;
|
||||||
|
hasKey: () => Promise<boolean>;
|
||||||
|
hasKeyInMemory: (userId?: string) => Promise<boolean>;
|
||||||
|
hasKeyStored: (keySuffix?: KeySuffixOptions, userId?: string) => Promise<boolean>;
|
||||||
|
hasEncKey: () => Promise<boolean>;
|
||||||
|
clearKey: (clearSecretStorage?: boolean, userId?: string) => Promise<any>;
|
||||||
|
clearKeyHash: () => Promise<any>;
|
||||||
|
clearEncKey: (memoryOnly?: boolean, userId?: string) => Promise<any>;
|
||||||
|
clearKeyPair: (memoryOnly?: boolean, userId?: string) => Promise<any>;
|
||||||
|
clearOrgKeys: (memoryOnly?: boolean, userId?: string) => Promise<any>;
|
||||||
|
clearProviderKeys: (memoryOnly?: boolean) => Promise<any>;
|
||||||
|
clearPinProtectedKey: () => Promise<any>;
|
||||||
|
clearKeys: (userId?: string) => Promise<any>;
|
||||||
|
toggleKey: () => Promise<any>;
|
||||||
|
makeKey: (
|
||||||
|
password: string,
|
||||||
|
salt: string,
|
||||||
|
kdf: KdfType,
|
||||||
|
kdfIterations: number
|
||||||
|
) => Promise<SymmetricCryptoKey>;
|
||||||
|
makeKeyFromPin: (
|
||||||
|
pin: string,
|
||||||
|
salt: string,
|
||||||
|
kdf: KdfType,
|
||||||
|
kdfIterations: number,
|
||||||
|
protectedKeyCs?: EncString
|
||||||
|
) => Promise<SymmetricCryptoKey>;
|
||||||
|
makeShareKey: () => Promise<[EncString, SymmetricCryptoKey]>;
|
||||||
|
makeKeyPair: (key?: SymmetricCryptoKey) => Promise<[string, EncString]>;
|
||||||
|
makePinKey: (
|
||||||
|
pin: string,
|
||||||
|
salt: string,
|
||||||
|
kdf: KdfType,
|
||||||
|
kdfIterations: number
|
||||||
|
) => Promise<SymmetricCryptoKey>;
|
||||||
|
makeSendKey: (keyMaterial: ArrayBuffer) => Promise<SymmetricCryptoKey>;
|
||||||
|
hashPassword: (
|
||||||
|
password: string,
|
||||||
|
key: SymmetricCryptoKey,
|
||||||
|
hashPurpose?: HashPurpose
|
||||||
|
) => Promise<string>;
|
||||||
|
makeEncKey: (key: SymmetricCryptoKey) => Promise<[SymmetricCryptoKey, EncString]>;
|
||||||
|
remakeEncKey: (
|
||||||
|
key: SymmetricCryptoKey,
|
||||||
|
encKey?: SymmetricCryptoKey
|
||||||
|
) => Promise<[SymmetricCryptoKey, EncString]>;
|
||||||
|
encrypt: (plainValue: string | ArrayBuffer, key?: SymmetricCryptoKey) => Promise<EncString>;
|
||||||
|
encryptToBytes: (plainValue: ArrayBuffer, key?: SymmetricCryptoKey) => Promise<EncArrayBuffer>;
|
||||||
|
rsaEncrypt: (data: ArrayBuffer, publicKey?: ArrayBuffer) => Promise<EncString>;
|
||||||
|
rsaDecrypt: (encValue: string, privateKeyValue?: ArrayBuffer) => Promise<ArrayBuffer>;
|
||||||
|
decryptToBytes: (encString: EncString, key?: SymmetricCryptoKey) => Promise<ArrayBuffer>;
|
||||||
|
decryptToUtf8: (encString: EncString, key?: SymmetricCryptoKey) => Promise<string>;
|
||||||
|
decryptFromBytes: (encBuf: ArrayBuffer, key: SymmetricCryptoKey) => Promise<ArrayBuffer>;
|
||||||
|
randomNumber: (min: number, max: number) => Promise<number>;
|
||||||
|
validateKey: (key: SymmetricCryptoKey) => Promise<boolean>;
|
||||||
|
}
|
||||||
62
jslib/common/src/abstractions/cryptoFunction.service.ts
Normal file
62
jslib/common/src/abstractions/cryptoFunction.service.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import { DecryptParameters } from "../models/domain/decryptParameters";
|
||||||
|
import { SymmetricCryptoKey } from "../models/domain/symmetricCryptoKey";
|
||||||
|
|
||||||
|
export abstract class CryptoFunctionService {
|
||||||
|
pbkdf2: (
|
||||||
|
password: string | ArrayBuffer,
|
||||||
|
salt: string | ArrayBuffer,
|
||||||
|
algorithm: "sha256" | "sha512",
|
||||||
|
iterations: number
|
||||||
|
) => Promise<ArrayBuffer>;
|
||||||
|
hkdf: (
|
||||||
|
ikm: ArrayBuffer,
|
||||||
|
salt: string | ArrayBuffer,
|
||||||
|
info: string | ArrayBuffer,
|
||||||
|
outputByteSize: number,
|
||||||
|
algorithm: "sha256" | "sha512"
|
||||||
|
) => Promise<ArrayBuffer>;
|
||||||
|
hkdfExpand: (
|
||||||
|
prk: ArrayBuffer,
|
||||||
|
info: string | ArrayBuffer,
|
||||||
|
outputByteSize: number,
|
||||||
|
algorithm: "sha256" | "sha512"
|
||||||
|
) => Promise<ArrayBuffer>;
|
||||||
|
hash: (
|
||||||
|
value: string | ArrayBuffer,
|
||||||
|
algorithm: "sha1" | "sha256" | "sha512" | "md5"
|
||||||
|
) => Promise<ArrayBuffer>;
|
||||||
|
hmac: (
|
||||||
|
value: ArrayBuffer,
|
||||||
|
key: ArrayBuffer,
|
||||||
|
algorithm: "sha1" | "sha256" | "sha512"
|
||||||
|
) => Promise<ArrayBuffer>;
|
||||||
|
compare: (a: ArrayBuffer, b: ArrayBuffer) => Promise<boolean>;
|
||||||
|
hmacFast: (
|
||||||
|
value: ArrayBuffer | string,
|
||||||
|
key: ArrayBuffer | string,
|
||||||
|
algorithm: "sha1" | "sha256" | "sha512"
|
||||||
|
) => Promise<ArrayBuffer | string>;
|
||||||
|
compareFast: (a: ArrayBuffer | string, b: ArrayBuffer | string) => Promise<boolean>;
|
||||||
|
aesEncrypt: (data: ArrayBuffer, iv: ArrayBuffer, key: ArrayBuffer) => Promise<ArrayBuffer>;
|
||||||
|
aesDecryptFastParameters: (
|
||||||
|
data: string,
|
||||||
|
iv: string,
|
||||||
|
mac: string,
|
||||||
|
key: SymmetricCryptoKey
|
||||||
|
) => DecryptParameters<ArrayBuffer | string>;
|
||||||
|
aesDecryptFast: (parameters: DecryptParameters<ArrayBuffer | string>) => Promise<string>;
|
||||||
|
aesDecrypt: (data: ArrayBuffer, iv: ArrayBuffer, key: ArrayBuffer) => Promise<ArrayBuffer>;
|
||||||
|
rsaEncrypt: (
|
||||||
|
data: ArrayBuffer,
|
||||||
|
publicKey: ArrayBuffer,
|
||||||
|
algorithm: "sha1" | "sha256"
|
||||||
|
) => Promise<ArrayBuffer>;
|
||||||
|
rsaDecrypt: (
|
||||||
|
data: ArrayBuffer,
|
||||||
|
privateKey: ArrayBuffer,
|
||||||
|
algorithm: "sha1" | "sha256"
|
||||||
|
) => Promise<ArrayBuffer>;
|
||||||
|
rsaExtractPublicKey: (privateKey: ArrayBuffer) => Promise<ArrayBuffer>;
|
||||||
|
rsaGenerateKeyPair: (length: 1024 | 2048 | 4096) => Promise<[ArrayBuffer, ArrayBuffer]>;
|
||||||
|
randomBytes: (length: number) => Promise<ArrayBuffer>;
|
||||||
|
}
|
||||||
34
jslib/common/src/abstractions/environment.service.ts
Normal file
34
jslib/common/src/abstractions/environment.service.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { Observable } from "rxjs";
|
||||||
|
|
||||||
|
export type Urls = {
|
||||||
|
base?: string;
|
||||||
|
webVault?: string;
|
||||||
|
api?: string;
|
||||||
|
identity?: string;
|
||||||
|
icons?: string;
|
||||||
|
notifications?: string;
|
||||||
|
events?: string;
|
||||||
|
keyConnector?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PayPalConfig = {
|
||||||
|
businessId?: string;
|
||||||
|
buttonAction?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export abstract class EnvironmentService {
|
||||||
|
urls: Observable<Urls>;
|
||||||
|
|
||||||
|
hasBaseUrl: () => boolean;
|
||||||
|
getNotificationsUrl: () => string;
|
||||||
|
getWebVaultUrl: () => string;
|
||||||
|
getSendUrl: () => string;
|
||||||
|
getIconsUrl: () => string;
|
||||||
|
getApiUrl: () => string;
|
||||||
|
getIdentityUrl: () => string;
|
||||||
|
getEventsUrl: () => string;
|
||||||
|
getKeyConnectorUrl: () => string;
|
||||||
|
setUrlsFromStorage: () => Promise<void>;
|
||||||
|
setUrls: (urls: Urls) => Promise<Urls>;
|
||||||
|
getUrls: () => Urls;
|
||||||
|
}
|
||||||
7
jslib/common/src/abstractions/event.service.ts
Normal file
7
jslib/common/src/abstractions/event.service.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import { EventType } from "../enums/eventType";
|
||||||
|
|
||||||
|
export abstract class EventService {
|
||||||
|
collect: (eventType: EventType, cipherId?: string, uploadImmediately?: boolean) => Promise<any>;
|
||||||
|
uploadEvents: (userId?: string) => Promise<any>;
|
||||||
|
clearEvents: (userId?: string) => Promise<any>;
|
||||||
|
}
|
||||||
11
jslib/common/src/abstractions/export.service.ts
Normal file
11
jslib/common/src/abstractions/export.service.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { EventView } from "../models/view/eventView";
|
||||||
|
|
||||||
|
export type ExportFormat = "csv" | "json" | "encrypted_json";
|
||||||
|
|
||||||
|
export abstract class ExportService {
|
||||||
|
getExport: (format?: ExportFormat, organizationId?: string) => Promise<string>;
|
||||||
|
getPasswordProtectedExport: (password: string, organizationId?: string) => Promise<string>;
|
||||||
|
getOrganizationExport: (organizationId: string, format?: ExportFormat) => Promise<string>;
|
||||||
|
getEventExport: (events: EventView[]) => Promise<string>;
|
||||||
|
getFileName: (prefix?: string, extension?: string) => string;
|
||||||
|
}
|
||||||
18
jslib/common/src/abstractions/fileUpload.service.ts
Normal file
18
jslib/common/src/abstractions/fileUpload.service.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { EncArrayBuffer } from "../models/domain/encArrayBuffer";
|
||||||
|
import { EncString } from "../models/domain/encString";
|
||||||
|
import { AttachmentUploadDataResponse } from "../models/response/attachmentUploadDataResponse";
|
||||||
|
import { SendFileUploadDataResponse } from "../models/response/sendFileUploadDataResponse";
|
||||||
|
|
||||||
|
export abstract class FileUploadService {
|
||||||
|
uploadSendFile: (
|
||||||
|
uploadData: SendFileUploadDataResponse,
|
||||||
|
fileName: EncString,
|
||||||
|
encryptedFileData: EncArrayBuffer
|
||||||
|
) => Promise<any>;
|
||||||
|
uploadCipherAttachment: (
|
||||||
|
admin: boolean,
|
||||||
|
uploadData: AttachmentUploadDataResponse,
|
||||||
|
fileName: EncString,
|
||||||
|
encryptedFileData: EncArrayBuffer
|
||||||
|
) => Promise<any>;
|
||||||
|
}
|
||||||
21
jslib/common/src/abstractions/folder.service.ts
Normal file
21
jslib/common/src/abstractions/folder.service.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { FolderData } from "../models/data/folderData";
|
||||||
|
import { Folder } from "../models/domain/folder";
|
||||||
|
import { SymmetricCryptoKey } from "../models/domain/symmetricCryptoKey";
|
||||||
|
import { TreeNode } from "../models/domain/treeNode";
|
||||||
|
import { FolderView } from "../models/view/folderView";
|
||||||
|
|
||||||
|
export abstract class FolderService {
|
||||||
|
clearCache: (userId?: string) => Promise<void>;
|
||||||
|
encrypt: (model: FolderView, key?: SymmetricCryptoKey) => Promise<Folder>;
|
||||||
|
get: (id: string) => Promise<Folder>;
|
||||||
|
getAll: () => Promise<Folder[]>;
|
||||||
|
getAllDecrypted: () => Promise<FolderView[]>;
|
||||||
|
getAllNested: () => Promise<TreeNode<FolderView>[]>;
|
||||||
|
getNested: (id: string) => Promise<TreeNode<FolderView>>;
|
||||||
|
saveWithServer: (folder: Folder) => Promise<any>;
|
||||||
|
upsert: (folder: FolderData | FolderData[]) => Promise<any>;
|
||||||
|
replace: (folders: { [id: string]: FolderData }) => Promise<any>;
|
||||||
|
clear: (userId: string) => Promise<any>;
|
||||||
|
delete: (id: string | string[]) => Promise<any>;
|
||||||
|
deleteWithServer: (id: string) => Promise<any>;
|
||||||
|
}
|
||||||
9
jslib/common/src/abstractions/i18n.service.ts
Normal file
9
jslib/common/src/abstractions/i18n.service.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export abstract class I18nService {
|
||||||
|
locale: string;
|
||||||
|
supportedTranslationLocales: string[];
|
||||||
|
translationLocale: string;
|
||||||
|
collator: Intl.Collator;
|
||||||
|
localeNames: Map<string, string>;
|
||||||
|
t: (id: string, p1?: string, p2?: string, p3?: string) => string;
|
||||||
|
translate: (id: string, p1?: string, p2?: string, p3?: string) => string;
|
||||||
|
}
|
||||||
19
jslib/common/src/abstractions/import.service.ts
Normal file
19
jslib/common/src/abstractions/import.service.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { ImportOption, ImportType } from "../enums/importOptions";
|
||||||
|
import { ImportError } from "../importers/importError";
|
||||||
|
import { Importer } from "../importers/importer";
|
||||||
|
|
||||||
|
export abstract class ImportService {
|
||||||
|
featuredImportOptions: readonly ImportOption[];
|
||||||
|
regularImportOptions: readonly ImportOption[];
|
||||||
|
getImportOptions: () => ImportOption[];
|
||||||
|
import: (
|
||||||
|
importer: Importer,
|
||||||
|
fileContents: string,
|
||||||
|
organizationId?: string
|
||||||
|
) => Promise<ImportError>;
|
||||||
|
getImporter: (
|
||||||
|
format: ImportType | "bitwardenpasswordprotected",
|
||||||
|
organizationId: string,
|
||||||
|
password?: string
|
||||||
|
) => Importer;
|
||||||
|
}
|
||||||
19
jslib/common/src/abstractions/keyConnector.service.ts
Normal file
19
jslib/common/src/abstractions/keyConnector.service.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { Organization } from "../models/domain/organization";
|
||||||
|
import { IdentityTokenResponse } from "../models/response/identityTokenResponse";
|
||||||
|
|
||||||
|
export abstract class KeyConnectorService {
|
||||||
|
getAndSetKey: (url?: string) => Promise<void>;
|
||||||
|
getManagingOrganization: () => Promise<Organization>;
|
||||||
|
getUsesKeyConnector: () => Promise<boolean>;
|
||||||
|
migrateUser: () => Promise<void>;
|
||||||
|
userNeedsMigration: () => Promise<boolean>;
|
||||||
|
convertNewSsoUserToKeyConnector: (
|
||||||
|
tokenResponse: IdentityTokenResponse,
|
||||||
|
orgId: string
|
||||||
|
) => Promise<void>;
|
||||||
|
setUsesKeyConnector: (enabled: boolean) => Promise<void>;
|
||||||
|
setConvertAccountRequired: (status: boolean) => Promise<void>;
|
||||||
|
getConvertAccountRequired: () => Promise<boolean>;
|
||||||
|
removeConvertAccountRequired: () => Promise<void>;
|
||||||
|
clear: () => Promise<void>;
|
||||||
|
}
|
||||||
11
jslib/common/src/abstractions/log.service.ts
Normal file
11
jslib/common/src/abstractions/log.service.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { LogLevelType } from "../enums/logLevelType";
|
||||||
|
|
||||||
|
export abstract class LogService {
|
||||||
|
debug: (message: string) => void;
|
||||||
|
info: (message: string) => void;
|
||||||
|
warning: (message: string) => void;
|
||||||
|
error: (message: string) => void;
|
||||||
|
write: (level: LogLevelType, message: string) => void;
|
||||||
|
time: (label: string) => void;
|
||||||
|
timeEnd: (label: string) => [number, number];
|
||||||
|
}
|
||||||
3
jslib/common/src/abstractions/messaging.service.ts
Normal file
3
jslib/common/src/abstractions/messaging.service.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export abstract class MessagingService {
|
||||||
|
send: (subscriber: string, arg?: any) => void;
|
||||||
|
}
|
||||||
6
jslib/common/src/abstractions/notifications.service.ts
Normal file
6
jslib/common/src/abstractions/notifications.service.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export abstract class NotificationsService {
|
||||||
|
init: () => Promise<void>;
|
||||||
|
updateConnection: (sync?: boolean) => Promise<void>;
|
||||||
|
reconnectFromActivity: () => Promise<void>;
|
||||||
|
disconnectFromInactivity: () => Promise<void>;
|
||||||
|
}
|
||||||
11
jslib/common/src/abstractions/organization.service.ts
Normal file
11
jslib/common/src/abstractions/organization.service.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { OrganizationData } from "../models/data/organizationData";
|
||||||
|
import { Organization } from "../models/domain/organization";
|
||||||
|
|
||||||
|
export abstract class OrganizationService {
|
||||||
|
get: (id: string) => Promise<Organization>;
|
||||||
|
getByIdentifier: (identifier: string) => Promise<Organization>;
|
||||||
|
getAll: (userId?: string) => Promise<Organization[]>;
|
||||||
|
save: (orgs: { [id: string]: OrganizationData }) => Promise<any>;
|
||||||
|
canManageSponsorships: () => Promise<boolean>;
|
||||||
|
hasOrganizations: (userId?: string) => Promise<boolean>;
|
||||||
|
}
|
||||||
20
jslib/common/src/abstractions/passwordGeneration.service.ts
Normal file
20
jslib/common/src/abstractions/passwordGeneration.service.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import * as zxcvbn from "zxcvbn";
|
||||||
|
|
||||||
|
import { GeneratedPasswordHistory } from "../models/domain/generatedPasswordHistory";
|
||||||
|
import { PasswordGeneratorPolicyOptions } from "../models/domain/passwordGeneratorPolicyOptions";
|
||||||
|
|
||||||
|
export abstract class PasswordGenerationService {
|
||||||
|
generatePassword: (options: any) => Promise<string>;
|
||||||
|
generatePassphrase: (options: any) => Promise<string>;
|
||||||
|
getOptions: () => Promise<[any, PasswordGeneratorPolicyOptions]>;
|
||||||
|
enforcePasswordGeneratorPoliciesOnOptions: (
|
||||||
|
options: any
|
||||||
|
) => Promise<[any, PasswordGeneratorPolicyOptions]>;
|
||||||
|
getPasswordGeneratorPolicyOptions: () => Promise<PasswordGeneratorPolicyOptions>;
|
||||||
|
saveOptions: (options: any) => Promise<any>;
|
||||||
|
getHistory: () => Promise<GeneratedPasswordHistory[]>;
|
||||||
|
addHistory: (password: string) => Promise<any>;
|
||||||
|
clear: (userId?: string) => Promise<any>;
|
||||||
|
passwordStrength: (password: string, userInputs?: string[]) => zxcvbn.ZXCVBNResult;
|
||||||
|
normalizeOptions: (options: any, enforcedPolicyOptions: PasswordGeneratorPolicyOptions) => void;
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export abstract class PasswordRepromptService {
|
||||||
|
protectedFields: () => string[];
|
||||||
|
showPasswordPrompt: () => Promise<boolean>;
|
||||||
|
enabled: () => Promise<boolean>;
|
||||||
|
}
|
||||||
52
jslib/common/src/abstractions/platformUtils.service.ts
Normal file
52
jslib/common/src/abstractions/platformUtils.service.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import { ClientType } from "../enums/clientType";
|
||||||
|
import { DeviceType } from "../enums/deviceType";
|
||||||
|
import { ThemeType } from "../enums/themeType";
|
||||||
|
|
||||||
|
interface ToastOptions {
|
||||||
|
timeout?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export abstract class PlatformUtilsService {
|
||||||
|
getDevice: () => DeviceType;
|
||||||
|
getDeviceString: () => string;
|
||||||
|
getClientType: () => ClientType;
|
||||||
|
isFirefox: () => boolean;
|
||||||
|
isChrome: () => boolean;
|
||||||
|
isEdge: () => boolean;
|
||||||
|
isOpera: () => boolean;
|
||||||
|
isVivaldi: () => boolean;
|
||||||
|
isSafari: () => boolean;
|
||||||
|
isMacAppStore: () => boolean;
|
||||||
|
isViewOpen: () => Promise<boolean>;
|
||||||
|
launchUri: (uri: string, options?: any) => void;
|
||||||
|
saveFile: (win: Window, blobData: any, blobOptions: any, fileName: string) => void;
|
||||||
|
getApplicationVersion: () => Promise<string>;
|
||||||
|
supportsWebAuthn: (win: Window) => boolean;
|
||||||
|
supportsDuo: () => boolean;
|
||||||
|
showToast: (
|
||||||
|
type: "error" | "success" | "warning" | "info",
|
||||||
|
title: string,
|
||||||
|
text: string | string[],
|
||||||
|
options?: ToastOptions
|
||||||
|
) => void;
|
||||||
|
showDialog: (
|
||||||
|
body: string,
|
||||||
|
title?: string,
|
||||||
|
confirmText?: string,
|
||||||
|
cancelText?: string,
|
||||||
|
type?: string,
|
||||||
|
bodyIsHtml?: boolean
|
||||||
|
) => Promise<boolean>;
|
||||||
|
isDev: () => boolean;
|
||||||
|
isSelfHost: () => boolean;
|
||||||
|
copyToClipboard: (text: string, options?: any) => void | boolean;
|
||||||
|
readFromClipboard: (options?: any) => Promise<string>;
|
||||||
|
supportsBiometric: () => Promise<boolean>;
|
||||||
|
authenticateBiometric: () => Promise<boolean>;
|
||||||
|
getDefaultSystemTheme: () => Promise<ThemeType.Light | ThemeType.Dark>;
|
||||||
|
onDefaultSystemThemeChange: (
|
||||||
|
callback: (theme: ThemeType.Light | ThemeType.Dark) => unknown
|
||||||
|
) => unknown;
|
||||||
|
getEffectiveTheme: () => Promise<ThemeType>;
|
||||||
|
supportsSecureStorage: () => boolean;
|
||||||
|
}
|
||||||
32
jslib/common/src/abstractions/policy.service.ts
Normal file
32
jslib/common/src/abstractions/policy.service.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { PolicyType } from "../enums/policyType";
|
||||||
|
import { PolicyData } from "../models/data/policyData";
|
||||||
|
import { MasterPasswordPolicyOptions } from "../models/domain/masterPasswordPolicyOptions";
|
||||||
|
import { Policy } from "../models/domain/policy";
|
||||||
|
import { ResetPasswordPolicyOptions } from "../models/domain/resetPasswordPolicyOptions";
|
||||||
|
import { ListResponse } from "../models/response/listResponse";
|
||||||
|
import { PolicyResponse } from "../models/response/policyResponse";
|
||||||
|
|
||||||
|
export abstract class PolicyService {
|
||||||
|
clearCache: () => void;
|
||||||
|
getAll: (type?: PolicyType, userId?: string) => Promise<Policy[]>;
|
||||||
|
getPolicyForOrganization: (policyType: PolicyType, organizationId: string) => Promise<Policy>;
|
||||||
|
replace: (policies: { [id: string]: PolicyData }) => Promise<any>;
|
||||||
|
clear: (userId?: string) => Promise<any>;
|
||||||
|
getMasterPasswordPoliciesForInvitedUsers: (orgId: string) => Promise<MasterPasswordPolicyOptions>;
|
||||||
|
getMasterPasswordPolicyOptions: (policies?: Policy[]) => Promise<MasterPasswordPolicyOptions>;
|
||||||
|
evaluateMasterPassword: (
|
||||||
|
passwordStrength: number,
|
||||||
|
newPassword: string,
|
||||||
|
enforcedPolicyOptions?: MasterPasswordPolicyOptions
|
||||||
|
) => boolean;
|
||||||
|
getResetPasswordPolicyOptions: (
|
||||||
|
policies: Policy[],
|
||||||
|
orgId: string
|
||||||
|
) => [ResetPasswordPolicyOptions, boolean];
|
||||||
|
mapPoliciesFromToken: (policiesResponse: ListResponse<PolicyResponse>) => Policy[];
|
||||||
|
policyAppliesToUser: (
|
||||||
|
policyType: PolicyType,
|
||||||
|
policyFilter?: (policy: Policy) => boolean,
|
||||||
|
userId?: string
|
||||||
|
) => Promise<boolean>;
|
||||||
|
}
|
||||||
8
jslib/common/src/abstractions/provider.service.ts
Normal file
8
jslib/common/src/abstractions/provider.service.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { ProviderData } from "../models/data/providerData";
|
||||||
|
import { Provider } from "../models/domain/provider";
|
||||||
|
|
||||||
|
export abstract class ProviderService {
|
||||||
|
get: (id: string) => Promise<Provider>;
|
||||||
|
getAll: () => Promise<Provider[]>;
|
||||||
|
save: (providers: { [id: string]: ProviderData }) => Promise<any>;
|
||||||
|
}
|
||||||
16
jslib/common/src/abstractions/search.service.ts
Normal file
16
jslib/common/src/abstractions/search.service.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { CipherView } from "../models/view/cipherView";
|
||||||
|
import { SendView } from "../models/view/sendView";
|
||||||
|
|
||||||
|
export abstract class SearchService {
|
||||||
|
indexedEntityId?: string = null;
|
||||||
|
clearIndex: () => void;
|
||||||
|
isSearchable: (query: string) => boolean;
|
||||||
|
indexCiphers: (indexedEntityGuid?: string, ciphersToIndex?: CipherView[]) => Promise<void>;
|
||||||
|
searchCiphers: (
|
||||||
|
query: string,
|
||||||
|
filter?: ((cipher: CipherView) => boolean) | ((cipher: CipherView) => boolean)[],
|
||||||
|
ciphers?: CipherView[]
|
||||||
|
) => Promise<CipherView[]>;
|
||||||
|
searchCiphersBasic: (ciphers: CipherView[], query: string, deleted?: boolean) => CipherView[];
|
||||||
|
searchSends: (sends: SendView[], query: string) => SendView[];
|
||||||
|
}
|
||||||
25
jslib/common/src/abstractions/send.service.ts
Normal file
25
jslib/common/src/abstractions/send.service.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { SendData } from "../models/data/sendData";
|
||||||
|
import { EncArrayBuffer } from "../models/domain/encArrayBuffer";
|
||||||
|
import { Send } from "../models/domain/send";
|
||||||
|
import { SymmetricCryptoKey } from "../models/domain/symmetricCryptoKey";
|
||||||
|
import { SendView } from "../models/view/sendView";
|
||||||
|
|
||||||
|
export abstract class SendService {
|
||||||
|
clearCache: () => Promise<void>;
|
||||||
|
encrypt: (
|
||||||
|
model: SendView,
|
||||||
|
file: File | ArrayBuffer,
|
||||||
|
password: string,
|
||||||
|
key?: SymmetricCryptoKey
|
||||||
|
) => Promise<[Send, EncArrayBuffer]>;
|
||||||
|
get: (id: string) => Promise<Send>;
|
||||||
|
getAll: () => Promise<Send[]>;
|
||||||
|
getAllDecrypted: () => Promise<SendView[]>;
|
||||||
|
saveWithServer: (sendData: [Send, EncArrayBuffer]) => Promise<any>;
|
||||||
|
upsert: (send: SendData | SendData[]) => Promise<any>;
|
||||||
|
replace: (sends: { [id: string]: SendData }) => Promise<any>;
|
||||||
|
clear: (userId: string) => Promise<any>;
|
||||||
|
delete: (id: string | string[]) => Promise<any>;
|
||||||
|
deleteWithServer: (id: string) => Promise<any>;
|
||||||
|
removePasswordWithServer: (id: string) => Promise<any>;
|
||||||
|
}
|
||||||
6
jslib/common/src/abstractions/settings.service.ts
Normal file
6
jslib/common/src/abstractions/settings.service.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export abstract class SettingsService {
|
||||||
|
clearCache: () => Promise<void>;
|
||||||
|
getEquivalentDomains: () => Promise<any>;
|
||||||
|
setEquivalentDomains: (equivalentDomains: string[][]) => Promise<any>;
|
||||||
|
clear: (userId?: string) => Promise<void>;
|
||||||
|
}
|
||||||
307
jslib/common/src/abstractions/state.service.ts
Normal file
307
jslib/common/src/abstractions/state.service.ts
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
import { Observable } from "rxjs";
|
||||||
|
|
||||||
|
import { KdfType } from "../enums/kdfType";
|
||||||
|
import { ThemeType } from "../enums/themeType";
|
||||||
|
import { UriMatchType } from "../enums/uriMatchType";
|
||||||
|
import { CipherData } from "../models/data/cipherData";
|
||||||
|
import { CollectionData } from "../models/data/collectionData";
|
||||||
|
import { EventData } from "../models/data/eventData";
|
||||||
|
import { FolderData } from "../models/data/folderData";
|
||||||
|
import { OrganizationData } from "../models/data/organizationData";
|
||||||
|
import { PolicyData } from "../models/data/policyData";
|
||||||
|
import { ProviderData } from "../models/data/providerData";
|
||||||
|
import { SendData } from "../models/data/sendData";
|
||||||
|
import { Account } from "../models/domain/account";
|
||||||
|
import { EncString } from "../models/domain/encString";
|
||||||
|
import { EnvironmentUrls } from "../models/domain/environmentUrls";
|
||||||
|
import { GeneratedPasswordHistory } from "../models/domain/generatedPasswordHistory";
|
||||||
|
import { Policy } from "../models/domain/policy";
|
||||||
|
import { StorageOptions } from "../models/domain/storageOptions";
|
||||||
|
import { SymmetricCryptoKey } from "../models/domain/symmetricCryptoKey";
|
||||||
|
import { WindowState } from "../models/domain/windowState";
|
||||||
|
import { CipherView } from "../models/view/cipherView";
|
||||||
|
import { CollectionView } from "../models/view/collectionView";
|
||||||
|
import { FolderView } from "../models/view/folderView";
|
||||||
|
import { SendView } from "../models/view/sendView";
|
||||||
|
|
||||||
|
export abstract class StateService<T extends Account = Account> {
|
||||||
|
accounts$: Observable<{ [userId: string]: T }>;
|
||||||
|
activeAccount$: Observable<string>;
|
||||||
|
|
||||||
|
addAccount: (account: T) => Promise<void>;
|
||||||
|
setActiveUser: (userId: string) => Promise<void>;
|
||||||
|
clean: (options?: StorageOptions) => Promise<void>;
|
||||||
|
init: () => Promise<void>;
|
||||||
|
|
||||||
|
getAccessToken: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setAccessToken: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getAddEditCipherInfo: (options?: StorageOptions) => Promise<any>;
|
||||||
|
setAddEditCipherInfo: (value: any, options?: StorageOptions) => Promise<void>;
|
||||||
|
getAlwaysShowDock: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setAlwaysShowDock: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getApiKeyClientId: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setApiKeyClientId: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getApiKeyClientSecret: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setApiKeyClientSecret: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getAutoConfirmFingerPrints: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setAutoConfirmFingerprints: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getAutoFillOnPageLoadDefault: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setAutoFillOnPageLoadDefault: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getBiometricAwaitingAcceptance: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setBiometricAwaitingAcceptance: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getBiometricFingerprintValidated: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setBiometricFingerprintValidated: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getBiometricLocked: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setBiometricLocked: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getBiometricText: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setBiometricText: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getBiometricUnlock: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setBiometricUnlock: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getCanAccessPremium: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
getClearClipboard: (options?: StorageOptions) => Promise<number>;
|
||||||
|
setClearClipboard: (value: number, options?: StorageOptions) => Promise<void>;
|
||||||
|
getCollapsedGroupings: (options?: StorageOptions) => Promise<string[]>;
|
||||||
|
setCollapsedGroupings: (value: string[], options?: StorageOptions) => Promise<void>;
|
||||||
|
getConvertAccountToKeyConnector: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setConvertAccountToKeyConnector: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getCryptoMasterKey: (options?: StorageOptions) => Promise<SymmetricCryptoKey>;
|
||||||
|
setCryptoMasterKey: (value: SymmetricCryptoKey, options?: StorageOptions) => Promise<void>;
|
||||||
|
getCryptoMasterKeyAuto: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setCryptoMasterKeyAuto: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getCryptoMasterKeyB64: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setCryptoMasterKeyB64: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getCryptoMasterKeyBiometric: (options?: StorageOptions) => Promise<string>;
|
||||||
|
hasCryptoMasterKeyBiometric: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setCryptoMasterKeyBiometric: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getDecodedToken: (options?: StorageOptions) => Promise<any>;
|
||||||
|
setDecodedToken: (value: any, options?: StorageOptions) => Promise<void>;
|
||||||
|
getDecryptedCiphers: (options?: StorageOptions) => Promise<CipherView[]>;
|
||||||
|
setDecryptedCiphers: (value: CipherView[], options?: StorageOptions) => Promise<void>;
|
||||||
|
getDecryptedCollections: (options?: StorageOptions) => Promise<CollectionView[]>;
|
||||||
|
setDecryptedCollections: (value: CollectionView[], options?: StorageOptions) => Promise<void>;
|
||||||
|
getDecryptedCryptoSymmetricKey: (options?: StorageOptions) => Promise<SymmetricCryptoKey>;
|
||||||
|
setDecryptedCryptoSymmetricKey: (
|
||||||
|
value: SymmetricCryptoKey,
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<void>;
|
||||||
|
getDecryptedFolders: (options?: StorageOptions) => Promise<FolderView[]>;
|
||||||
|
setDecryptedFolders: (value: FolderView[], options?: StorageOptions) => Promise<void>;
|
||||||
|
getDecryptedOrganizationKeys: (
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<Map<string, SymmetricCryptoKey>>;
|
||||||
|
setDecryptedOrganizationKeys: (
|
||||||
|
value: Map<string, SymmetricCryptoKey>,
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<void>;
|
||||||
|
getDecryptedPasswordGenerationHistory: (
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<GeneratedPasswordHistory[]>;
|
||||||
|
setDecryptedPasswordGenerationHistory: (
|
||||||
|
value: GeneratedPasswordHistory[],
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<void>;
|
||||||
|
getDecryptedPinProtected: (options?: StorageOptions) => Promise<EncString>;
|
||||||
|
setDecryptedPinProtected: (value: EncString, options?: StorageOptions) => Promise<void>;
|
||||||
|
getDecryptedPolicies: (options?: StorageOptions) => Promise<Policy[]>;
|
||||||
|
setDecryptedPolicies: (value: Policy[], options?: StorageOptions) => Promise<void>;
|
||||||
|
getDecryptedPrivateKey: (options?: StorageOptions) => Promise<ArrayBuffer>;
|
||||||
|
setDecryptedPrivateKey: (value: ArrayBuffer, options?: StorageOptions) => Promise<void>;
|
||||||
|
getDecryptedProviderKeys: (options?: StorageOptions) => Promise<Map<string, SymmetricCryptoKey>>;
|
||||||
|
setDecryptedProviderKeys: (
|
||||||
|
value: Map<string, SymmetricCryptoKey>,
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<void>;
|
||||||
|
getDecryptedSends: (options?: StorageOptions) => Promise<SendView[]>;
|
||||||
|
setDecryptedSends: (value: SendView[], options?: StorageOptions) => Promise<void>;
|
||||||
|
getDefaultUriMatch: (options?: StorageOptions) => Promise<UriMatchType>;
|
||||||
|
setDefaultUriMatch: (value: UriMatchType, options?: StorageOptions) => Promise<void>;
|
||||||
|
getDisableAddLoginNotification: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setDisableAddLoginNotification: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getDisableAutoBiometricsPrompt: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setDisableAutoBiometricsPrompt: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getDisableAutoTotpCopy: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setDisableAutoTotpCopy: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getDisableBadgeCounter: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setDisableBadgeCounter: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getDisableChangedPasswordNotification: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setDisableChangedPasswordNotification: (
|
||||||
|
value: boolean,
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<void>;
|
||||||
|
getDisableContextMenuItem: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setDisableContextMenuItem: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getDisableFavicon: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setDisableFavicon: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getDisableGa: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setDisableGa: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getDontShowCardsCurrentTab: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setDontShowCardsCurrentTab: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getDontShowIdentitiesCurrentTab: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setDontShowIdentitiesCurrentTab: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEmail: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setEmail: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEmailVerified: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setEmailVerified: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEnableAlwaysOnTop: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setEnableAlwaysOnTop: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEnableAutoFillOnPageLoad: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setEnableAutoFillOnPageLoad: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEnableBiometric: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setEnableBiometric: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEnableBrowserIntegration: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setEnableBrowserIntegration: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEnableBrowserIntegrationFingerprint: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setEnableBrowserIntegrationFingerprint: (
|
||||||
|
value: boolean,
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<void>;
|
||||||
|
getEnableCloseToTray: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setEnableCloseToTray: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEnableFullWidth: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setEnableFullWidth: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEnableGravitars: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setEnableGravitars: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEnableMinimizeToTray: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setEnableMinimizeToTray: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEnableStartToTray: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setEnableStartToTray: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEnableTray: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setEnableTray: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEncryptedCiphers: (options?: StorageOptions) => Promise<{ [id: string]: CipherData }>;
|
||||||
|
setEncryptedCiphers: (
|
||||||
|
value: { [id: string]: CipherData },
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<void>;
|
||||||
|
getEncryptedCollections: (options?: StorageOptions) => Promise<{ [id: string]: CollectionData }>;
|
||||||
|
setEncryptedCollections: (
|
||||||
|
value: { [id: string]: CollectionData },
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<void>;
|
||||||
|
getEncryptedCryptoSymmetricKey: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setEncryptedCryptoSymmetricKey: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEncryptedFolders: (options?: StorageOptions) => Promise<{ [id: string]: FolderData }>;
|
||||||
|
setEncryptedFolders: (
|
||||||
|
value: { [id: string]: FolderData },
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<void>;
|
||||||
|
getEncryptedOrganizationKeys: (options?: StorageOptions) => Promise<any>;
|
||||||
|
setEncryptedOrganizationKeys: (
|
||||||
|
value: Map<string, SymmetricCryptoKey>,
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<void>;
|
||||||
|
getEncryptedPasswordGenerationHistory: (
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<GeneratedPasswordHistory[]>;
|
||||||
|
setEncryptedPasswordGenerationHistory: (
|
||||||
|
value: GeneratedPasswordHistory[],
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<void>;
|
||||||
|
getEncryptedPinProtected: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setEncryptedPinProtected: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEncryptedPolicies: (options?: StorageOptions) => Promise<{ [id: string]: PolicyData }>;
|
||||||
|
setEncryptedPolicies: (
|
||||||
|
value: { [id: string]: PolicyData },
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<void>;
|
||||||
|
getEncryptedPrivateKey: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setEncryptedPrivateKey: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEncryptedProviderKeys: (options?: StorageOptions) => Promise<any>;
|
||||||
|
setEncryptedProviderKeys: (value: any, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEncryptedSends: (options?: StorageOptions) => Promise<{ [id: string]: SendData }>;
|
||||||
|
setEncryptedSends: (value: { [id: string]: SendData }, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEntityId: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setEntityId: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEntityType: (options?: StorageOptions) => Promise<any>;
|
||||||
|
setEntityType: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEnvironmentUrls: (options?: StorageOptions) => Promise<EnvironmentUrls>;
|
||||||
|
setEnvironmentUrls: (value: EnvironmentUrls, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEquivalentDomains: (options?: StorageOptions) => Promise<any>;
|
||||||
|
setEquivalentDomains: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getEventCollection: (options?: StorageOptions) => Promise<EventData[]>;
|
||||||
|
setEventCollection: (value: EventData[], options?: StorageOptions) => Promise<void>;
|
||||||
|
getEverBeenUnlocked: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setEverBeenUnlocked: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getForcePasswordReset: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setForcePasswordReset: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getInstalledVersion: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setInstalledVersion: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getIsAuthenticated: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
getKdfIterations: (options?: StorageOptions) => Promise<number>;
|
||||||
|
setKdfIterations: (value: number, options?: StorageOptions) => Promise<void>;
|
||||||
|
getKdfType: (options?: StorageOptions) => Promise<KdfType>;
|
||||||
|
setKdfType: (value: KdfType, options?: StorageOptions) => Promise<void>;
|
||||||
|
getKeyHash: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setKeyHash: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getLastActive: (options?: StorageOptions) => Promise<number>;
|
||||||
|
setLastActive: (value: number, options?: StorageOptions) => Promise<void>;
|
||||||
|
getLastSync: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setLastSync: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getLegacyEtmKey: (options?: StorageOptions) => Promise<SymmetricCryptoKey>;
|
||||||
|
setLegacyEtmKey: (value: SymmetricCryptoKey, options?: StorageOptions) => Promise<void>;
|
||||||
|
getLocalData: (options?: StorageOptions) => Promise<any>;
|
||||||
|
setLocalData: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getLocale: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setLocale: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getLoginRedirect: (options?: StorageOptions) => Promise<any>;
|
||||||
|
setLoginRedirect: (value: any, options?: StorageOptions) => Promise<void>;
|
||||||
|
getMainWindowSize: (options?: StorageOptions) => Promise<number>;
|
||||||
|
setMainWindowSize: (value: number, options?: StorageOptions) => Promise<void>;
|
||||||
|
getMinimizeOnCopyToClipboard: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setMinimizeOnCopyToClipboard: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getNeverDomains: (options?: StorageOptions) => Promise<{ [id: string]: any }>;
|
||||||
|
setNeverDomains: (value: { [id: string]: any }, options?: StorageOptions) => Promise<void>;
|
||||||
|
getNoAutoPromptBiometrics: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setNoAutoPromptBiometrics: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getNoAutoPromptBiometricsText: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setNoAutoPromptBiometricsText: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getOpenAtLogin: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setOpenAtLogin: (value: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getOrganizationInvitation: (options?: StorageOptions) => Promise<any>;
|
||||||
|
setOrganizationInvitation: (value: any, options?: StorageOptions) => Promise<void>;
|
||||||
|
getOrganizations: (options?: StorageOptions) => Promise<{ [id: string]: OrganizationData }>;
|
||||||
|
setOrganizations: (
|
||||||
|
value: { [id: string]: OrganizationData },
|
||||||
|
options?: StorageOptions
|
||||||
|
) => Promise<void>;
|
||||||
|
getPasswordGenerationOptions: (options?: StorageOptions) => Promise<any>;
|
||||||
|
setPasswordGenerationOptions: (value: any, options?: StorageOptions) => Promise<void>;
|
||||||
|
getUsernameGenerationOptions: (options?: StorageOptions) => Promise<any>;
|
||||||
|
setUsernameGenerationOptions: (value: any, options?: StorageOptions) => Promise<void>;
|
||||||
|
getGeneratorOptions: (options?: StorageOptions) => Promise<any>;
|
||||||
|
setGeneratorOptions: (value: any, options?: StorageOptions) => Promise<void>;
|
||||||
|
getProtectedPin: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setProtectedPin: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getProviders: (options?: StorageOptions) => Promise<{ [id: string]: ProviderData }>;
|
||||||
|
setProviders: (value: { [id: string]: ProviderData }, options?: StorageOptions) => Promise<void>;
|
||||||
|
getPublicKey: (options?: StorageOptions) => Promise<ArrayBuffer>;
|
||||||
|
setPublicKey: (value: ArrayBuffer, options?: StorageOptions) => Promise<void>;
|
||||||
|
getRefreshToken: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setRefreshToken: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getRememberedEmail: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setRememberedEmail: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getSecurityStamp: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setSecurityStamp: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getSettings: (options?: StorageOptions) => Promise<any>;
|
||||||
|
setSettings: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getSsoCodeVerifier: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setSsoCodeVerifier: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getSsoOrgIdentifier: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setSsoOrganizationIdentifier: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getSsoState: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setSsoState: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getTheme: (options?: StorageOptions) => Promise<ThemeType>;
|
||||||
|
setTheme: (value: ThemeType, options?: StorageOptions) => Promise<void>;
|
||||||
|
getTwoFactorToken: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setTwoFactorToken: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getUserId: (options?: StorageOptions) => Promise<string>;
|
||||||
|
getUsesKeyConnector: (options?: StorageOptions) => Promise<boolean>;
|
||||||
|
setUsesKeyConnector: (vaule: boolean, options?: StorageOptions) => Promise<void>;
|
||||||
|
getVaultTimeout: (options?: StorageOptions) => Promise<number>;
|
||||||
|
setVaultTimeout: (value: number, options?: StorageOptions) => Promise<void>;
|
||||||
|
getVaultTimeoutAction: (options?: StorageOptions) => Promise<string>;
|
||||||
|
setVaultTimeoutAction: (value: string, options?: StorageOptions) => Promise<void>;
|
||||||
|
getStateVersion: () => Promise<number>;
|
||||||
|
setStateVersion: (value: number) => Promise<void>;
|
||||||
|
getWindow: () => Promise<WindowState>;
|
||||||
|
setWindow: (value: WindowState) => Promise<void>;
|
||||||
|
}
|
||||||
4
jslib/common/src/abstractions/stateMigration.service.ts
Normal file
4
jslib/common/src/abstractions/stateMigration.service.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export abstract class StateMigrationService {
|
||||||
|
needsMigration: () => Promise<boolean>;
|
||||||
|
migrate: () => Promise<void>;
|
||||||
|
}
|
||||||
8
jslib/common/src/abstractions/storage.service.ts
Normal file
8
jslib/common/src/abstractions/storage.service.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { StorageOptions } from "../models/domain/storageOptions";
|
||||||
|
|
||||||
|
export abstract class StorageService {
|
||||||
|
get: <T>(key: string, options?: StorageOptions) => Promise<T>;
|
||||||
|
has: (key: string, options?: StorageOptions) => Promise<boolean>;
|
||||||
|
save: (key: string, obj: any, options?: StorageOptions) => Promise<any>;
|
||||||
|
remove: (key: string, options?: StorageOptions) => Promise<any>;
|
||||||
|
}
|
||||||
19
jslib/common/src/abstractions/sync.service.ts
Normal file
19
jslib/common/src/abstractions/sync.service.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import {
|
||||||
|
SyncCipherNotification,
|
||||||
|
SyncFolderNotification,
|
||||||
|
SyncSendNotification,
|
||||||
|
} from "../models/response/notificationResponse";
|
||||||
|
|
||||||
|
export abstract class SyncService {
|
||||||
|
syncInProgress: boolean;
|
||||||
|
|
||||||
|
getLastSync: () => Promise<Date>;
|
||||||
|
setLastSync: (date: Date, userId?: string) => Promise<any>;
|
||||||
|
fullSync: (forceSync: boolean, allowThrowOnError?: boolean) => Promise<boolean>;
|
||||||
|
syncUpsertFolder: (notification: SyncFolderNotification, isEdit: boolean) => Promise<boolean>;
|
||||||
|
syncDeleteFolder: (notification: SyncFolderNotification) => Promise<boolean>;
|
||||||
|
syncUpsertCipher: (notification: SyncCipherNotification, isEdit: boolean) => Promise<boolean>;
|
||||||
|
syncDeleteCipher: (notification: SyncFolderNotification) => Promise<boolean>;
|
||||||
|
syncUpsertSend: (notification: SyncSendNotification, isEdit: boolean) => Promise<boolean>;
|
||||||
|
syncDeleteSend: (notification: SyncSendNotification) => Promise<boolean>;
|
||||||
|
}
|
||||||
6
jslib/common/src/abstractions/system.service.ts
Normal file
6
jslib/common/src/abstractions/system.service.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export abstract class SystemService {
|
||||||
|
startProcessReload: () => Promise<void>;
|
||||||
|
cancelProcessReload: () => void;
|
||||||
|
clearClipboard: (clipboardValue: string, timeoutMs?: number) => Promise<void>;
|
||||||
|
clearPendingClipboard: () => Promise<any>;
|
||||||
|
}
|
||||||
32
jslib/common/src/abstractions/token.service.ts
Normal file
32
jslib/common/src/abstractions/token.service.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { IdentityTokenResponse } from "../models/response/identityTokenResponse";
|
||||||
|
|
||||||
|
export abstract class TokenService {
|
||||||
|
setTokens: (
|
||||||
|
accessToken: string,
|
||||||
|
refreshToken: string,
|
||||||
|
clientIdClientSecret: [string, string]
|
||||||
|
) => Promise<any>;
|
||||||
|
setToken: (token: string) => Promise<any>;
|
||||||
|
getToken: () => Promise<string>;
|
||||||
|
setRefreshToken: (refreshToken: string) => Promise<any>;
|
||||||
|
getRefreshToken: () => Promise<string>;
|
||||||
|
setClientId: (clientId: string) => Promise<any>;
|
||||||
|
getClientId: () => Promise<string>;
|
||||||
|
setClientSecret: (clientSecret: string) => Promise<any>;
|
||||||
|
getClientSecret: () => Promise<string>;
|
||||||
|
setTwoFactorToken: (tokenResponse: IdentityTokenResponse) => Promise<any>;
|
||||||
|
getTwoFactorToken: () => Promise<string>;
|
||||||
|
clearTwoFactorToken: () => Promise<any>;
|
||||||
|
clearToken: (userId?: string) => Promise<any>;
|
||||||
|
decodeToken: (token?: string) => any;
|
||||||
|
getTokenExpirationDate: () => Promise<Date>;
|
||||||
|
tokenSecondsRemaining: (offsetSeconds?: number) => Promise<number>;
|
||||||
|
tokenNeedsRefresh: (minutes?: number) => Promise<boolean>;
|
||||||
|
getUserId: () => Promise<string>;
|
||||||
|
getEmail: () => Promise<string>;
|
||||||
|
getEmailVerified: () => Promise<boolean>;
|
||||||
|
getName: () => Promise<string>;
|
||||||
|
getPremium: () => Promise<boolean>;
|
||||||
|
getIssuer: () => Promise<string>;
|
||||||
|
getIsExternal: () => Promise<boolean>;
|
||||||
|
}
|
||||||
5
jslib/common/src/abstractions/totp.service.ts
Normal file
5
jslib/common/src/abstractions/totp.service.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export abstract class TotpService {
|
||||||
|
getCode: (key: string) => Promise<string>;
|
||||||
|
getTimeInterval: (key: string) => number;
|
||||||
|
isAutoCopyEnabled: () => Promise<boolean>;
|
||||||
|
}
|
||||||
23
jslib/common/src/abstractions/twoFactor.service.ts
Normal file
23
jslib/common/src/abstractions/twoFactor.service.ts
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import { TwoFactorProviderType } from "../enums/twoFactorProviderType";
|
||||||
|
import { IdentityTwoFactorResponse } from "../models/response/identityTwoFactorResponse";
|
||||||
|
|
||||||
|
export interface TwoFactorProviderDetails {
|
||||||
|
type: TwoFactorProviderType;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
priority: number;
|
||||||
|
sort: number;
|
||||||
|
premium: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export abstract class TwoFactorService {
|
||||||
|
init: () => void;
|
||||||
|
getSupportedProviders: (win: Window) => TwoFactorProviderDetails[];
|
||||||
|
getDefaultProvider: (webAuthnSupported: boolean) => TwoFactorProviderType;
|
||||||
|
setSelectedProvider: (type: TwoFactorProviderType) => void;
|
||||||
|
clearSelectedProvider: () => void;
|
||||||
|
|
||||||
|
setProviders: (response: IdentityTwoFactorResponse) => void;
|
||||||
|
clearProviders: () => void;
|
||||||
|
getProviders: () => Map<TwoFactorProviderType, { [key: string]: string }>;
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user