Compare commits

...

462 Commits

Author SHA1 Message Date
Oscar Hinton d7674f5c91
Update README.md (#1531) 2022-05-05 15:06:09 -04:00
Jake Fink 9852f2ec22
[PS-106] update jslib (#1530) 2022-05-05 17:11:39 +02:00
Micaiah Martin fec6838f90
Updated publisher to use generic (#1529) 2022-05-05 09:51:17 -05:00
Patrick H. Lauke 55a9403ee3
[PS-540] Accessibility: remove `appBlurClick`, add `aria-expanded` to cog options, links to buttons, fix unsufficient focus indication (#1514) 2022-05-05 16:36:46 +02:00
Oscar Hinton 817856bc82
Rust improvements (#1495) 2022-05-05 16:01:09 +02:00
Micaiah Martin 508292ae39
Patched build workflow (#1527) 2022-05-04 13:59:36 -05:00
Micaiah Martin 00fd2ec03f
Update publish settings to use S3 (#1521)
* Update publish settings to use S3

* Fix formatting

* Added endpoint with new domain

* Updated S3 publisher config

* added npm CD commands for workflow later.

* Updated release workflow to publish to S3

* testing release

* Reduce aws cli output

* Remove test

* Finalize release workflow
- Reverted back testing logic
- Removed dry run check for GH release since it creates it as a draf anyways
- Removed artifact_url env as it's no longer needed.

* Remove testing values

* Merge Master

* Added endpoint in config
2022-05-04 11:19:04 -04:00
Oscar Hinton 9a954710d9
Add keytar to externals (#1520) 2022-05-03 11:03:21 +02:00
Oscar Hinton a81c3c95a4
[CP-30] Add credit card pipe (#1517) 2022-05-02 19:45:24 +02:00
Kyle Spearrin 75470dc169
Forwarded email providers to username generator (#1511)
* forward email username generation

* update jslib
2022-05-02 10:57:01 -04:00
Oscar Hinton 18b5e4adfd
[EC-163] Undo move to rust implementation (#1509) 2022-05-02 12:39:38 +02:00
Patrick H. Lauke 0396d682b1
Change links to buttons, expose `aria-pressed` for toggles, add `aria-expanded` to send view's "Options" (#1437)
* Change links to buttons, expose `aria-pressed` for toggles

- also make existing `<a routerLink...>` type controls keyboard focusable with the addition of `tabindex="0"`

* Correctly set aria-pressed

now that I have a working build environment, could verify correct way to set this with my limited Angular knowledge

* Change more links to buttons, initial style changes

* Fix layout of <button> elements with .box-content-row

* Update jslib submodule

* Add `aria-expanded` to the send view's "Show options" expand/collapse control

* Fix position of "Edit" pencil when hovering over folders

* Update jslib

* Change sends list links to buttons

* Add `aria-pressed` to vault and send list buttons

Programmatically denote which of the buttons is currently active/shown in the right-most panel

* Fix incorrect "Options" expand/collapse button in add-edit view

Currently, that buttons lacks an accName because the "Options" text is outside of it.

* Add `aria-pressed` to the send left-hand column filters

* Simplify base, list, and vault styles

Since links are now buttons, no need to double up selectors for both types of elements. No need to double-up theming in base, as this also causes incorrect "x" in toasts.

* Remove unnecessary `position:relative`

Fixes issue with cut-off focus outlines, has no other adverse effect

* Fix styling for last child of action buttons

Old approach of making right padding smaller results in unsightly, off-center icon (noticeable when focus outline is visible). This visually remains the same, but reduces right-hand margin instead.
2022-04-30 16:09:41 +02:00
Thomas Rittson ef60112855
[PS-74] Fix user authentication state checks (#1464)
* Use new authStatus method, clean up account switcher

* Update naming

* update jslib
2022-04-30 09:16:46 +10:00
Thomas Rittson b467206448
[EC-156] [BEEEP] Remove factory providers in Angular DI (#1496)
* Use tokens

* Use initService

Co-authored-by: Oscar Hinton <oscar@oscarhinton.com>
2022-04-29 17:48:44 +10:00
Nils Fahldieck 55b301c267
Widen the sidebar to 600px max (#1503)
This implements the suggestion by MrBlack of the community forums in: https://community.bitwarden.com/t/manually-resizable-sidebar-columns-in-bitwarden-desktop-app/31909/3
2022-04-27 22:10:11 +02:00
github-actions[bot] a5ebb9fb52
Bumped version to 1.33.1 (#1502)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-04-25 11:40:39 -07:00
github-actions[bot] 2764c9610b
Bumped version to 1.33.0 (#1501)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-04-25 08:02:04 -07:00
Oscar Hinton 241e08b7ff
[EC-166] Move electron metadata to separate file (#1498)
* Move electron metadata to separate file

* Replace yml with json

* Update build script
2022-04-25 15:54:08 +02:00
Oscar Hinton 865e92c94c
Improve reorganization note (#1497) 2022-04-22 17:13:06 +02:00
Patrick H. Lauke c3d0a529fb
[CP-92] Add new more understandable labels to password generator checkboxes (#1461) 2022-04-22 15:26:38 +02:00
Oscar Hinton 1315b3c6cd
Add reorganization notice (#1494) 2022-04-22 09:51:13 +02:00
Dave Nicolson 9f77dd9d09
[CP-96] Capitalize menu items consistently (#1489) 2022-04-21 19:44:53 +02:00
Thomas Rittson 5082c7708a
[PS-211] [PS-212] Make Generator page accessible (#1493)
* Fix radiobutton names

* Add role=radiogroup

* Add aria-labelledby
2022-04-21 09:51:37 -04:00
dwbit 10d35d863b
Contribution Documentation edits (#1486)
Making corrections to the mobile contributions doc:

Update Crowdin contact from Kyle to dwbit.
Update 'User-to-User Support' forum category to 'Ask the Bitwarden Community category'
2022-04-21 08:02:41 -04:00
Kyle Spearrin caafbc2b73
fix disabling of generate type (#1491) 2022-04-20 11:46:12 -04:00
Thomas Rittson a4ca9bf64c
Update jslib (#1490)
* Update jslib

* Update name of UserVerificationComponent
2022-04-19 10:29:43 -05:00
Joseph Flinn 3862a19571
Bumping pinned commit of the download-artifact action to bypass the broken GitHub api (#1488) 2022-04-18 14:28:49 -07:00
Oscar Hinton 8be88a731c
Resolve rust for windows and linux (#1485) 2022-04-13 16:32:08 +02:00
Oscar Hinton 2b0d7ac72c
Bump libsecret for rust (#1480) 2022-04-13 08:04:48 -05:00
Matt Gibson e0d7d2b43a
Add descriptions to vague messages (#1476)
* Add descriptions to vague messages

* Fix typo
2022-04-12 15:36:25 +02:00
Oscar Hinton 70db11e659
Update readme with rust instructions (#1482) 2022-04-12 08:24:09 +02:00
Oscar Hinton 2e3c89269d
Resolve cross-compile for rust (#1481) 2022-04-11 19:53:16 +02:00
github-actions[bot] 31523bdf0e
Autosync the updated translations (#1478)
Co-authored-by: github-actions <>
2022-04-08 11:50:48 +02:00
Oscar Hinton 6b6666cd0d
Undo electron builder bump (#1477) 2022-04-07 22:13:58 +02:00
Oscar Hinton be1ab221f4
Bump electron dependencies (#1447)
Co-authored-by: Micaiah Martin <mmartin@bitwarden.com>
2022-04-05 19:46:07 +02:00
Oscar Hinton 78986023e7
[BEEEP] Add native rust module (#1379) 2022-04-05 16:54:44 +02:00
Addison Beck 14b9decf21
[bug] Adjust mode in render webpack.config to variable (#1473) 2022-04-04 10:45:35 -05:00
github-actions[bot] 0e9465601a
Autosync the updated translations (#1470)
Co-authored-by: github-actions <>
2022-04-01 13:10:34 +02:00
Oscar Hinton 52bb77fb66
Add electron:ignore which ignores invalid certificates (#1463) 2022-04-01 11:24:46 +02:00
Kyle Spearrin b4cec5b46f
generator updates (#1469)
* generator updates

* update jslib
2022-03-31 18:49:53 -04:00
Robyn MacCallum 72405ebe87
update jslib (#1467) 2022-03-31 11:39:27 -04:00
Patrick H. Lauke 4379274154
Add `aria-label` to password generator length slider, make it non-keyboard-focusable (#1459)
Closes https://github.com/bitwarden/desktop/issues/1458

Co-authored-by: Thomas Rittson <trittson@bitwarden.com>
2022-03-31 13:14:16 +10:00
Kyle Spearrin 9e0cc45704
Username generator (#1456)
* username generator implemented

* disable type when coming from add/edit

* restyle buttons to new icon-btn

* update generated-wrapper styles

* only show policy messages for passwords

* make generated-wrapper a standalone style

* Update src/app/vault/password-generator.component.html

Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>

* aria-expanded on show options

Co-authored-by: Thomas Rittson <31796059+eliykat@users.noreply.github.com>
2022-03-29 15:01:57 -04:00
Francesco De Feo bc21703a2b
Update macOS icon to follow Big Sur design (#837)
Co-authored-by: Hinton <oscar@oscarhinton.com>
2022-03-29 20:56:03 +02:00
Patrick H. Lauke 4ddeff2eee
Add `aria-pressed` to all eye/toggle visibility buttons (#1443)
* Add `aria-pressed` to all eye/toggle visibility buttons

Closes #1442

* Correct custom field visibility toggle `aria-pressed` value
2022-03-27 22:42:47 +02:00
Patrick H. Lauke 75af5b94d4
Fix "Custom environment", "Options" expand/collapse controls - wrong accessible name, state not exposed (#1441)
* Fix "Custom environment" expand/collapse control wrong accessible name, expose state

Closes #1440

* Correct "Options" expand/collapse accname, expose state

* Remove redundant appA11yTitle
2022-03-27 15:04:45 +02:00
Oscar Hinton cbadcccc85
Fix Mac App Store minimumSystemVersion (#1453) 2022-03-25 15:29:43 +01:00
Kyle Spearrin 21167301f1
Bump jslib and add compatability with username generation (#1450)
Co-authored-by: Hinton <oscar@oscarhinton.com>
2022-03-25 10:56:34 +01:00
github-actions[bot] ad6308eb48
Autosync the updated translations (#1451)
Co-authored-by: github-actions <>
2022-03-25 01:28:44 +01:00
Oscar Hinton fec023866e
Add utils for testing updating processes (#1448) 2022-03-24 21:23:29 +01:00
Jake Fink d2a7012d3f
PS-91 bug/mas hide update option (#1446)
* PS-91 - hide update option if MAS build

* fix isMacAppStore
2022-03-24 15:55:06 -04:00
Jake Fink 6555312034
PS-91 - hide update option if MAS build (#1432) 2022-03-23 13:03:08 -04:00
github-actions[bot] e2fe0c8b09
Bump version to 1.32.2 (#1429)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
- Patch for Testflight track.
2022-03-22 13:30:43 -06:00
Oscar Hinton 3b2427e913
Change minimumSystemVersion to only apply for MAS (#1428) 2022-03-22 13:43:37 -04:00
Oscar Hinton 37e9523f00
Define Angular CLI globals to support tree shaking (#1408) 2022-03-22 10:09:19 +01:00
github-actions[bot] 09d7376f39
Bump version to 1.32.1 (#1427)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-03-21 14:09:45 -06:00
Thomas Rittson be0b6113e4
[JslibModule] Refactor to use JslibModule (#1425) 2022-03-21 20:39:35 +10:00
github-actions[bot] 75f11cdbf1
Autosync the updated translations (#1421)
Co-authored-by: github-actions <>
2022-03-18 01:13:12 +01:00
github-actions[bot] e5feda0fa6
Bump version to 1.32.0 (#1415)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-03-16 10:46:16 -06:00
Micaiah Martin 5ebed777c2
Updated actions (#1412) 2022-03-16 10:11:17 -06:00
Vince Grassia e49d317d19
Remove safari build script from Build workflow (#1413) 2022-03-15 16:47:02 -04:00
Chad Scharf 114d7455b8
Update SECURITY.md (#1411)
* Update SECURITY.md

Add link to our HackerOne program for submitting potential security issues.

* Revise language on SECURITY.md
2022-03-15 15:56:26 -04:00
Vince Grassia d1146acb1e
Add Node caching to Build workflow (#1410) 2022-03-15 15:19:12 -04:00
Micaiah Martin 703d390566
Moved linting to it's own step, removed duplicates (#1404) 2022-03-15 10:38:13 -06:00
Thomas Rittson c0170563f2
Disable disk caching in stateService (#1406)
* Disable disk caching in stateService

* Turn back on caching for the renderer

Co-authored-by: addison <addisonbeck1@gmail.com>
2022-03-15 09:25:43 -04:00
Thomas Rittson f46405a508
Update jslib (#1403) 2022-03-15 15:15:49 +10:00
Micaiah Martin 6d429465fb
Added manual build trigger (#1405) 2022-03-14 16:53:59 -06:00
Matt Gibson 81457f6c05
Add jit entitlement (#1395)
* Add arm64 package

* temporarily remove workflow ignore

* Don't delete universal dist when completing arm64

* Add allow-jit entitlement

* Revert "Don't delete universal dist when completing arm64"

This reverts commit b06d638345.

* Revert "temporarily remove workflow ignore"

This reverts commit 8007983547.

* Revert "Add arm64 package"

This reverts commit c8359dae4d.

Co-authored-by: Hinton <oscar@oscarhinton.com>
2022-03-11 10:01:19 -06:00
github-actions[bot] aee27f9570
Autosync the updated translations (#1399)
Co-authored-by: github-actions <>
2022-03-11 02:25:09 +01:00
Joseph Flinn f845bcf6c1
Update hotfix release branch name to hotfix-rc (#1396) 2022-03-09 12:46:13 -08:00
Micaiah Martin b134eba27b
Renewed certs and profiles (#1393) 2022-03-04 10:25:28 -07:00
Vincent Salucci e84be59075
[Captcha] Implement captcha for 2fa (#1390)
* [Captcha] Implement captcha for 2fa

* Update jslib

* Added remaining items necessary for captcha // updated login to match 2fa style
2022-03-03 18:20:29 -06:00
github-actions[bot] edc5245173
Autosync the updated translations (#1394)
Co-authored-by: github-actions <>
2022-03-04 01:14:56 +01:00
Addison Beck 7bad97dd82
[dep] Update jslib (#1392) 2022-03-03 20:34:39 +01:00
Oscar Hinton 3071bec03f
Update NSIS build settings (#1389) 2022-03-03 19:50:35 +01:00
Thomas Rittson 80415f8cd5
Update jslib (#1387) 2022-03-02 08:49:07 +10:00
Daniel James Smith 03c279865f
BEEEP: Add missing languages (#1382)
* Pull in jslib

* Register missing languages
2022-03-01 13:52:53 +01:00
Addison Beck 54025f269a
[feature] Implement scope warning for exports (#1384) 2022-02-28 17:44:10 +01:00
Thomas Rittson 4ce5e5fbdc
Update Help menu options (#1383) 2022-02-28 11:23:14 +01:00
Addison Beck c738366eef
[dep] Update jslib (#1381) 2022-02-25 11:27:43 -05:00
Micaiah Martin 0114d96e18
[BEEEP] - Ignored workflow files from triggering builds (#1375) 2022-02-25 08:14:19 -06:00
Micaiah Martin 1eac8f0c0f
Added dry run logic (#1376) 2022-02-25 08:13:39 -06:00
Daniel James Smith 8880e9700e
BEEEP: Colorize hidden custom field when value visible (#1380) 2022-02-25 14:27:54 +01:00
github-actions[bot] 2f289ebd1f
Autosync the updated translations (#1378)
Co-authored-by: github-actions <>
2022-02-25 12:29:23 +01:00
Oscar Hinton 3aa52a5537
Add eslint (#1369) 2022-02-24 20:50:19 +01:00
Robyn MacCallum 233f876bbb
Accessibility fixes for account switcher menu (#1373) 2022-02-24 14:11:54 -05:00
Thomas Rittson d7276850a2
Update jslib (#1374)
* Update jslib

* Update i18n
2022-02-24 09:36:15 -05:00
Jake Fink e570551a5a
fix desktop close window shortcut (#1372)
* fix syntax not adding additional items

* lint
2022-02-23 09:58:59 -05:00
Vincent Salucci 7401204b70
[Icons] Added missing custom field sort icon (#1370) 2022-02-23 07:54:33 -06:00
github-actions[bot] 685ffbcac5
Bumped version to 1.31.4 (#1362)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-02-22 05:51:46 -08:00
Chad Scharf f9e6d13708
We're Hiring (#1367)
Added link to README.md for Bitwarden Careers page.
2022-02-22 14:04:32 +01:00
Micaiah Martin f798995764
Added linter workflow (#1355) 2022-02-18 13:28:17 -06:00
github-actions[bot] f6298b2684
Autosync the updated translations (#1360)
Co-authored-by: github-actions <>
2022-02-18 10:21:18 +01:00
Thomas Rittson 3881223a73
Exclude jslib from prettier hook (#1343)
* Exlude jslib from prettier hook
2022-02-17 10:37:41 +10:00
Matt Gibson d2df8dacad
Add label enforcement (#1346)
* Enforce Hold label

* Linting

Co-authored-by: Micaiah Martin <77340197+mimartin12@users.noreply.github.com>
2022-02-16 08:43:26 -06:00
Addison Beck 10ffdce5b9
[lib] Update jslib (#1347) 2022-02-15 15:05:31 -05:00
github-actions[bot] d6d74e178c
Bumped version to 1.31.3 (#1345)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-02-15 09:04:33 -05:00
Addison Beck 2e09265d3a
[bug] Fix tab order regression (#1340) 2022-02-14 15:43:05 -05:00
Thomas Rittson 659c9ea78d
Update i18n string and id for tray menu Lock item (#1334) 2022-02-14 08:40:06 -05:00
Addison Beck 884615c23a
update jslib (#1337) 2022-02-14 08:32:55 -05:00
Oscar Hinton 2470d8ce25
Resolve preferences not setting correct focus (#1336) 2022-02-14 14:23:05 +01:00
github-actions[bot] 6b6468e061
Bumped version to 1.31.2 (#1328)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-02-11 14:21:09 -08:00
github-actions[bot] 45b144361c
Autosync the updated translations (#1313)
Co-authored-by: github-actions <>
2022-02-11 22:46:20 +01:00
Addison Beck 881bb3cb49
Update jslib (#1327)
* Update jslib

* Add a null check

* Reworked condition

* Ran prettier
2022-02-11 15:34:36 -05:00
Addison Beck fd4c41b043
update jslib (#1324)
* update jslib

* Update jslib
2022-02-11 12:51:48 -05:00
Oscar Hinton 7a8a78b4df
Bump jslib (https://github.com/bitwarden/jslib/pull/673) (#1322) 2022-02-11 16:31:13 +01:00
Oscar Hinton f82e2fbb03
Bump jslib (performance and hasKeyStored fix) (#1321) 2022-02-11 14:53:49 +01:00
Matt Gibson e9a3c586f8
Fix/load lock component (#1319)
* Update jslib

* update jslib
2022-02-11 03:58:31 -06:00
Thomas Rittson f54a614d6b
Update jslib (#1318) 2022-02-11 00:30:53 -05:00
Thomas Rittson 95b5d68566
Update jslib (#1317) 2022-02-11 15:02:04 +10:00
Thomas Rittson 3ffb658db6
Update jslib (#1316) 2022-02-11 14:29:47 +10:00
github-actions[bot] 530f25c88a
Bump version to 1.31.1 (#1308)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-02-10 13:47:25 -07:00
Joseph Flinn 97d367dab8
Switching where we are pulling our snap token from (#1307) 2022-02-10 10:57:32 -08:00
Micaiah Martin 0a545c88b2
Update release.yml (#1306) 2022-02-10 10:51:50 -07:00
github-actions[bot] 0f6ee08dd5
Bump version to 1.31.0 (#1304)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-02-10 09:40:21 -07:00
Addison Beck b227ae13f6
Remove unused import (#1298) 2022-02-09 21:34:01 -05:00
Addison Beck 79f6a33596
[bug] Remove redundant token clean call (#1303)
* [bug] Remove redundant token clean call

* bump jslib
2022-02-09 17:06:30 -05:00
Addison Beck 1e80c4335f
[bug] Resolve several regression issues (#1302)
* [bug] Ensure accounts logging out in the background doesn't impact active account ui

The main issue here: inactive accounts with a logout timeout actually log out the active account" is fixed by pulling in jslib.
These changes are for some asthetic issues I noticed, where inactive accounts logging out still fires a switchAccount event, which causes a loading spinner to appear and a sync that redraws the vault.

* Only load if the account being logged out is the active account:
* Replaced any calls to `stateService.activeAccount.getValue` with references to `this.activeUserId`, since we subscribe to that in the component now.
* Only send a "switchAccount" method if the active user before a clean and after a clean don't match

* [bug] Ensure default vault timeout is set to On Restart

We dont override the StateMigrationService instance that is injected in desktop, so it is not aware of desktop defaults.
This results in fresh accounts having a "Never" timeout action insteads of "On Restart"

* Use the correct StateMigrationService instance

* update jslib
2022-02-09 12:42:16 -05:00
Vincent Salucci c51b8523b7
[Help] Update links to new pattern (#1300)
* [Help] Update links to new pattern

* Update jslib
2022-02-08 18:02:17 -06:00
Joseph Flinn bd2ed43498
Fixing safari ref logic (#1299) 2022-02-08 07:41:58 -08:00
Oscar Hinton 243afc9da0
Client & Version headers (#1297) 2022-02-08 15:29:01 +01:00
Thomas Rittson 762e3f8198
Update client for authService refactor (#1239) 2022-02-08 09:26:53 +10:00
Thomas Rittson 4e75a25492
Make husky pre-commit hook executable (#1295) 2022-02-08 08:33:25 +10:00
Addison Beck 143a262743
[chore] Update jslib (#1296) 2022-02-07 12:08:15 -05:00
Addison Beck c1a3178538
Update jslib (#1293)
* Update jslib

* [style] Ran prettier
2022-02-03 14:39:49 -05:00
Oscar Hinton 166c459da4
Potentially improve path detection of regedit vbs files (#1288) 2022-02-03 19:39:23 +01:00
Daniel James Smith 94b561382d
fix announcement of security header (#1292) 2022-02-03 17:58:55 +01:00
Daniel James Smith 2b58861296
[AccountSwitching]Make account switcher accessible (#1289)
* Make account switcher keyboard accessible

* ScreenReader: Announce submenu and expansion

* ScreenReader: Announc switch account button with account info

* Fix tab focus on dropdown

* Fix esc not changing state

* Fix linting issues

Co-authored-by: Hinton <oscar@oscarhinton.com>
2022-02-03 17:46:14 +01:00
Vincent Salucci 3e8705d548
[Icons] FF - requested icon changes (#1291)
* [Icons] Remove FA

* Icon changes // webpack correction
2022-02-03 10:28:34 -06:00
Oscar Hinton 1e877f6cf8
Set minimumSystemVersion (#1287) 2022-02-03 14:13:50 +01:00
Joseph Flinn 9151fc0164
Switching the way we are pulling secrets for the EV SSL cert (#1285) 2022-02-02 14:35:03 -08:00
Addison Beck 03eed41d86
[bug] Remove scroll from login screen (#1283) 2022-02-02 10:32:06 -05:00
Addison Beck cad6e9481f
[bug] Attempt to resolve windows portable build issues (#1280) 2022-02-02 10:28:36 -05:00
Daniel James Smith 270411dff7
Fix icons on the settings headers (#1279) 2022-02-02 15:50:48 +01:00
Vincent Salucci 7c68e3802e
[bug] Add options string (#1281) 2022-02-01 23:06:29 -06:00
Addison Beck 48ff9f61ae
[bug] Inactive accounts with power-based timeout settings are not timing out (#1278)
* [bug] Move bulk of system lock checks into app.component

* [review] Extract shared system timeout logic

* [review] Correct an improper number

* [review] Opt for a more locally scoped system timeout helper than a dedicated enum
2022-02-01 11:31:30 -05:00
Addison Beck 2b22a39d45
[chore] Update jslib (#1277)
* [chore] Update jslib

* [bug] Correct value for system theme dropdown key

* [chore] Update jslib
2022-01-31 18:00:37 -05:00
Addison Beck c1ba54f646
[bug] Patch the windows menu bar regressions (#1273)
* [bug] Patch the windows menu bar regressions

* [chore] Update jslib
2022-01-28 11:27:30 -05:00
Daniel James Smith bb597e96a7
Use ThemeType instead of string (#1275) 2022-01-28 14:46:07 +01:00
github-actions[bot] 6aa9e7611a
Autosync the updated translations (#1274)
Co-authored-by: github-actions <>
2022-01-28 11:05:05 +01:00
Oscar Hinton 3c99920435
Add support for handling multiple accounts with native messaging (#1266) 2022-01-27 20:52:06 +01:00
Oscar Hinton a7c5f1ad45
Fix webpack using double dots (#1272) 2022-01-27 19:36:50 +01:00
Vincent Salucci ec3c95d736
[Icons] Update Font Sheet (#1245)
* [Icons] Update Font Sheet

* Added import statement for styles

* updated to clone icon

* Changed save to save changes icon

* Revert to using base bwi class

* Updated import order for bwi icon styles

* Converted new account switcher ui updates

* Bump jslib

* Fix occurances where bwi-eye-slash was used instead of btw-eye-slash-2

* Move settings cog to the left side

* Updated eye/eye-slash icon references

* Update jslib

* Update jslib

* Update fallback image for cipher icon

* Update jslib

Co-authored-by: Hinton <oscar@oscarhinton.com>
2022-01-27 11:21:53 -06:00
Addison Beck 058be7e895
[bug] Disable the preferences screen if there is no active unlocked vault (#1270) 2022-01-26 12:32:00 -05:00
Addison Beck ff7dd4ad8f
[bug] Don't monitor vault timeout action valueChanges until after init (#1271) 2022-01-26 09:33:37 -05:00
Addison Beck 9271ec37b9
[bug] Ensure remembering email always happens for desktop (#1269)
* [bug] Ensure remembering email always happens for desktop

* update jslib
2022-01-25 19:00:49 +01:00
Addison Beck d80fdc8a78
Adjust an iterator used to check for locked vaults on reloadProcess (#1268) 2022-01-25 09:49:57 -05:00
Addison Beck 555ee1c230
[bug] Checkout all vaults before reloading process (#1267) 2022-01-25 09:36:30 -05:00
Addison Beck c458b4d8a9
[bug] Move enableBrowserIntegration to global settings (#1265)
* [bug] Move enableBrowserIntegration to global settings

* [style] Ran prettier

* [chore] Update jslib
2022-01-24 11:35:24 -05:00
Oscar Hinton 7d46e5c145
Add explicit init to native messaging service (#1262) 2022-01-24 16:10:32 +01:00
Addison Beck ca41cdf8b5
[chore] Update jslib (#1264) 2022-01-24 08:45:35 -05:00
Addison Beck d211b3fcd2
Unset active account when adding additional accounts (#1258) 2022-01-24 07:28:39 -05:00
Addison Beck ef48ba1ae2
[bug] Correct DI setup for SystemService (#1257)
The DI refactor created a bad initlizer for SystemService that left out the reload callback.
This callback is null in prod, so I just set up a factory initlizer that used null for the callback value.

This fixes a bug causing clipboard clearing to not function, as platformUtilsService was not correctly injected.
2022-01-22 15:24:12 -05:00
Robyn MacCallum 33704b016f
Beeep/remove sad faces (#1255)
* Replace sad face with searching image

* Change css variable name

* Added aria-hidden="true" to images

* Run prettier
2022-01-21 14:37:28 -05:00
Oscar Hinton a64273f829
Hide account switcher border if no accounts (#1254) 2022-01-21 17:57:09 +01:00
Daniel James Smith cb4e6debf3
Fix display of account limit (#1253) 2022-01-21 14:15:24 +01:00
github-actions[bot] 2e7f8a127d
Autosync the updated translations (#1250)
Co-authored-by: github-actions <>
2022-01-21 11:51:41 +01:00
Thomas Rittson c6eaf3a31e
Move KeyConnector call from client to syncService (#1252) 2022-01-21 19:32:44 +10:00
Daniel James Smith 37b03b09a1
[Account Switching] Design changes to settings menu (#1244)
* Design changes to settings menu

* Remove black border on settings headers

* Pull in jslib

* Only load account related settings when authed

* Hide account related settings when not authed

* Change settings titles

* Changes discussed with Danielle
2022-01-20 22:56:15 +01:00
Oscar Hinton d1c01a2bb0
Remove account switching border (#1249) 2022-01-20 17:15:29 +01:00
Oscar Hinton 0edee78da1
Change account switching dropdown to align with the right side (#1248) 2022-01-20 16:32:05 +01:00
Addison Beck 80c9196e44
[chore] Update jslib (#1247) 2022-01-20 09:26:24 -05:00
Addison Beck 032d2be990
[bug] Remove old mac-bar styling (#1246)
With the account switching work a header was added to the desktop app that new acts as a home for the mac window controls.
Previously we needed a special home for these controls, but since moving them we are not just creating empty space.
Removing this class and the divs that use it corrects the behavior.
2022-01-20 07:44:20 -05:00
Daniel James Smith a684c102d7
Bump electron from 16.0.2 to 16.0.7 (#1243)
* Pull jslib to bump electron from 16.0.2 to 16.0.7

* Updates to package-lock.json
2022-01-20 12:22:22 +01:00
Daniel James Smith 12bb8b060c
[Account switching] Design changes (#1240)
* Various design changes to the account switcher

* Hide serverUrl on cloud accounts

* Display account limit reached instead of add account
2022-01-19 17:03:34 +01:00
Addison Beck b796fe094f
[Bug] [Account Switching] Improve State Management Performance (#1237)
* [dep] Implement new StateService factory parameter from jslib

* [bug] Ensure setLastActive uses the correct userId

Sometimes, because of how often it fires, setLastActive can cause accounts to override each other. To make sure the correct userId is always used we now subscribe to activeUser in the appComponent and pass that value into any setLastActive calls.

* [bug] Show loader when logging out

When logging out of a large vault the application can appear to hang. This commit turns on the app component loader while logout is doing work.

* [bug] Stop tracking activity without an active user

* [style] Ran prettier

* [chore] Update jslib
2022-01-19 11:00:28 -05:00
Daniel James Smith 8b521aa35e
[Account switching] Hide active account (#1241)
* Hide active account from dropdown

* No longer need to check if selected account is active before switching

* Applied feedback from PR review
2022-01-18 21:43:14 +01:00
Oscar Hinton 3cacf8a8c4
Rename package to @bitwarden/desktop (#1242) 2022-01-18 14:04:21 +01:00
Vince Grassia dad1a95fb0
Update Version Bump action to latest (#1238) 2022-01-14 13:32:16 -05:00
github-actions[bot] 5b6e5fc4fa
Autosync the updated translations (#1236)
Co-authored-by: github-actions <>
2022-01-14 11:21:53 +01:00
Oscar Hinton 4644d03b28
Exclude dist-safari from prettier (#1234) 2022-01-13 18:10:59 +01:00
Daniel James Smith abede3e5af
Fix logging out of all accounts instead of one (#1231)
When logOut is triggered and the userId is not provided. Retrieve currentUserId
2022-01-13 15:43:00 +01:00
Daniel James Smith 7818ffc2fb
[Account Switching] Fix menus (#1232)
* Fix enabled/disabling menu items with locked state

* Fix the empty about menu (title)

Moved the items to the help menu
2022-01-13 14:29:49 +01:00
Oscar Hinton b6117d6801
Re-add native dependencies to src/package.json (#1233) 2022-01-13 10:46:33 +01:00
Addison Beck 653ff8f45f
[Bug] VaultTimeout incorrectly defaults to "Never" (#1230)
* [Bug] VaultTimeout incorrectly defaults to "Never"

The default desktop vault timeout value is "On Restart", but there is no default set for this in the state service and account model.
This commit extends the StateService and Account model to consider the special vault timeout default requirements needed for desktop.

* [style] Lint fixes

* [chore] Update jslib
2022-01-12 11:37:23 -05:00
Daniel James Smith 71c2fee574
Close opened AccountSwitcher dropdown (#1228)
When a user clicks outside of an opened account switching dropdown, it should close automatically when clicking outside of the dropdown.
2022-01-12 17:20:19 +01:00
Daniel James Smith d885e3296b
Do not switch accounts if it is already the active account (#1229) 2022-01-12 17:20:07 +01:00
Addison Beck f32b917a9f
[Account Switching] Misc Bug Fixes and Refactors (#1223)
* [bug] Pull serverUrl directly from stateService for the account switcher

Create a small extended Account model for handling the switchers server url, and pull environment urls from disk where they actually live

* [refactor] Add a message handler for switching accounts

* This allows for logic reuse between manually switching accounts and automatically switching accounts on login
* This commit also adds a loading spinner to app root while syncing after a switch

* [bug] Remove vertical scrollbar

* An old styling fix to add extra height and padding seems to be now creating an unecassary scroll bar. It is likely that since making more use of flexbox for our containers that this issue has been resolved without the manually added extra hight & padding

* [refactor] Turn down activity monitoring

Saving last activity is a disk call, and we currently do this a lot more than is necassary. For example:
* We track mousedown & click, which is redundant
* We track every mouse movement regardless of if an action is taken. This seems inappropriate for use in locking behavior.

* [bug] Address potential race condition when locking

Sometimes when swapping between an unlocked account and a locked account a race condition occurs that swaps the user but doesn't redirect to the lock screen
This commit just adds some awaits and restructures lock order of operations to be more in line with other message handlers

* [refactor] Change click event to mousedown event for the account switcher

This is simply a little snappier, and ensures we stay ahead of change detection and don't get stuck not properly interpreting the action

* [chore] Update jslib

* [chore] Linter fixes

* [chore] Linter fixes

* [chore] Update jslib

* [chore] Update jslib
2022-01-12 09:23:00 -05:00
Daniel James Smith 2b64ec5375
Fix null ref when building/updating the MenuBar (#1227) 2022-01-12 15:19:18 +01:00
Oscar Hinton f6f0bd2bfb
Remove webpack-node-externals and use asarUnpack (#1221) 2022-01-12 11:32:02 +01:00
Oscar Hinton 23a7072341
Disable spellchecker (#1225) 2022-01-10 18:27:14 +01:00
Daniel James Smith d64b00977c
Fix menu separators (#1220)
* Fix separators appearing when they shouldn't

* Use const instead of let
2022-01-07 15:54:35 +01:00
github-actions[bot] 695e8389d8
Autosync the updated translations (#1222)
Co-authored-by: github-actions <>
2022-01-07 13:50:31 +01:00
Daniel James Smith dd73a45f64
Add ts files to prettier (#1219)
* Add ts files to prettier

* Add scss to prettier

* Add all filetypes to prettier and ignore via .prettierignore

* Add --ignore-unknown to prettier
2022-01-06 23:06:58 +01:00
Daniel James Smith a1bbbcf4bf
Update year in copyright (#1216) 2022-01-05 19:44:08 +01:00
Oscar Hinton 27b1ee2ab3
Whitelist rxjs in nodeExternals (#1218) 2022-01-04 20:51:21 +01:00
github-actions[bot] f01856d34f
Autosync the updated translations (#1213)
Co-authored-by: github-actions <>
2022-01-01 17:50:34 +01:00
Robyn MacCallum ef5e8e1e2a
rename fb to formBuilder (#1214) 2021-12-31 10:52:28 -05:00
Addison Beck ed78a79042
[bug] Apply background color for light theme account switcher (#1211) 2021-12-28 14:53:37 -05:00
github-actions[bot] 017a3bffd6
Autosync the updated translations (#1210)
Co-authored-by: github-actions <>
2021-12-24 01:08:21 +01:00
Micaiah Martin ad965e54e4
Rename .pkg to .pkg.archive in release pipeline (#1208)
* Add step to change .pkg file name
* Linting
2021-12-21 14:25:29 -07:00
Oscar Hinton 6e69b61128
Fix .git-blame-ignore-revs filename (#1207) 2021-12-21 17:05:54 +01:00
Daniel James Smith 406f4bf62c
Fixed prettier issue (#1206) 2021-12-21 15:22:12 +01:00
Linus Aarnio 83c3635932
Add credit card logos to allow displaying icons based on brand (#1149)
Co-authored-by: Hinton <oscar@oscarhinton.com>
2021-12-21 13:21:41 +01:00
Micaiah Martin 3c2094bb04
Patch version check to allow for redeployments. (#1204)
* Added logic for redployment

* Applied linting

- Prettier config was already updated by Oscar. b4df834b16
2021-12-20 10:49:16 -07:00
Oscar Hinton f7ae94199f
Add .git-blame-ignore-revs (#1203) 2021-12-20 16:49:00 +01:00
Oscar Hinton 521feae535
Apply Prettier (#1202) 2021-12-20 15:47:17 +01:00
Oscar Hinton b4df834b16
Add Prettier configuration (#1201) 2021-12-20 14:17:39 +01:00
Vince Grassia b33d37e610
Update with linter suggestions (#1199) 2021-12-17 12:26:26 -05:00
Daniel James Smith 3ad71103dd
Bump electron dependencies (#1194)
* Pull in jslib

* Bumping electron dependencies that relate tojslib

* Bump electron-rebuild

* Bump electron-builder

* Revert "Bump electron-builder"

This reverts commit 8cada43567.

* Bump jslib
2021-12-17 11:15:07 +01:00
github-actions[bot] da296559c0
Autosync the updated translations (#1198)
Co-authored-by: github-actions <>
2021-12-17 01:15:45 +01:00
Addison Beck 0b306ca1a7
[Account Switching] [Feature] Add the ability to maintain state for up to 5 accounts at once (#1079)
* [refactor] Remove references to deprecated services

* [feature] Implement account switching

* [bug] Fix state handling for authentication dependent system menu items

* [bug] Enable the account switcher to fucntion properly when switching to a locked accounts

* [feature] Enable locking any account from the menu

* [bug] Ensure the avatar instance used in the account switcher updates on account change

* [style] Fix lint complaints

* [bug] Ensure the logout command callback can handle any user in state

* [style] Fix lint complaints

* rollup

* [style] Fix lint complaints

* [bug] Don't clean up state until everything else is done on logout

* [bug] Navigate to vault on a succesful account switch

* [bug] Init the state service on start

* [feature] Limit account switching to 5 account maximum

* [bug] Resolve app lock state with 5 logged out accounts

* [chore] Update account refrences to match recent jslib restructuring

* [bug] Add missing awaits

* [bug] Update app menu on logout

* [bug] Hide the switcher if there are no authed accounts

* [bug] Move authenticationStatus display information out of jslib

* [bug] Remove unused active style from scss

* [refactor] Rewrite the menu bar

* [style] Fix lint complaints

* [bug] Clean state of loggout out user after redirect

* [bug] Redirect on logout if not explicity provided a userId that isn't active

* [bug] Relocated several settings items to persistant storage

* [bug] Correct account switcher styles on all themes

* [chore] Include state migration service in services

* [bug] Swap to next account on logout

* [bug] Correct DI service

* [bug] fix loginGuard deps in services.module

* [chore] update jslib

* [bug] Remove badly merged scss

* [chore] update jslib

* [review] Code review cleanup

* [review] Code review cleanup

Co-authored-by: Hinton <oscar@oscarhinton.com>
2021-12-15 17:32:00 -05:00
Daniel James Smith 5865f08b37
Bump node to v16 (#1189)
* Pull in jslib

* Update .nvmrc

* Bump engines required to node 16 and npm 8

* Bump @types/node to 16
The dep on node 14.18 will get cleaned up once we bump electron

* Modify build.yml to build with node 16 and npm 8

* Update requirements in README.md

* Removed install of npm8 and renamed action step
npm8 is included in node v16

* Pull jslib
2021-12-13 17:16:44 +01:00
github-actions[bot] 74c9c1972f
Bumped version to 1.30.1 (#1191)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-12-10 10:05:34 -05:00
Oscar Hinton a10259ecab
Bump angular to v12 (#1186) 2021-12-09 20:29:24 +01:00
github-actions[bot] 9feb147654
Bumped version to 1.30.0 (#1187)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2021-12-08 09:02:21 -05:00
Vince Grassia 822c791cf9
Fix typo (#1185) 2021-12-08 08:48:37 -05:00
Oscar Hinton b70d2fb3c3
Fix development build not working with bitwarden:// protocol (#1165) 2021-12-07 21:04:52 +01:00
Oscar Hinton 5fd1da0c58
Replace toaster library (#1183) 2021-12-07 20:42:31 +01:00
github-actions[bot] 2822d748f1
Autosync the updated translations (#1174)
Co-authored-by: github-actions <>
2021-12-07 17:01:42 +01:00
Oscar Hinton 04cfdb246d
BEEEP: Refactor services DI (#1175) 2021-12-06 12:03:02 +01:00
Micaiah Martin 00d57d0310
Added version bump workflow (#1177)
* Added version bump workflow

* Fixed job name
2021-11-30 15:52:54 -07:00
Thomas Rittson b6db41c26c
Update jslib (#1176)
* Update jslib

* Update component constructors

* Update jslib
2021-11-29 10:21:48 +10:00
Thomas Rittson b83058ecab
Apply AppInputVerbatim directive (#1170) 2021-11-24 08:03:43 +10:00
Oscar Hinton b607a4ed08
Hide password input when using key connector (#1169) 2021-11-22 18:37:28 +01:00
Oscar Hinton 25b915cf26
[Key Connector] Resolve not prompting to remove password (#1168) 2021-11-19 13:55:31 +01:00
github-actions[bot] 30d3192344
Autosync the updated translations (#1167)
Co-authored-by: github-actions <>
2021-11-19 13:01:05 +01:00
Thomas Rittson 9e3528df44
[Key Connector] Hide "Master Pass On Restart" prompt when setting pin (#1166)
* Hide Master Pass on Restart for Key Connector

* Update jslib
2021-11-18 21:53:41 +10:00
Oscar Hinton b57cba8632
Update export to match the design changes (#1163) 2021-11-17 20:32:00 +01:00
Joseph Flinn 52d9244f7f
Revert linux ARM (#1162)
* Revert "Adding the newly added Linux Arm Desktop build assets to the release (#1159)"

This reverts commit dde7afb3df.

* Revert "package: Package ARM64 binaries for Linux (#1095)"

This reverts commit dd602024d8.
2021-11-16 11:22:22 -08:00
Joseph Flinn dde7afb3df
Adding the newly added Linux Arm Desktop build assets to the release (#1159) 2021-11-16 07:10:10 -08:00
Thomas Rittson 3d8fd3cbce
Update jslib and service dependencies (#1160)
* Update service deps

* Update jslib
2021-11-16 21:01:23 +10:00
Thomas Rittson ca700e4feb
Add missing i18n string (#1161) 2021-11-16 20:41:25 +10:00
Alistair Francis dd602024d8
package: Package ARM64 binaries for Linux (#1095)
Signed-off-by: Alistair Francis <alistair@alistair23.me>

Co-authored-by: Joseph Flinn <58369717+joseph-flinn@users.noreply.github.com>
2021-11-15 14:39:11 -08:00
github-actions[bot] 3010b3e1ac
Autosync the updated translations (#1155)
Co-authored-by: github-actions <>
2021-11-15 10:57:01 -05:00
Thomas Rittson 9b68468710
Update jslib (#1154) 2021-11-12 09:33:22 +10:00
Oscar Hinton fa98ef37ec
Hide change password when using key connector (#1153) 2021-11-12 08:41:08 +10:00
Daniel James Smith 9124314ef9
Update package-lock.json to reflect update of electron to 14.2.0 (#1152) 2021-11-10 12:06:01 +01:00
Thomas Rittson afb30d5e0b
[Key Connector] Add support for key connector and OTP (#1135)
Co-authored-by: Hinton <oscar@oscarhinton.com>
2021-11-09 19:00:01 +01:00
Joseph Flinn aa73bde593
Version Bump to 1.29.2 (#1151) 2021-11-09 07:52:47 -08:00
Joseph Flinn d6c100afeb
Moving the push of the MAS artifact to the build workflow to enable manual publishing from TestFlight (#1150) 2021-11-09 07:26:30 -08:00
Joseph Flinn 4f77f12552
Updating the Crowin sync process (#1144) 2021-11-05 10:59:21 -07:00
Vince Grassia 086e09c7dc
Change release workflow to only allow releases from rc or hotfix branches (#1146) 2021-11-05 12:45:56 -04:00
Thomas Rittson f2a5fe4429
[Linked fields] Add Linked Field as custom field type (#1091)
* Add linked fields

* Update to use Field.linkedId

* Add missing deps

* Update jslib
2021-11-04 08:02:41 +10:00
Vince Grassia 6cea5e053d
Add Universal DMG Artifact (#1136) 2021-11-02 11:24:33 -04:00
Vince Grassia ecfbf2ba15
Add step to get Safari Extension branch ref (#1134) 2021-11-02 09:26:49 -04:00
Joseph Flinn 3ebfc14cbf
fixing typo in the checksum (#1133) 2021-11-01 08:01:16 -07:00
Vince Grassia 9edd154a0e
Version bump 1.29.1 (#1130) 2021-10-29 10:09:00 -04:00
Oscar Hinton 05470b489c
Ensure safari extension is included in mas and not only darwin (#1128)
* Ensure safari extension is included in mas and not only darwin

* Add support for re-signing mas

* Add support for mas-dev
2021-10-29 09:48:43 -04:00
Joseph Flinn 59bed9b12e
fixing the release asset names (#1124) 2021-10-27 13:10:15 -07:00
Joseph Flinn 4fa9325330
Version Bump 1.29.0 (#1123) 2021-10-27 08:37:15 -07:00
github-actions[bot] 5a179ec530
Autosync the updated translations (#1122)
Co-authored-by: github-actions <>
2021-10-27 07:41:25 -07:00
Thomas Rittson 22546932a2
Add PR template (#1121) 2021-10-27 19:02:07 +10:00
Thomas Rittson 52a30f4d8a
Fixes for dynamic modal a11y (#1107)
* Remove tabindex and cdkTrapFocus from modals

* Add styling for modal-dismiss

* Remove modal-dismiss styles

* Update jslib
2021-10-25 16:26:12 +10:00
Joseph Flinn a61ef74895
Updating the release constraints (#1118)
* updating the release constraints

* removing the master branch release ci code execution

* updating some verbiage
2021-10-22 08:41:15 -07:00
Oscar Hinton 6f69486c36
Remove empty catch blocks and remove allow-empty-catch tslint rule (#1117) 2021-10-21 11:10:36 +02:00
Vince Grassia 66d560aab5
Add notify constraint (#1112) 2021-10-15 13:07:05 -04:00
Kyle Spearrin bee11204b2
New Crowdin updates (#1111)
* New translations messages.json (Romanian)

* New translations messages.json (Estonian)

* New translations messages.json (Chinese Traditional)

* New translations messages.json (Vietnamese)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Indonesian)

* New translations messages.json (Persian)

* New translations messages.json (Bengali)

* New translations messages.json (Thai)

* New translations messages.json (Croatian)

* New translations messages.json (Norwegian Nynorsk)

* New translations messages.json (Latvian)

* New translations messages.json (Ukrainian)

* New translations messages.json (Azerbaijani)

* New translations messages.json (Hindi)

* New translations messages.json (English, United Kingdom)

* New translations messages.json (Esperanto)

* New translations messages.json (Filipino)

* New translations messages.json (Malayalam)

* New translations messages.json (Sinhala)

* New translations messages.json (Kannada)

* New translations messages.json (Norwegian Bokmal)

* New translations messages.json (Montenegrin (Latin))

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Turkish)

* New translations messages.json (French)

* New translations messages.json (Hebrew)

* New translations messages.json (Spanish)

* New translations messages.json (Afrikaans)

* New translations messages.json (Belarusian)

* New translations messages.json (Bulgarian)

* New translations messages.json (Catalan)

* New translations messages.json (Czech)

* New translations messages.json (Danish)

* New translations messages.json (German)

* New translations messages.json (Greek)

* New translations messages.json (Finnish)

* New translations messages.json (Hungarian)

* New translations messages.json (Swedish)

* New translations messages.json (Italian)

* New translations messages.json (Japanese)

* New translations messages.json (Korean)

* New translations messages.json (Dutch)

* New translations messages.json (Polish)

* New translations messages.json (Portuguese)

* New translations messages.json (Russian)

* New translations messages.json (Slovak)

* New translations messages.json (Slovenian)

* New translations messages.json (Serbian (Cyrillic))

* New translations messages.json (English, India)
2021-10-14 19:22:52 -04:00
github-actions[bot] 7046f8cfd3
Autosync the updated translations (#1110)
Co-authored-by: github-actions <>
2021-10-14 18:01:36 -04:00
Thomas Rittson 77ab177d2c
[Refactor] Use rxjs first instead of unsubscribe from queryParams (#1105)
* Use rxjs first instead of unsubscribe

* Remove unneeded variable

* Update jslib
2021-10-15 07:59:08 +10:00
Vince Grassia 7327ab75c9
Add Slack alerts for Build workflow failures (#1108) 2021-10-14 13:05:49 -04:00
Vince Grassia b66d32b57e
Upgrade workflows to new model (#1104)
* Update workflows to new Build/Test/Release model
2021-10-12 11:51:26 -04:00
Oscar Hinton 42fd0dd2a6
Bump jslib (#1103) 2021-10-11 19:40:46 +02:00
Vincent Salucci b5fd993bad
[Reset Password] Update jslib (#1102)
* Update jslib

* Updated constructor
2021-10-08 16:55:32 -05:00
Thomas Rittson d02ebea219
Update jslib (#1101) 2021-10-08 10:09:07 +10:00
Thomas Rittson 15e8e5fec9
Use theme enum and platformUtilsService helpers (#1094)
* Use new theme enum and platformUtilsService helper

* Use theme enum

* Update jslib

* Fix linting
2021-10-05 06:30:09 +10:00
Oscar Hinton 2639d13e42
Bump signalr to 5.0.10 (#1093) 2021-09-28 17:23:39 +02:00
Oscar Hinton e985018862
Bump Electron to v14 (#1088) 2021-09-28 16:51:53 +02:00
Oscar Hinton facedab33c
Use webfonts from jslib instead of downloading them using gulp (#1089)
* Use webfonts from jslib instead of downloading them using gulp

* Remove accidental command for disabling certificates

* Bump jslib
2021-09-27 14:27:39 +10:00
Vincent Salucci df382a3611
[Reset Password v1] Refactor ForcePasswordReset flow (#1067)
* [Reset Password v1] Refactor ForcePasswordReset flow

* Update jslib
2021-09-24 08:33:57 -05:00
Joseph Flinn bab33c3a64
Version bump to 1.28.3 (#1086) 2021-09-22 08:39:18 -07:00
github-actions[bot] 004f18e04d
Autosync the updated translations (#1085)
Co-authored-by: github-actions <>
2021-09-21 14:12:42 -07:00
Thomas Rittson c385efdbd2
Move custom fields to separate components (#1076)
* Move custom fields to own component

* Update jslib

* Fix import statements

* Fix linting
2021-09-21 10:48:17 +10:00
Oscar Hinton 0297ea57da
Use explicit import paths (#1084) 2021-09-20 10:41:57 +02:00
Vincent Salucci 762c026b6f
[SSO/Auto Enroll] Fixed typo for banner (#1083) 2021-09-16 23:09:23 -05:00
Joseph Flinn c5461f82c1
rolling back accidental changes to mac runner (#1081) 2021-09-16 11:10:12 -07:00
Joseph Flinn c99a543030
Pinning ast version (#1080)
* Pinning version of AST instead of using latest

* adding the pinned version of the commit

* adding an array join

* pinning version of dotnet

* trying the AST pin of the version we started using

* disabling jobs and adding test step to window job

* adding dotnet 2.1.x to see if that fixes the issue

* removing the test code and testing the addition of .net 2.1.x

* repinning to last successful sign

* trying the newest version of AST

* disabling the non-windows jobs again

* disabling the windows build job and added a test job

* removing stray comma

* changing the multiline delimiter

* pivoting away from our EV cert and testing with a test one

* switching back to the EV cert and adding a verbose flag

* disabling some steps that are breaking

* swithing back to the test cert

* testing new format for the ast command

* removing the node portions of the test since they are not needed

* trying AST without the tenat-id

* rolling back to original commit

* switching to custom AST for better troubleshooting

* removing the ast commit logic and forcing latest

* fixing up the pwsh sign command

* fixing the AST verison

* making sure that the secrets are not blank

* trying the EV cert for signing

* Using pinned commit from AST instead of custom code

* fixing env

* building the actually pinned commit instead of whatever the other thing was...

* testing the windows job

* removing the dotnet 2.1.x dependency since the older AST version shouldn't need it

* reenabling the test ast job since something is failing

* moving the git switch command

* testing new gh-action

* fixing the gh-action path

* updating the hash of the new action

* enabling the build jobs again

* updating the hash for the new Install AST action

* fixing linter issues
2021-09-16 10:15:05 -07:00
Vincent Salucci eac84128ed
update jslib (#1074) 2021-09-15 21:33:15 -05:00
Oscar Hinton aa19e678f7
Vault Timeout Policy (#1052) 2021-09-15 20:02:46 +02:00
Oscar Hinton da4af743f3
Disable Private Vault Export Policy (#1068) 2021-09-15 20:02:17 +02:00
Joseph Flinn e8da01bafb
adding more dependencies on the release update job (#1058) 2021-09-13 07:08:53 -07:00
Thomas Rittson ebaf27b7c9
Use a modal to set the unlock pin (#1064)
* Use separate modal to set pin

* Remove incorrect label

* Fix tab focus for settings and set-pin modals

* Remove leftover code

* Update jslib
2021-09-13 10:52:58 +10:00
Oscar Hinton cdac1a4508
Improve ViewComponent (#1069) 2021-09-10 15:32:08 +02:00
Thomas Rittson b552222132
Update jslib (#1066) 2021-09-10 07:50:59 +10:00
baylorrandolph 4287f617f0
Update README.md (#1062) 2021-09-09 09:00:14 -04:00
Oscar Hinton 6b59df2f39
Add issue template and template chooser (#1061) 2021-09-08 14:11:54 +02:00
Vincent Salucci c62144424f
[SSO/Auto Enroll] Set Password banner (#1053)
* [SSO/Auto Enroll] Set Password banner

* Update jslib
2021-09-07 12:11:43 -05:00
Matt Alexander dfd00bdaee
Fix typo in README (#1060) 2021-09-07 12:50:32 -04:00
Vince Grassia fcadedd458
Update workflows with linter suggestions (#1056) 2021-09-02 16:05:38 -04:00
Thomas Rittson 6bfd4ebafd
Update jslib (#1051) 2021-09-02 07:51:21 +10:00
Thomas Rittson 9494eb4b2d
Update jslib (#1050) 2021-09-01 07:12:35 +10:00
Vincent Salucci 39ac46aaa7
[Callout] Update UI structure (#1028)
* [Callout] Update UI structure

* Update jslib
2021-08-27 17:04:32 -05:00
Joseph Flinn 9dbd692e2d
Simplifying the Crowdin Sync workflow (#1048) 2021-08-27 10:08:32 -07:00
Oscar Hinton 2ba8925b81
Add password show/hide to reprompt (#959) 2021-08-27 15:30:44 +02:00
Joseph Flinn 5b4931e260
Reverting Chinese and Portuguese translations (#1044) 2021-08-25 09:23:10 -07:00
Joseph Flinn 1a6f283771
Removing the old setup logic that no longer works (#974)
* Removing the old setup logic that no longer works

* adding in formatting
2021-08-24 11:58:21 -07:00
Joseph Flinn 2d68fe37a1
Updating the release name (#1038) 2021-08-24 11:57:43 -07:00
Oscar Hinton 29b33b14e5
Bump version (#1040) 2021-08-23 12:03:19 +02:00
Oscar Hinton 9ae439b52f
Bump version to 1.28.1 (#1035) 2021-08-20 15:57:47 +02:00
Daniel James Smith a325ca2363
Added a comment to I18nService (#1032) 2021-08-19 22:40:33 +02:00
Vince Grassia 741fc69343
Revert EN Crowdin sync (#1031) 2021-08-19 13:45:56 -04:00
github-actions[bot] 026ee20250
Autosync Crowdin Translations (#1021)
* Autosync Crowdin translations

* Autosync Crowdin translations

Co-authored-by: github-actions <>
2021-08-18 14:24:16 -07:00
Daniel James Smith 72b688e241
Fix broken link to open Edge extension store from Help menu (#1025) 2021-08-18 07:46:53 +02:00
Matt Gibson 3100f55d51
Version bump to 1.28.0 (#1027) 2021-08-17 12:46:46 -05:00
Oscar Hinton 3cbb336416
Close proxy application when stdin is closed (#1024) 2021-08-17 14:01:31 +02:00
Joseph Flinn 99b8be81f6
Crowdin sync workflow (#1022)
* Initial addition of the crowdin sync workflow for testing

* adding some echo statements for debugging

* adding logic to gracefully exit if there are no new updates

* adding logic to select the correct diff_branch
2021-08-13 13:27:46 -07:00
Joseph Flinn 99b9a0951a
Adding stub for crowdin sync testing (#1020) 2021-08-13 07:29:43 -07:00
Matt Gibson a76f8749ca
Set iframe allow on window load (#1019)
* Set webauthn allow on initial load

* Update jslib
2021-08-13 09:24:07 -05:00
Vincent Salucci d82378a7a0
[Reset Password v1] Update Temp Password (#1015) 2021-08-11 15:49:44 -04:00
Thomas Rittson 816249a48a
Use cdk-virtual-scroll for long cipher lists (#1001)
* Use cdk-virtual-scroll for cipher lists

* add trackBy, reorder dom

* Undo merge conflict error

* Fix layout, increase scrolling buffer

* fix linting

* Remove unused infinite-scroll directives for Send

* Add back refresh method

* Update jslib

* Fix itemSize and min/maxBufferPx directives

* Move refresh() into base class

* Use cipherListVirtualScroll strategy

* fix linting

* Update to use latest virtual-scroll strategy

* Update jslib
2021-08-11 13:00:04 +10:00
Daniel James Smith 157d9478d4
Remove dependency on duo_web_sdk and update jslib (#1006) 2021-07-28 19:50:06 +02:00
Oscar Hinton 20561fff87
Add support for helpers in environment service (#1002)
* Add support for helpers in environment service

* Add environment service to register component

* Bump jslib
2021-07-23 17:15:32 -04:00
Matt Gibson c863d68057
Feature/use hcaptcha if bot (#1000)
* Add captcha to login component

* Add catpcha to login page

* Update content width if captcha is visible

* extend submit to handle widening if captcha is required

* Improve login styling

* Add Captcha to registration page

* Remove padding from captcha div

The padding was messing up image selection of captcha items

* Update jslib

* PR review

* update jslib
2021-07-23 13:48:10 -05:00
Addison Beck d7287e7aa3
set Send date presets to Custom if editing a send (#997) 2021-07-21 12:43:40 -04:00
Addison Beck 0682269e34
Resolved Safari Date/Time Issues In Send (#992)
* cleaned up date and time logic for Send

* updated jslib

* set up change detection for initial form values on data swap
2021-07-19 09:56:31 -04:00
Kyle Spearrin 9201730fe1 remove old code from #351 2021-07-12 10:11:43 -04:00
Trey Greer 6990056c04
Add AZ language (#988) 2021-07-12 07:44:40 +10:00
Joseph Flinn d5e9de2b8b
fixing the delayed release logic (#987) 2021-07-09 07:31:34 -07:00
Kyle Spearrin ccdd45b09e
New Crowdin updates (#983)
* New translations messages.json (Romanian)

* New translations messages.json (Ukrainian)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Chinese Traditional)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Persian)

* New translations messages.json (Estonian)

* New translations messages.json (Swedish)

* New translations messages.json (Azerbaijani)

* New translations messages.json (English, United Kingdom)

* New translations messages.json (Kannada)

* New translations messages.json (Turkish)

* New translations messages.json (Serbian (Cyrillic))

* New translations messages.json (Finnish)

* New translations messages.json (Bulgarian)

* New translations messages.json (Catalan)

* New translations messages.json (Czech)

* New translations messages.json (Danish)

* New translations messages.json (German)

* New translations messages.json (Hebrew)

* New translations messages.json (Hungarian)

* New translations messages.json (Italian)

* New translations messages.json (Japanese)

* New translations messages.json (Korean)

* New translations messages.json (Dutch)

* New translations messages.json (Polish)

* New translations messages.json (Russian)

* New translations messages.json (Slovak)

* New translations messages.json (English, India)
2021-07-07 17:39:11 -04:00
Chad Scharf d70de84fb7
[chore] version bump 1.27.1 (#982) 2021-07-07 17:23:56 -04:00
Shashank S 359daffd9e
Use radio buttons for password generator type instead of dropdown (#955)
* fix: radio instead of dropdown

* fix: remove, depend on upstream jslib

* chore: remove unnecessary label

* fix: missing tag

* chore: add label, remove dupl. intlz.

* feat: update jslib version

* Revert "feat: update jslib version"

This reverts commit 85f4b758bd.

* Update jslib

Co-authored-by: Thomas Rittson <trittson@bitwarden.com>
2021-07-07 21:28:41 +10:00
Trey Greer cf56b68ba5
add Kannada language (#980) 2021-07-07 07:40:17 +10:00
Thomas Rittson 3aa171a664
[macOS] Don't enable secure input when app is not in focus (#970)
* Don't engage macOS secure input if not focused

* Refactor to use focusInputOnPageLoad

* Fix style and linting

* Refactor to remove focusOnPageLoad

* Update jslib
2021-07-05 08:06:24 +10:00
Joseph Flinn 6d8fbf1e43
changing the default browser extension branch to rc (#975) 2021-07-01 10:19:52 -07:00
Oscar Hinton c89ca36f51
Add SDKROOT to release workflow (#973) 2021-06-30 21:41:45 +02:00
Kyle Spearrin 8a01dcb87d
New Crowdin updates (#971)
* New translations messages.json (Romanian)

* New translations messages.json (Thai)

* New translations messages.json (Ukrainian)

* New translations messages.json (Chinese Simplified)

* New translations messages.json (Chinese Traditional)

* New translations messages.json (Vietnamese)

* New translations messages.json (Portuguese, Brazilian)

* New translations messages.json (Indonesian)

* New translations messages.json (Persian)

* New translations messages.json (Bengali)

* New translations messages.json (Croatian)

* New translations messages.json (Swedish)

* New translations messages.json (Estonian)

* New translations messages.json (Latvian)

* New translations messages.json (English, United Kingdom)

* New translations messages.json (Esperanto)

* New translations messages.json (Malayalam)

* New translations messages.json (Sinhala)

* New translations messages.json (Kannada)

* New translations messages.json (Norwegian Bokmal)

* New translations messages.json (Montenegrin (Latin))

* New translations messages.json (Turkish)

* New translations messages.json (Serbian (Cyrillic))

* New translations messages.json (French)

* New translations messages.json (Finnish)

* New translations messages.json (Spanish)

* New translations messages.json (Afrikaans)

* New translations messages.json (Belarusian)

* New translations messages.json (Bulgarian)

* New translations messages.json (Catalan)

* New translations messages.json (Czech)

* New translations messages.json (Danish)

* New translations messages.json (German)

* New translations messages.json (Greek)

* New translations messages.json (Hebrew)

* New translations messages.json (Slovenian)

* New translations messages.json (Hungarian)

* New translations messages.json (Italian)

* New translations messages.json (Japanese)

* New translations messages.json (Korean)

* New translations messages.json (Dutch)

* New translations messages.json (Polish)

* New translations messages.json (Portuguese)

* New translations messages.json (Russian)

* New translations messages.json (Slovak)

* New translations messages.json (English, India)
2021-06-29 15:33:15 -04:00
Vincent Salucci 4f781be542
[Version] Bump to 1.27.0 (#969) 2021-06-28 12:39:17 -05:00
Addison Beck f862fc3691
fixed the icon for sends being swapped between file and text sends (#967) 2021-06-24 15:45:36 +00:00
Oscar Hinton d748e0007e
Remove entryComponents (#966) 2021-06-24 17:13:22 +02:00
Matt Gibson 56a1cfe277
Redefine cipher "share" to "move to organization" (#961)
* Redefine cipher "share" to "move to organization"

* Update jslib

* PR review
2021-06-21 19:26:37 -05:00
Oscar Hinton 9c4ea9b491
Add reprompt help link (#963) 2021-06-21 20:56:37 +02:00
Vincent Salucci e0d1923237
[Toast] - BUG - Fixed styles (#957) 2021-06-16 14:44:17 -05:00
Matt Gibson bd0fb024c1
Always get key from storage to ensure biometric prompt. (#952)
* Always get key from storage to ensure biometric prompt.

* Update jslib

* Update jslib
2021-06-15 13:40:34 -05:00
Matt Gibson 3b4142bd0d
Merge pull request #946 from bitwarden/authenticate-with-secure-storage-service
Authenticate with secure storage service
2021-06-11 16:42:52 -05:00
Matt Gibson db688d208d Use default cache directory 2021-06-11 14:05:28 -04:00
Matt Gibson 1fc8c02579 Remove node_modules cache
`npm ci` deletes node_modules as a first step, so makes no sense to cache
2021-06-11 13:52:39 -04:00
Matt Gibson 1b96afe283 Cache npm directory and always run `npm ci` 2021-06-11 13:52:39 -04:00
Matt Gibson fc015bd4cb Default to development environment settings 2021-06-10 15:37:39 -04:00
Matt Gibson e751d24b35 Supply main sourcemaps only in dev builds 2021-06-10 12:50:59 -04:00
Matt Gibson ecd22e4d45 Update jslib 2021-06-09 16:56:12 -04:00
Matt Gibson 05e9419d65 Request biometrically secured stored key 2021-06-09 16:55:50 -04:00
Matt Gibson 29d538c3e6 Include main process source maps for debugging 2021-06-09 16:55:50 -04:00
Matt Gibson 1867949754
Merge pull request #947 from bitwarden/update-jslib
upate jslib
2021-06-09 08:51:43 -05:00
Matt Gibson 3888a9cdbb upate jslib 2021-06-09 09:28:58 -04:00
Oscar Hinton 296340a5be
Add jslib as a "real" dependency (#941)
* Add jslib as a "real" dependency

* Move more packages to jslib

* Remove some unesessary dev dependencies.

* Add back missing preinstall

* Revert jslib bump

* Fix jslib containing wrong types/node.

* Bump jslib

* Remove unessesary alias

* Remove dummy module
2021-06-07 19:26:36 +02:00
Vince Grassia 5ae7490478
MacOS Build Asset and Workflow Optimization (#942)
* adding more testable assets to the desktop build

* fixing typo

* renaming job

* fixing loading safari extension

* Fix typo

* Update workflows to use new Node caching

* Move checkout actions to beginning of jobs

* Add Run ID to key for Node cache

* Add Runner OS to cache actions

* Fix build commands by putting 'npx' in front

* Update builds to use other scripts in package.json

* Set up keychain for macos-package-dev

* Add 'Increment version' step to build workflow

* Disable MacOS dev build. Test other MacOS builds

* Add provisioning profile steps to other MacOS builds

* Remove test branch code

Co-authored-by: Joseph Flinn <joseph.s.flinn@gmail.com>
2021-06-07 12:00:13 -04:00
Thomas Rittson f0716c62d2
Merge pull request #929 from bitwarden/responsive-theme-change
Respond to OS theme changes
2021-06-03 07:47:07 +10:00
Chad Scharf 2cf4da8886
Merge pull request #940 from tgreer-bw/store-asset-update
New screenshots for MacOS + Windows
2021-06-02 14:35:45 -04:00
tgreer-bw c84ac6407a new screenshots 2021-06-02 13:54:46 -04:00
Oscar Hinton ea3316742c
Bump version to 1.26.5 (#938) 2021-06-02 18:09:20 +02:00
Thomas Rittson 6edd600006 Move theme update logic to services.module.ts 2021-06-02 07:28:21 +10:00
Vince Grassia 163351c3e7
Update pipelines (#936)
* Update workflows for consistency

* Update pipelines

- Trigger deploy workflow manually
- Publish release draft at the end of deploy workflow

* Enable artifact uploads for all branches and fail if no asset is found during upload

* Add if statements back in for MacOS

* Change Build application (dev) step
2021-06-01 17:14:02 -04:00
Thomas Rittson 98f614aeda bump jslib 2021-06-02 07:11:54 +10:00
Joseph Flinn 60f3d5d33e
Merge pull request #935 from bitwarden/constrain-release-rc
constraining releases to the rc branch
2021-06-01 11:45:31 -07:00
Joseph Flinn adb16783cf constraining releases to the rc branch 2021-06-01 11:21:04 -07:00
Tom Rittson b00df0112e Let all OS' use system theme on startup 2021-05-31 14:34:59 +10:00
Thomas Rittson 7f5a5a5fbb Only update to system theme if theme is Default 2021-05-31 14:34:59 +10:00
Thomas Rittson c225210a44 Respond to native OS theme changes 2021-05-31 14:34:53 +10:00
Oscar Hinton c7345197f7
Password reprompt fixes (#926)
* Hide card number when hidden

* Avoid double password prompts

* Bump jslib
2021-05-28 20:08:44 +02:00
Oscar Hinton c89da7f12b
Hardcode SDKRoot (#925)
* Hardcode SDKRoot

* Re-add branch check for app store
2021-05-28 19:38:09 +02:00
Thomas Rittson 78f9dd50ad
Merge pull request #924 from bitwarden/jslib-bump
bump jslib
2021-05-28 09:46:34 +10:00
Thomas Rittson a109259812 bump jslib 2021-05-28 07:56:30 +10:00
Oscar Hinton 42d280ac09
Bump NPM to v7 (#922)
* Bump NPM to v7

* Bump npm in build

* Add NPM v7 to readme

* Update node-gyp
2021-05-26 22:44:48 +02:00
Thomas Rittson b16f8bc253
Merge pull request #914 from bitwarden/hotfix-bump
Version bump to 1.26.4
2021-05-21 11:00:42 +10:00
Thomas Rittson f5175564b3 Version bump to 1.26.4 2021-05-21 08:59:07 +10:00
Thomas Rittson f5042bc07b
Merge pull request #905 from bitwarden/fix-set-saving
Convert Sets to Arrays before saving locally
2021-05-20 06:37:27 +10:00
Thomas Rittson 5bd7444e53 bump jslib 2021-05-19 10:11:24 +10:00
Chad Scharf 42091ac6d3
Merge pull request #903 from djsmith85/update-nvmrc
Update .nvmrc from 10.13.0 to 14.17.0
2021-05-18 14:58:41 -04:00
Daniel James Smith 9a2b2069b5 Update .nvmrc from 10.13.0 to 14.17.0 2021-05-18 18:30:24 +02:00
Vince Grassia 28ebbccbf1
Pin versions of actions in workflow (#901) 2021-05-18 09:21:26 -04:00
Chad Scharf 0156f7ba2d
Merge pull request #900 from bitwarden/fix-locale-typo
Fix locale typo
2021-05-17 16:48:02 -04:00
Vince Grassia c9ae2ed933 Update ME lang import to proper order 2021-05-17 16:25:57 -04:00
Vince Grassia 6f6de60509 Fix locale import typo 2021-05-17 16:24:11 -04:00
Chad Scharf 4a0be96b79
Merge pull request #898 from djsmith85/fix-me-locale
Fixed locale import for Montenegrin (Latin)
2021-05-17 14:43:58 -04:00
Daniel James Smith cae76cd74a Fixed locale import for Montenegrin (Latin) 2021-05-17 18:01:44 +02:00
Chad Scharf 012aa71054
Merge pull request #897 from tgreer-bw/language-adds
Add missing languages from Crowdin
2021-05-15 15:25:23 -04:00
Trey Greer cc165420f7
Update src/services/i18n.service.ts
Co-authored-by: Chad Scharf <3904944+cscharf@users.noreply.github.com>
2021-05-14 18:19:45 -04:00
tgreer-bw a24618be32 add missing languages from Crowdin 2021-05-14 16:42:12 -04:00
Chad Scharf 969a62de9e
Merge pull request #891 from djsmith85/update-readme
Adjust node version in README.md
2021-05-13 17:30:03 -04:00
Kyle Spearrin 0d5d8b671d
use swal titletext to avoid XSS (#884) 2021-05-13 15:22:52 -04:00
Thomas Rittson 55b0118240
Merge pull request #892 from bitwarden/improve-import-error-checking
Bump jslib
2021-05-13 11:23:49 +10:00
Thomas Rittson 2a471867aa bump jslib 2021-05-13 11:00:55 +10:00
Thomas Rittson 68096c1f12 update service deps 2021-05-13 10:53:38 +10:00
Daniel James Smith 731e44fd06 Adjust node version in README.md 2021-05-13 01:37:33 +02:00
Chad Scharf ee1f31d300 Version bump 1.26.3 2021-05-12 17:57:23 -04:00
Chad Scharf dd683e8dad Merge branch 'master' of https://github.com/bitwarden/desktop into master 2021-05-12 16:53:19 -04:00
Chad Scharf 2bf9f34472 Version bump 1.26.2 2021-05-12 16:53:17 -04:00
Oscar Hinton 8f7ab9f8db
Bump node to 14 (#869)
* Bump node to 14

* Bump some dependencies

* Bump jslib

* Ensure compatability with latest jslib

* Change node engine to ~14.
2021-05-12 22:38:02 +02:00
Chad Scharf 7d53ff788f Version bump to 1.26.1 2021-05-12 15:54:14 -04:00
Joseph Flinn 80ea232eb6
Merge pull request #889 from bitwarden/fix-desktop-deploy
Fix desktop deploy
2021-05-12 11:02:48 -07:00
Joseph Flinn 72c26ae999 switching one more PKG_VERSION environment variable 2021-05-12 10:57:48 -07:00
Joseph Flinn 3eb691fbd8 switching the env name 2021-05-12 10:54:20 -07:00
Joseph Flinn 7d959ffffb fixing the choco release asset grab 2021-05-12 10:53:20 -07:00
Joseph Flinn e2e41b7366 fixing the macos deploy 2021-05-12 10:47:58 -07:00
Joseph Flinn d50bb7bf3a fixing the snap deploy 2021-05-12 10:47:05 -07:00
Vince Grassia 64492d95cf
Update workflows to accommodate universal pkg artifact for Mac (#888) 2021-05-12 10:59:30 -04:00
Joseph Flinn d05cd38e70
Merge pull request #886 from bitwarden/fix-release-pipeline
Fix release pipeline
2021-05-11 14:45:21 -07:00
Joseph Flinn 95c1876178 Merge branch 'master' into fix-release-pipeline 2021-05-11 14:41:15 -07:00
Joseph Flinn cac06e473e removing the broken testing code 2021-05-11 14:41:10 -07:00
Chad Scharf 590a67d38d
Merge pull request #882 from djsmith85/fix-typo
Fix typo in webAuthnAuthenticate
2021-05-11 17:20:11 -04:00
Joseph Flinn 525f0e8a66
Merge pull request #885 from bitwarden/fix-release-pipeline
removing the unix flags from the pwsh
2021-05-11 14:10:45 -07:00
Joseph Flinn 564d170d7a removing the unix flags from the pwsh 2021-05-11 14:07:03 -07:00
Daniel James Smith 00781806f5 Fix typo in webAuthnAuthenticate 2021-05-11 21:04:18 +02:00
Chad Scharf 33d2c63798
Merge pull request #881 from bitwarden/l10n_master
New Crowdin updates
2021-05-11 14:01:04 -04:00
Kyle Spearrin 23e20ae0a3 New translations messages.json (English, India) 2021-05-11 13:47:37 -04:00
Kyle Spearrin 608505f9e6 New translations messages.json (Russian) 2021-05-11 13:47:36 -04:00
Kyle Spearrin dc3c33abad New translations messages.json (Portuguese) 2021-05-11 13:47:35 -04:00
Kyle Spearrin 2d022773ad New translations messages.json (Polish) 2021-05-11 13:47:34 -04:00
Kyle Spearrin 69f4782e46 New translations messages.json (Dutch) 2021-05-11 13:47:32 -04:00
Kyle Spearrin c9b9bd6ea5 New translations messages.json (Korean) 2021-05-11 13:47:31 -04:00
Kyle Spearrin 045e7b7001 New translations messages.json (Japanese) 2021-05-11 13:47:30 -04:00
Kyle Spearrin 728b4e06f5 New translations messages.json (Italian) 2021-05-11 13:47:29 -04:00
Kyle Spearrin c9af991027 New translations messages.json (Hungarian) 2021-05-11 13:47:27 -04:00
Kyle Spearrin 4301f5d881 New translations messages.json (Hebrew) 2021-05-11 13:47:26 -04:00
Kyle Spearrin 8b6d0a8a07 New translations messages.json (Slovak) 2021-05-11 13:47:25 -04:00
Kyle Spearrin 5581ec6aa1 New translations messages.json (Finnish) 2021-05-11 13:47:23 -04:00
Kyle Spearrin b143010486 New translations messages.json (German) 2021-05-11 13:47:22 -04:00
Kyle Spearrin 3a907bf3fa New translations messages.json (Danish) 2021-05-11 13:47:21 -04:00
Kyle Spearrin 79187c5782 New translations messages.json (Czech) 2021-05-11 13:47:20 -04:00
Kyle Spearrin 6a89651588 New translations messages.json (Catalan) 2021-05-11 13:47:18 -04:00
Kyle Spearrin 08a9a81992 New translations messages.json (Bulgarian) 2021-05-11 13:47:17 -04:00
Kyle Spearrin 9701fa9736 New translations messages.json (Belarusian) 2021-05-11 13:47:16 -04:00
Kyle Spearrin 765ef26340 New translations messages.json (Afrikaans) 2021-05-11 13:47:14 -04:00
Kyle Spearrin 3c83c14bb8 New translations messages.json (Spanish) 2021-05-11 13:47:13 -04:00
Kyle Spearrin 0ca036b968 New translations messages.json (Greek) 2021-05-11 13:47:12 -04:00
Kyle Spearrin 157dfabaae New translations messages.json (French) 2021-05-11 13:47:11 -04:00
Kyle Spearrin f82d900cc2 New translations messages.json (Slovenian) 2021-05-11 13:47:09 -04:00
Kyle Spearrin 444511152c New translations messages.json (Swedish) 2021-05-11 13:47:08 -04:00
Kyle Spearrin 9b294bf4dd New translations messages.json (Montenegrin (Latin)) 2021-05-11 13:47:07 -04:00
Kyle Spearrin 035d6ee5b3 New translations messages.json (Norwegian Bokmal) 2021-05-11 13:47:05 -04:00
Kyle Spearrin f024b33e02 New translations messages.json (Sinhala) 2021-05-11 13:47:03 -04:00
Kyle Spearrin d3bb87ccb7 New translations messages.json (Malayalam) 2021-05-11 13:47:02 -04:00
Kyle Spearrin 57f8176aac New translations messages.json (Esperanto) 2021-05-11 13:47:01 -04:00
Kyle Spearrin fb4cb327ab New translations messages.json (English, United Kingdom) 2021-05-11 13:46:59 -04:00
Kyle Spearrin 64cee80521 New translations messages.json (Latvian) 2021-05-11 13:46:58 -04:00
Kyle Spearrin cb73582038 New translations messages.json (Estonian) 2021-05-11 13:46:57 -04:00
Kyle Spearrin 203c44bace New translations messages.json (Croatian) 2021-05-11 13:46:56 -04:00
Kyle Spearrin 19e09243fb New translations messages.json (Serbian (Cyrillic)) 2021-05-11 13:46:55 -04:00
Kyle Spearrin e8e888698d New translations messages.json (Thai) 2021-05-11 13:46:54 -04:00
Kyle Spearrin 6b1c15519d New translations messages.json (Persian) 2021-05-11 13:46:52 -04:00
Kyle Spearrin 2402a6f4c6 New translations messages.json (Indonesian) 2021-05-11 13:46:51 -04:00
Kyle Spearrin 6f92b55f40 New translations messages.json (Portuguese, Brazilian) 2021-05-11 13:46:50 -04:00
Kyle Spearrin 2992a31b61 New translations messages.json (Vietnamese) 2021-05-11 13:46:48 -04:00
Kyle Spearrin 061996bf55 New translations messages.json (Chinese Traditional) 2021-05-11 13:46:47 -04:00
Kyle Spearrin 0a288899e7 New translations messages.json (Chinese Simplified) 2021-05-11 13:46:46 -04:00
Kyle Spearrin da8697ea94 New translations messages.json (Ukrainian) 2021-05-11 13:46:44 -04:00
Kyle Spearrin d5e5dfc1d5 New translations messages.json (Turkish) 2021-05-11 13:46:43 -04:00
Kyle Spearrin 21a3c4357a New translations messages.json (Bengali) 2021-05-11 13:46:42 -04:00
Kyle Spearrin 5db26cbcc6 New translations messages.json (Romanian) 2021-05-11 13:46:41 -04:00
Oscar Hinton af5898a001
Add setting for disabling auto prompt of biometrics (#873)
* Add setting for disabling auto prompt of biometrics

* Ensure window is visible before prompting for biometrics
2021-05-06 20:19:48 +02:00
Oscar Hinton a712917f47
Fix VS code ts language server no longer working after #866 (#872) 2021-05-06 16:45:27 +02:00
Oscar Hinton 266f089b3e
Cleanup tsconfig (#866)
* Simplify tsconfig

* Add separate tsconfig for renderer to get rid of last warnings
2021-05-05 09:47:35 +02:00
Oscar Hinton 2bdd7413aa
Block save button when uploading a send (#871)
* Block save button when uploading a send

* Add overflow hidden to prevent scrollbar appearing
2021-05-04 23:36:57 +02:00
Chad Scharf 3a342be095
Merge pull request #870 from gryffs/box-content-flex
Add flexbox to cipher list to correct display center issue.
2021-05-04 16:05:26 -04:00
Oscar Hinton 42564285d9
Password reprompt (#838)
* Add support for password reprompt
2021-05-04 21:32:03 +02:00
Chad Griffis 49748ee05a Replace single quote with double quotes in HTML and use div in place of a element. 2021-05-03 23:31:45 +08:00
Chad Griffis 0c12367721 Add flexbox to cipher list to correct display center issue. 2021-05-03 17:17:19 +08:00
Oscar Hinton 20b8a83dd8
Disconnect active connections when closing native messaging. Fix exe path on windows (#865) 2021-05-03 09:59:40 +02:00
Thomas Rittson 163fa2aa41
Merge pull request #851 from gryffs/prompt-trigger-apwd
Implement the markAsDirty form controls for AddEditComponent(#761)

Prevents add-edit page from closing if new password has been generated
2021-05-03 07:45:03 +10:00
Chad Griffis 7bed3b0b59 Update a formatting issue with markPasswordAsDirty 2021-05-01 16:44:40 +08:00
Oscar Hinton 418625682a
Write native messaging manifests for Chromium (#862) 2021-04-29 16:12:57 +02:00
Chad Scharf 2f2a76d186
Merge pull request #860 from djsmith85/bump-jslib
Bump jslib to include fix for lastpass totp import
2021-04-29 05:59:13 -04:00
Daniel James Smith 422180fed1 Bump jslib to include fix for lastpass totp import 2021-04-29 00:01:25 +02:00
Oscar Hinton ea90aebaba
Bump jslib for download in renderer (#859) 2021-04-27 17:17:49 +02:00
Chad Scharf 7e52657de6
Merge pull request #856 from gryffs/update-jslib
update submodule
2021-04-26 15:21:13 -04:00
Thomas Rittson eb1c5f809a
Merge pull request #853 from bitwarden/fix-biometric-button
Don't submit form when unlocking with biometrics
2021-04-26 08:35:08 +10:00
Chad Griffis 113937b3d3 update submodule 2021-04-23 18:57:39 +08:00
Oscar Hinton e6e79917f7
Bump dependencies (#848)
* Bump dependencies
2021-04-23 10:45:30 +02:00
Tom Rittson cf29c35e07 Don't submit form when unlocking with biometrics 2021-04-23 10:58:44 +10:00
Oscar Hinton 6dc82a8707
Change unlock biometric button to be selectable using tab (#846) 2021-04-22 20:00:05 +02:00
Vincent Salucci 227a1eaff9
[Version] Bump to 1.26.0 (#852) 2021-04-22 12:13:17 -05:00
Chad Griffis 06f2364733 Implement the markAsDirty form controls for AddEditComponent(#761). 2021-04-22 23:24:59 +08:00
300 changed files with 64203 additions and 25309 deletions

View File

@ -12,4 +12,4 @@ insert_final_newline = true
[*.{js,ts,scss,html}]
charset = utf-8
indent_style = space
indent_size = 4
indent_size = 2

9
.eslintignore Normal file
View File

@ -0,0 +1,9 @@
dist
build
jslib
webpack.main.js
webpack.renderer.js
src/scripts/duo.js
desktop_native
**/node_modules

32
.eslintrc.json Normal file
View File

@ -0,0 +1,32 @@
{
"root": true,
"env": {
"browser": true,
"node": true
},
"extends": ["./jslib/shared/eslintrc.json"],
"rules": {
"import/order": [
"error",
{
"alphabetize": {
"order": "asc"
},
"newlines-between": "always",
"pathGroups": [
{
"pattern": "jslib-*/**",
"group": "external",
"position": "after"
},
{
"pattern": "src/**/*",
"group": "parent",
"position": "before"
}
],
"pathGroupsExcludedImportTypes": ["builtin"]
}
]
}
}

2
.git-blame-ignore-revs Normal file
View File

@ -0,0 +1,2 @@
# Apply Prettier https://github.com/bitwarden/desktop/pull/1202
521feae535d83166e620c3c28dfc3e7b0314a00e

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text=auto eol=lf

85
.github/ISSUE_TEMPLATE/bug.yml vendored Normal file
View File

@ -0,0 +1,85 @@
name: Bug Report
description: File a bug report
labels: [bug]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
Please do not submit feature requests. The [Community Forums](https://community.bitwarden.com) has a section for submitting, voting for, and discussing product feature requests.
- type: textarea
id: reproduce
attributes:
label: Steps To Reproduce
description: How can we reproduce the behavior.
value: |
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. Click on '...'
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected Result
description: A clear and concise description of what you expected to happen.
validations:
required: true
- type: textarea
id: actual
attributes:
label: Actual Result
description: A clear and concise description of what is happening.
validations:
required: true
- type: textarea
id: screenshots
attributes:
label: Screenshots or Videos
description: If applicable, add screenshots and/or a short video to help explain your problem.
- type: textarea
id: additional-context
attributes:
label: Additional Context
description: Add any other context about the problem here.
- type: dropdown
id: os
attributes:
label: Operating System
description: What operating system are you seeing the problem on?
multiple: true
options:
- Windows
- macOS
- Linux
validations:
required: true
- type: input
id: os-version
attributes:
label: Operating System Version
description: What version of the operating system(s) are you seeing the problem on?
- type: dropdown
id: install-method
attributes:
label: Installation method
multiple: true
options:
- Direct Download (from bitwarden.com)
- Mac App Store
- Microsoft Store
- Homebrew
- Chocolatey
- Snap
- Other
validations:
required: true
- type: input
id: version
attributes:
label: Build Version
description: What version of our software are you running? (go to "Help" → "About Bitwarden" in the app)
validations:
required: true

14
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,14 @@
blank_issues_enabled: false
contact_links:
- name: Feature Requests
url: https://community.bitwarden.com/c/feature-requests/
about: Request new features using the Community Forums. Please search existing feature requests before making a new one.
- name: Bitwarden Community Forums
url: https://community.bitwarden.com
about: Please visit the community forums for general community discussion, support and the development roadmap.
- name: Customer Support
url: https://bitwarden.com/contact/
about: Please contact our customer support for account issues and general customer support.
- name: Security Issues
url: https://hackerone.com/bitwarden
about: We use HackerOne to manage security disclosures.

32
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,32 @@
## Type of change
- [ ] Bug fix
- [ ] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [ ] Other
## Objective
<!--Describe what the purpose of this PR is. For example: what bug you're fixing or what new feature you're adding-->
## Code changes
<!--Explain the changes you've made to each file or major component. This should help the reviewer understand your changes-->
<!--Also refer to any related changes or PRs in other repositories-->
- **file.ext:** Description of what was changed and why
## Screenshots
<!--Required for any UI changes. Delete if not applicable-->
## Testing requirements
<!--What functionality requires testing by QA? This includes testing new behavior and regression testing-->
## Before you submit
- [ ] I have checked for **linting** errors (`npm run lint`) (required)
- [ ] This change requires a **documentation update** (notify the documentation team)
- [ ] This change has particular **deployment requirements** (notify the DevOps team)

View File

@ -1,29 +0,0 @@
param (
[Parameter(Mandatory=$true)]
[string] $filename,
[string] $output
)
$homePath = Resolve-Path "~" | Select-Object -ExpandProperty Path
$rootPath = $env:GITHUB_WORKSPACE
$secretInputPath = $rootPath + "/.github/secrets"
$input = $secretInputPath + "/" + $filename
$passphrase = $env:DECRYPT_FILE_PASSWORD
$secretOutputPath = $homePath + "/secrets"
if ([string]::IsNullOrEmpty($output)) {
if ($filename.EndsWith(".gpg")) {
$output = $secretOutputPath + "/" + $filename.TrimEnd(".gpg")
} else {
$output = $secretOutputPath + "/" + $filename + ".plaintext"
}
}
if (!(Test-Path -Path $secretOutputPath))
{
New-Item -ItemType Directory -Path $secretOutputPath
}
gpg --quiet --batch --yes --decrypt --passphrase="$passphrase" --output $output $input

View File

@ -1,5 +0,0 @@
$rootPath = $env:GITHUB_WORKSPACE;
$packageVersion = (Get-Content -Raw -Path $rootPath\src\package.json | ConvertFrom-Json).version;
Write-Output "Setting package version to $packageVersion";
Write-Output "PACKAGE_VERSION=$packageVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append;

View File

@ -1,11 +0,0 @@
$rootPath = $env:GITHUB_WORKSPACE;
$decryptSecretPath = $($rootPath + "/.github/scripts/decrypt-secret.ps1");
Invoke-Expression "& `"$decryptSecretPath`" -filename bitwarden-desktop-key.p12.gpg"
Invoke-Expression "& `"$decryptSecretPath`" -filename appstore-app-cert.p12.gpg"
Invoke-Expression "& `"$decryptSecretPath`" -filename appstore-installer-cert.p12.gpg"
Invoke-Expression "& `"$decryptSecretPath`" -filename devid-app-cert.p12.gpg"
Invoke-Expression "& `"$decryptSecretPath`" -filename devid-installer-cert.p12.gpg"
Invoke-Expression "& `"$decryptSecretPath`" -filename macdev-cert.p12.gpg"
Invoke-Expression "& `"$decryptSecretPath`" -filename bitwarden_desktop_appstore.provisionprofile.gpg"

View File

@ -1,8 +0,0 @@
$rootPath = $env:GITHUB_WORKSPACE;
$packagePath = "$rootPath\package.json";
$buildNumber = 500 + [int]$env:GITHUB_RUN_NUMBER;
Write-Output "Setting build number to $buildNumber";
Write-Output "BUILD_NUMBER=$buildNumber" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append;
$package = Get-Content -Raw -Path $packagePath | ConvertFrom-Json;
$package.build | Add-Member -MemberType NoteProperty -Name buildVersion -Value "$buildNumber";
$package | ConvertTo-Json -Depth 32 | Set-Content $packagePath;

View File

@ -1,21 +0,0 @@
$homePath = Resolve-Path "~" | Select-Object -ExpandProperty Path;
$secretsPath = $homePath + "/secrets"
$desktopKeyPath = $($secretsPath + "/bitwarden-desktop-key.p12");
$devidAppCertPath = $($secretsPath + "/devid-app-cert.p12");
$devidInstallerCertPath = $($secretsPath + "/devid-installer-cert.p12");
$appstoreAppCertPath = $($secretsPath + "/appstore-app-cert.p12");
$appstoreInstallerCertPath = $($secretsPath + "/appstore-installer-cert.p12");
$macdevCertPath = $($secretsPath + "/macdev-cert.p12");
security create-keychain -p $env:KEYCHAIN_PASSWORD build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p $env:KEYCHAIN_PASSWORD build.keychain
security set-keychain-settings -lut 1200 build.keychain
security import $desktopKeyPath -k build.keychain -P $env:DESKTOP_KEY_PASSWORD -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import $devidAppCertPath -k build.keychain -P $env:DEVID_CERT_PASSWORD -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import $devidInstallerCertPath -k build.keychain -P $env:DEVID_CERT_PASSWORD -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import $appstoreAppCertPath -k build.keychain -P $env:APPSTORE_CERT_PASSWORD -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import $appstoreInstallerCertPath -k build.keychain -P $env:APPSTORE_CERT_PASSWORD -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security import $macdevCertPath -k build.keychain -P $env:MACDEV_CERT_PASSWORD -T /usr/bin/codesign -T /usr/bin/security -T /usr/bin/productbuild
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $env:KEYCHAIN_PASSWORD build.keychain

View File

@ -1,6 +0,0 @@
$homePath = Resolve-Path "~" | Select-Object -ExpandProperty Path;
$secretsPath = $homePath + "/secrets"
$rootPath = $env:GITHUB_WORKSPACE
$pprofile = "bitwarden_desktop_appstore.provisionprofile"
Copy-Item "$secretsPath/$pprofile" -destination "$rootPath/$pprofile"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

49
.github/workflows/crowndin-pull.yml vendored Normal file
View File

@ -0,0 +1,49 @@
---
name: Crowdin Sync
on:
workflow_dispatch:
inputs: {}
schedule:
- cron: "0 0 * * 5"
jobs:
crowdin-sync:
name: Autosync
runs-on: ubuntu-20.04
env:
_CROWDIN_PROJECT_ID: "299360"
steps:
- name: Checkout repo
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
- name: Login to Azure
uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a
with:
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
- name: Retrieve secrets
id: retrieve-secrets
uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403
with:
keyvault: "bitwarden-prod-kv"
secrets: "crowdin-api-token"
- name: Download translations
uses: crowdin/github-action@e39093fd75daae7859c68eded4b43d42ec78d8ea
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_API_TOKEN: ${{ steps.retrieve-secrets.outputs.crowdin-api-token }}
with:
config: crowdin.yml
crowdin_branch_name: master
upload_sources: false
upload_translations: false
download_translations: true
github_user_name: "github-actions"
github_user_email: "<>"
commit_message: "Autosync the updated translations"
localization_branch_name: crowdin-auto-sync
create_pull_request: true
pull_request_title: "Autosync Crowdin Translations"
pull_request_body: "Autosync the updated translations"

View File

@ -1,157 +0,0 @@
name: Deploy
on:
workflow_dispatch:
inputs:
release_tag_name_input:
description: "Release Tag Name <X.X.X>"
required: true
release:
types:
- published
jobs:
setup:
runs-on: ubuntu-latest
outputs:
package_version: ${{ steps.create_tags.outputs.package_version }}
tag_version: ${{ steps.create_tags.outputs.tag_version }}
steps:
- name: Checkout Repo
uses: actions/checkout@v2
- name: Create Deploy version vars
id: create_tags
run: |
if ! [[ "${{ github.event_name }}" -eq "release" ]]; then
case "${RELEASE_TAG_NAME_INPUT:0:1}" in
v)
echo "RELEASE_NAME=${RELEASE_TAG_NAME_INPUT:1}" >> $GITHUB_ENV
echo "RELEASE_TAG_NAME=$RELEASE_TAG_NAME_INPUT" >> $GITHUB_ENV
echo "::set-output name=package_version::${RELEASE_TAG_NAME_INPUT:1}"
echo "::set-output name=tag_version::$RELEASE_TAG_NAME_INPUT"
;;
[0-9])
echo "RELEASE_NAME=$RELEASE_TAG_NAME_INPUT" >> $GITHUB_ENV
echo "RELEASE_TAG_NAME=v$RELEASE_TAG_NAME_INPUT" >> $GITHUB_ENV
echo "::set-output name=package_version::$RELEASE_TAG_NAME_INPUT"
echo "::set-output name=tag_version::v$RELEASE_TAG_NAME_INPUT"
;;
*)
exit 1
;;
esac
else
TAG_VERSION=$(echo ${{ github.ref }} | cut -d "/" -f 3)
PKG_VERSION=${TAG_VERSION:1}
echo "::set-output name=package_version::$PKG_VERSION"
echo "::set-output name=tag_version::$TAG_VERSION"
fi
env:
RELEASE_TAG_NAME_INPUT: ${{ github.event.inputs.release_tag_name_input }}
snap:
name: Deploy Snap
runs-on: ubuntu-latest
needs: setup
env:
PKG_VERSION: ${{ needs.setup.outputs.package_version }}
TAG_VERSION: ${{ needs.setup.ouputs.tag_version }}
steps:
- name: Checkout Repo
uses: actions/checkout@v2
- name: Install Snap
uses: samuelmeuli/action-snapcraft@v1
with:
snapcraft_token: ${{ secrets.SNAP_TOKEN }}
- name: setup
run: mkdir dist
- name: get snap package
uses: Xotl/cool-github-releases@v1
with:
mode: download
tag_name: ${{ env.TAG_VERSION }}
assets: bitwarden_${{ env.PKG_VERSION }}_amd64.snap|./dist/bitwarden_${{ env.PKG_VERSION }}_amd64.snap
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: test
run: ls -alht dist
- name: Deploy to Snap Store
run: |
snapcraft upload dist/bitwarden_${{ env.PACKAGE_VERSION }}_amd64.snap --release stable
snapcraft logout
choco:
name: Deploy Choco
runs-on: windows-latest
needs: setup
env:
PKG_VERSION: ${{ needs.setup.outputs.package_version }}
TAG_VERSION: ${{ needs.setup.outputs.tag_version }}
steps:
- name: Checkout Repo
uses: actions/checkout@v2
- name: Get choco release asset
uses: dsaltares/fetch-gh-release-asset@0.0.5
with:
version: tags/${{ env.TAG_VERSION }}
file: bitwarden.${{ env.PKG_VERSION }}.nupkg
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Chocolatey
run: choco apikey --key $env:CHOCO_API_KEY --source https://push.chocolatey.org/
env:
CHOCO_API_KEY: ${{ secrets.CHOCO_API_KEY }}
- name: make dist dir
shell: pwsh
run: New-Item -ItemType directory -Path ./dist
- name: Get nupkg
uses: Xotl/cool-github-releases@v1
with:
mode: download
tag_name: ${{ env.TAG_VERSION }}
assets: bitwarden.${{ env.PKG_VERSION }}.nupkg|./dist/bitwarden.${{ env.PKG_VERSION }}.nupkg
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Push to Chocolatey
shell: pwsh
run: |
cd dist
choco push
macos:
runs-on: macos-latest
needs: setup
steps:
- name: Checkout repo
uses: actions/checkout@v2
- name: make target directory
run: mkdir -p dist/mas
- name: Get mac release asset
uses: Xotl/cool-github-releases@v1
with:
mode: download
tag_name: ${{ env.TAG_VERSION }}
assets: Bitwarden-${{ env.PACKAGE_VERSION }}.pkg|./dist/mas/Bitwarden-${{ env.PACKAGE_VERSION }}.pkg
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Deploy to App Store
run: npm run upload:mas
env:
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}

16
.github/workflows/enforce-labels.yml vendored Normal file
View File

@ -0,0 +1,16 @@
---
name: Enforce PR labels
on:
pull_request:
types: [labeled, unlabeled, opened, edited, synchronize]
jobs:
enforce-label:
name: EnforceLabel
runs-on: ubuntu-20.04
steps:
- name: Enforce Label
uses: yogevbd/enforce-label-action@8d1e1709b1011e6d90400a0e6cf7c0b77aa5efeb
with:
BANNED_LABELS: "hold"
BANNED_LABELS_DESCRIPTION: "PRs on hold cannot be merged"

View File

@ -1,371 +1,213 @@
---
name: Release
on:
workflow_dispatch:
inputs:
release_tag_name_input:
description: 'Release Tag Name <X.X.X>'
release_type:
description: 'Release Options'
required: true
browser_extension_ref:
description: 'Browser Extension ref (defaults to `master`):'
default: master
default: 'Initial Release'
type: choice
options:
- Initial Release
- Redeploy
- Dry Run
jobs:
setup:
runs-on: ubuntu-latest
name: Setup
runs-on: ubuntu-20.04
outputs:
release_upload_url: ${{ steps.create_release.outputs.upload_url }}
package_version: ${{ steps.retrieve-version.outputs.package_version }}
branch-name: ${{ steps.branch.outputs.branch-name }}
steps:
- name: Checkout repo
uses: actions/checkout@v2
- name: Create Release Vars
id: create_tags
- name: Branch check
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
run: |
case "${RELEASE_TAG_NAME_INPUT:0:1}" in
v)
echo "RELEASE_NAME=${RELEASE_TAG_NAME_INPUT:1}" >> $GITHUB_ENV
echo "RELEASE_TAG_NAME=$RELEASE_TAG_NAME_INPUT" >> $GITHUB_ENV
;;
[0-9])
echo "RELEASE_NAME=$RELEASE_TAG_NAME_INPUT" >> $GITHUB_ENV
echo "RELEASE_TAG_NAME=v$RELEASE_TAG_NAME_INPUT" >> $GITHUB_ENV
;;
*)
exit 1
;;
esac
env:
RELEASE_TAG_NAME_INPUT: ${{ github.event.inputs.release_tag_name_input }}
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc" ]]; then
echo "==================================="
echo "[!] Can only release from the 'rc' or 'hotfix-rc' branches"
echo "==================================="
exit 1
fi
- name: Create Draft Release
id: create_release
uses: actions/create-release@v1
- name: Checkout repo
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
- name: Get Package Version
id: retrieve-version
run: |
PKG_VERSION=$(jq -r .version src/package.json)
echo "::set-output name=package_version::$PKG_VERSION"
- name: Check to make sure Desktop release version has been bumped
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
latest_ver=$(hub release -L 1 -f '%T')
latest_ver=${latest_ver:1}
echo "Latest version: $latest_ver"
ver=${{ steps.retrieve-version.outputs.package_version }}
echo "Version: $ver"
if [ "$latest_ver" = "$ver" ] && \
[ "${{ github.event.inputs.release_type }}" == "Initial Release" ]; then
echo "Version has not been bumped!"
exit 1
fi
- name: Get branch name
id: branch
run: |
BRANCH_NAME=$(basename ${{ github.ref }})
echo "::set-output name=branch-name::$BRANCH_NAME"
- name: Login to Azure
uses: Azure/login@ec3c14589bd3e9312b3cc8c41e6860e258df9010
with:
tag_name: ${{ env.RELEASE_TAG_NAME }}
release_name: ${{ env.RELEASE_NAME }}
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
- name: Retrieve secrets
id: retrieve-secrets
uses: Azure/get-keyvault-secrets@b5c723b9ac7870c022b8c35befe620b7009b336f
with:
keyvault: "bitwarden-prod-kv"
secrets: "aws-electron-access-id, aws-electron-access-key"
- name: Download all artifacts
uses: bitwarden/gh-actions/download-artifacts@c1fa8e09871a860862d6bbe36184b06d2c7e35a8
with:
workflow: build.yml
workflow_conclusion: success
branch: ${{ steps.branch.outputs.branch-name }}
path: ./artifacts
- name: Rename .pkg to .pkg.archive
env:
PKG_VERSION: ${{ steps.retrieve-version.outputs.package_version }}
working-directory: ./artifacts
run: mv Bitwarden-${{ env.PKG_VERSION }}-universal.pkg Bitwarden-${{ env.PKG_VERSION }}-universal.pkg.archive
- name: Publish artifacts to S3
env:
AWS_ACCESS_KEY_ID: ${{ steps.retrieve-secrets.outputs.aws-electron-access-id }}
AWS_SECRET_ACCESS_KEY: ${{ steps.retrieve-secrets.outputs.aws-electron-access-key }}
AWS_DEFAULT_REGION: 'us-west-2'
run: |
aws s3 cp ./artifacts s3://public-s3-electron-artifacts/desktop/ \
--acl "public-read" \
--recursive \
--quiet
- name: Create release
uses: ncipollo/release-action@95215a3cb6e6a1908b3c44e00b4fdb15548b1e09 # v2.8.5
env:
PKG_VERSION: ${{ steps.retrieve-version.outputs.package_version }}
with:
artifacts: "artifacts/Bitwarden-${{ env.PKG_VERSION }}-amd64.deb,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-x86_64.rpm,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-x64.freebsd,
artifacts/bitwarden_${{ env.PKG_VERSION }}_amd64.snap,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-x86_64.AppImage,
artifacts/Bitwarden-Portable-${{ env.PKG_VERSION }}.exe,
artifacts/Bitwarden-Installer-${{ env.PKG_VERSION }}.exe,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-ia32-store.appx,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-ia32.appx,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-ia32.nsis.7z,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-x64-store.appx,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-x64.appx,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-x64.nsis.7z,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-arm64-store.appx,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-arm64.appx,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-arm64.nsis.7z,
artifacts/bitwarden.${{ env.PKG_VERSION }}.nupkg,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-universal-mac.zip,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-universal.dmg,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-universal.dmg.blockmap,
artifacts/Bitwarden-${{ env.PKG_VERSION }}-universal.pkg.archive"
commit: ${{ github.sha }}
tag: v${{ env.PKG_VERSION }}
name: Version ${{ env.PKG_VERSION }}
body: "<insert release notes here>"
token: ${{ secrets.GITHUB_TOKEN }}
draft: true
prerelease: false
linux:
runs-on: ubuntu-latest
snap:
name: Deploy Snap
runs-on: ubuntu-20.04
needs: setup
env:
_PKG_VERSION: ${{ needs.setup.outputs.package_version }}
steps:
- name: Set up Node
uses: actions/setup-node@v1
- name: Checkout Repo
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
- name: Login to Azure
uses: Azure/login@77f1b2e3fb80c0e8645114159d17008b8a2e475a
with:
node-version: '10.x'
creds: ${{ secrets.AZURE_PROD_KV_CREDENTIALS }}
- name: Set Node options
run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV
- name: Retrieve secrets
id: retrieve-secrets
uses: Azure/get-keyvault-secrets@80ccd3fafe5662407cc2e55f202ee34bfff8c403
with:
keyvault: "bitwarden-prod-kv"
secrets: "snapcraft-store-token"
- name: Set up environment
- name: Install Snap
uses: samuelmeuli/action-snapcraft@10d7d0a84d9d86098b19f872257df314b0bd8e2d # v1.2.0
with:
snapcraft_token: ${{ steps.retrieve-secrets.outputs.snapcraft-store-token }}
- name: Setup
run: mkdir dist
- name: Download Snap artifact
uses: bitwarden/gh-actions/download-artifacts@c1fa8e09871a860862d6bbe36184b06d2c7e35a8
with:
workflow: build.yml
workflow_conclusion: success
branch: ${{ needs.setup.outputs.branch-name }}
artifacts: bitwarden_${{ env._PKG_VERSION }}_amd64.snap
path: ./dist
- name: Deploy to Snap Store
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
run: |
sudo apt-get update
sudo apt-get -y install pkg-config libxss-dev libsecret-1-dev rpm
snapcraft upload dist/bitwarden_${{ env._PKG_VERSION }}_amd64.snap --release stable
snapcraft logout
- name: Print environment
run: |
node --version
npm --version
- name: Checkout repo
uses: actions/checkout@v2
- name: Load package version
run: ./.github/scripts/load-version.ps1
shell: pwsh
- name: Install Node dependencies
run: npm install
- name: Run linter
run: npm run lint
- name: Build & Publish
run: npm run publish:lin
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
windows-signed:
runs-on: windows-latest
choco:
name: Deploy Choco
runs-on: windows-2019
needs: setup
env:
_PKG_VERSION: ${{ needs.setup.outputs.package_version }}
steps:
- name: Set up dotnet
uses: actions/setup-dotnet@v1
with:
dotnet-version: "3.1.x"
- name: Checkout Repo
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f # v2.3.4
- name: Set up Node
uses: actions/setup-node@v1
with:
node-version: '10.x'
- 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: Install AST
shell: pwsh
run: |
cd $HOME
git clone https://github.com/vcsjones/AzureSignTool.git
cd AzureSignTool
$latest_head = $(git rev-parse HEAD)[0..9] -join ""
$latest_version = "0.0.0-g$latest_head"
Write-Host "--------"
Write-Host "git commit - $(git rev-parse HEAD)"
Write-Host "latest_head - $latest_head"
Write-Host "PACKAGE VERSION TO BUILD - $latest_version"
Write-Host "--------"
dotnet restore
dotnet pack --output ./nupkg
dotnet tool install --global --ignore-failed-sources --add-source ./nupkg --version $latest_version azuresigntool
- name: Set up environment
shell: pwsh
run: |
choco install checksum --no-progress
choco apikey --key $env:CHOCO_API_KEY --source https://push.chocolatey.org/
- name: Setup Chocolatey
run: choco apikey --key $env:CHOCO_API_KEY --source https://push.chocolatey.org/
env:
CHOCO_API_KEY: ${{ secrets.CHOCO_API_KEY }}
- name: Print environment
run: |
node --version
npm --version
choco --version
- name: Checkout repo
uses: actions/checkout@v2
- name: Load package version
run: ./.github/scripts/load-version.ps1
- name: Make dist dir
shell: pwsh
run: New-Item -ItemType directory -Path ./dist
- name: Install Node dependencies
run: npm install
- name: Download choco artifact
uses: bitwarden/gh-actions/download-artifacts@c1fa8e09871a860862d6bbe36184b06d2c7e35a8
with:
workflow: build.yml
workflow_conclusion: success
branch: ${{ needs.setup.outputs.branch-name }}
artifacts: bitwarden.${{ env._PKG_VERSION }}.nupkg
path: ./dist
- name: Run linter
run: npm run lint
- name: Build, Sign & Release
run: npm run publish:win
env:
ELECTRON_BUILDER_SIGN: 1
SIGNING_VAULT_URL: ${{ secrets.SIGNING_VAULT_URL }}
SIGNING_CLIENT_ID: ${{ secrets.SIGNING_CLIENT_ID }}
SIGNING_TENANT_ID: ${{ secrets.SIGNING_TENANT_ID }}
SIGNING_CLIENT_SECRET: ${{ secrets.SIGNING_CLIENT_SECRET }}
SIGNING_CERT_NAME: ${{ secrets.SIGNING_CERT_NAME }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Package Chocolatey
- name: Push to Chocolatey
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
shell: pwsh
run: |
Copy-Item -Path ./stores/chocolatey -Destination ./dist/chocolatey -Recurse
Copy-Item -Path ./dist/nsis-web/Bitwarden-Installer-${{ env.PACKAGE_VERSION }}.exe -Destination ./dist/chocolatey
$checksum = checksum -t sha256 ./dist/chocolatey/Bitwarden-Installer-${{ env.PACKAGE_VERSION }}.exe
$chocoInstall = "./dist/chocolatey/tools/chocolateyinstall.ps1"
(Get-Content $chocoInstall).replace('__version__', "$env:PACKAGE_VERSION").replace('__checksum__', $checksum) | Set-Content $chocoInstall
ls -alht dist/chocolatey
choco pack ./dist/chocolatey/bitwarden.nuspec --version "$env:PACKAGE_VERSION" --out ./dist/chocolatey
cd ./dist/chocolatey
ls -alht dist/chocolatey
- name: Upload Chocolatey nupkg release asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.setup.outputs.release_upload_url }}
asset_name: bitwarden.${{ env.PACKAGE_VERSION }}.nupkg
asset_path: ./dist/chocolatey/bitwarden.${{ env.PACKAGE_VERSION }}.nupkg
asset_content_type: application
windows-store:
runs-on: windows-latest
needs: setup
steps:
- name: Set up Node
uses: actions/setup-node@v1
with:
node-version: '10.x'
- 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: Set up environment
shell: pwsh
run: |
choco install checksum --no-progress
- name: Print environment
run: |
node --version
npm --version
choco --version
- name: Checkout repo
uses: actions/checkout@v2
- name: Load package version
run: ./.github/scripts/load-version.ps1
shell: pwsh
- name: Install Node dependencies
run: npm install
- name: Run linter
run: npm run lint
- name: Build, Sign & Release
run: npm run dist:win:ci
- name: Upload unsigned ia32 Windows Store release asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.setup.outputs.release_upload_url }}
asset_name: Bitwarden-${{ env.PACKAGE_VERSION }}-ia32-store.appx
asset_path: ./dist/Bitwarden-${{ env.PACKAGE_VERSION }}-ia32.appx
asset_content_type: application
- name: Upload unsigned x64 Windows Store release asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.setup.outputs.release_upload_url }}
asset_name: Bitwarden-${{ env.PACKAGE_VERSION }}-x64-store.appx
asset_path: ./dist/Bitwarden-${{ env.PACKAGE_VERSION }}-x64.appx
asset_content_type: application
- name: Upload unsigned ARM64 Windows Store release asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.setup.outputs.release_upload_url }}
asset_name: Bitwarden-${{ env.PACKAGE_VERSION }}-arm64-store.appx
asset_path: ./dist/Bitwarden-${{ env.PACKAGE_VERSION }}-arm64.appx
asset_content_type: application
macos:
runs-on: macos-latest
needs: setup
steps:
- name: Set up Node
uses: actions/setup-node@v1
with:
node-version: '10.x'
- name: Set Node options
run: echo "NODE_OPTIONS=--max_old_space_size=4096" >> $GITHUB_ENV
- name: Print environment
run: |
node --version
npm --version
Write-Output "GitHub ref: $env:GITHUB_REF"
Write-Output "GitHub event: $env:GITHUB_EVENT"
shell: pwsh
env:
GITHUB_REF: ${{ github.ref }}
GITHUB_EVENT: ${{ github.event_name }}
- name: Checkout repo
uses: actions/checkout@v2
- name: Decrypt secrets
run: ./.github/scripts/macos/decrypt-secrets.ps1
shell: pwsh
env:
DECRYPT_FILE_PASSWORD: ${{ secrets.DECRYPT_FILE_PASSWORD }}
- name: Set up keychain
run: ./.github/scripts/macos/setup-keychain.ps1
shell: pwsh
env:
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
DESKTOP_KEY_PASSWORD: ${{ secrets.DESKTOP_KEY_PASSWORD }}
DEVID_CERT_PASSWORD: ${{ secrets.DEVID_CERT_PASSWORD }}
APPSTORE_CERT_PASSWORD: ${{ secrets.APPSTORE_CERT_PASSWORD }}
MACDEV_CERT_PASSWORD: ${{ secrets.MACDEV_CERT_PASSWORD }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
- name: Set up provisioning profiles
run: ./.github/scripts/macos/setup-profiles.ps1
shell: pwsh
- name: Increment version
run: ./.github/scripts/macos/increment-version.ps1
shell: pwsh
- name: Load package version
run: ./.github/scripts/load-version.ps1
shell: pwsh
- name: Install Node dependencies
run: npm install
- name: Run linter
run: npm run lint
- name: Create Safari directory
shell: pwsh
run: New-Item ./dist-safari -ItemType Directory -ea 0
- name: Checkout browser extension
uses: actions/checkout@v2
with:
repository: 'bitwarden/browser'
ref: ${{ github.event.inputs.browser_extension_ref }}
path: 'dist-safari/browser'
- name: Build Safari extension
shell: pwsh
run: ./scripts/safari-build.ps1 -skipcheckout -skipoutcopy
- name: Load Safari extension for .dmg
shell: pwsh
run: ./scripts/safari-build.ps1 -copyonly
- name: Build application (dist)
run: npm run publish:mac
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
- name: Load Safari extension for App Store
shell: pwsh
run: ./scripts/safari-build.ps1 -mas -copyonly
- name: Build application for App Store
run: npm run dist:mac:mas
env:
APPLE_ID_USERNAME: ${{ secrets.APPLE_ID_USERNAME }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
- name: Upload Apple Store release asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.setup.outputs.release_upload_url }}
asset_name: Bitwarden-${{ env.PACKAGE_VERSION }}.pkg
asset_path: ./dist/mas/Bitwarden-${{ env.PACKAGE_VERSION }}.pkg
asset_content_type: application
cd dist
choco push

65
.github/workflows/version-bump.yml vendored Normal file
View File

@ -0,0 +1,65 @@
---
name: Version Bump
on:
workflow_dispatch:
inputs:
version_number:
description: "New Version"
required: true
jobs:
bump_version:
name: "Create version_bump_${{ github.event.inputs.version_number }} branch"
runs-on: ubuntu-20.04
steps:
- name: Checkout Branch
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
- name: Create Version Branch
run: |
git switch -c version_bump_${{ github.event.inputs.version_number }}
git push -u origin version_bump_${{ github.event.inputs.version_number }}
- name: Checkout Version Branch
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579
with:
ref: version_bump_${{ github.event.inputs.version_number }}
- name: Bump Version - Package
uses: bitwarden/gh-actions/version-bump@03ad9a873c39cdc95dd8d77dbbda67f84db43945
with:
version: ${{ github.event.inputs.version_number }}
file_path: "./src/package.json"
- name: Commit files
run: |
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git commit -m "Bumped version to ${{ github.event.inputs.version_number }}" -a
- name: Push changes
run: git push -u origin version_bump_${{ github.event.inputs.version_number }}
- name: Create Version PR
env:
PR_BRANCH: "version_bump_${{ github.event.inputs.version_number }}"
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
BASE_BRANCH: master
TITLE: "Bump version to ${{ github.event.inputs.version_number }}"
run: |
gh pr create --title "$TITLE" \
--base "$BASE" \
--head "$PR_BRANCH" \
--label "version update" \
--label "automated pr" \
--body "
## Type of change
- [ ] Bug fix
- [ ] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [X] Other
## Objective
Automated version bump to ${{ github.event.inputs.version_number }}"

11
.github/workflows/workflow-linter.yml vendored Normal file
View File

@ -0,0 +1,11 @@
---
name: Workflow Linter
on:
pull_request:
paths:
- .github/workflows/**
jobs:
call-workflow:
uses: bitwarden/gh-actions/.github/workflows/workflow-linter.yml@master

1
.husky/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
_

4
.husky/pre-commit Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged

2
.nvmrc
View File

@ -1 +1 @@
10.13.0
v16.13.1

14
.prettierignore Normal file
View File

@ -0,0 +1,14 @@
# Build directories
build
dist
dist-safari
desktop_native
jslib
# External libraries / auto synced locales
src/locales
src/scripts/duo.js
# Github Workflows
.github/workflows

3
.prettierrc.json Normal file
View File

@ -0,0 +1,3 @@
{
"printWidth": 100
}

4
.vscode/launch.json vendored
View File

@ -10,9 +10,7 @@
"windows": {
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd"
},
"args": [
"."
]
"args": ["."]
}
]
}

View File

@ -6,17 +6,12 @@ Please visit our [Community Forums](https://community.bitwarden.com/) for genera
Here is how you can get involved:
* **Request a new feature:** Go to the [Feature Requests category](https://community.bitwarden.com/c/feature-requests/) of the Community Forums. Please search existing feature requests before making a new one
* **Write code for a new feature:** Make a new post in the [Github Contributions category](https://community.bitwarden.com/c/github-contributions/) of the Community Forums. Include a description of your proposed contribution, screeshots, and links to any relevant feature requests. This helps get feedback from the community and Bitwarden team members before you start writing code
* **Report a bug or submit a bugfix:** Use Github issues and pull requests
* **Write documentation:** Submit a pull request to the [Bitwarden help repository](https://github.com/bitwarden/help)
* **Help other users:** Go to the [User-to-User Support category](https://community.bitwarden.com/c/support/) on the Community Forums
* **Translate:** See the localization (l10n) section below
- **Request a new feature:** Go to the [Feature Requests category](https://community.bitwarden.com/c/feature-requests/) of the Community Forums. Please search existing feature requests before making a new one
- **Write code for a new feature:** Make a new post in the [Github Contributions category](https://community.bitwarden.com/c/github-contributions/) of the Community Forums. Include a description of your proposed contribution, screeshots, and links to any relevant feature requests. This helps get feedback from the community and Bitwarden team members before you start writing code
- **Report a bug or submit a bugfix:** Use Github issues and pull requests
- **Write documentation:** Submit a pull request to the [Bitwarden help repository](https://github.com/bitwarden/help)
- **Help other users:** Go to the [Ask the Bitwarden Community category](https://community.bitwarden.com/c/support/) on the Community Forums
- **Translate:** See the localization (l10n) section below
## Contributor Agreement
@ -24,9 +19,9 @@ Please sign the [Contributor Agreement](https://cla-assistant.io/bitwarden/deskt
## Pull Request Guidelines
* use `npm run lint` and fix any linting suggestions before submitting a pull request
* commit any pull requests against the `master` branch
* include a link to your Community Forums post
- use `npm run lint` and fix any linting suggestions before submitting a pull request
- commit any pull requests against the `master` branch
- include a link to your Community Forums post
# Localization (l10n)
@ -36,6 +31,6 @@ We use a translation tool called [Crowdin](https://crowdin.com) to help manage o
If you are interested in helping translate the Bitwarden desktop app into another language (or make a translation correction), please register an account at Crowdin and join our project here: https://crowdin.com/project/bitwarden-desktop
If the language that you are interested in translating is not already listed, create a new account on Crowdin, join the project, and contact the project owner (https://crowdin.com/profile/kspearrin).
If the language that you are interested in translating is not already listed, create a new account on Crowdin, join the project, and contact the project owner (https://crowdin.com/profile/dwbit).
You can read Crowdin's getting started guide for translators here: https://support.crowdin.com/crowdin-intro/

View File

@ -1,52 +0,0 @@
<!--
Please do not submit feature requests. The [Community Forums][1] has a
section for submitting, voting for, and discussing product feature requests.
[1]: https://community.bitwarden.com
-->
## Describe the Bug
<!-- Comment:
A clear and concise description of what the bug is.
-->
## Steps To Reproduce
<!-- Comment:
How can we reproduce the behavior:
-->
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. Click on '...'
## Expected Result
<!-- Comment:
A clear and concise description of what you expected to happen.
-->
## Actual Result
<!-- Comment:
A clear and concise description of what is happening.
-->
## Screenshots or Videos
<!-- Comment:
If applicable, add screenshots and/or a short video to help explain your problem.
-->
## Environment
- Operating system: [e.g. Windows 10, Mac OS Catalina]
- Installation method: [e.g. Downloaded from Bitwarden.com, Mac App Store / Microsoft Store, Homebrew, Snap]
- Build Version (go to "Settings" → "About"): [e.g. 1.16.10]
## Additional Context
<!-- Comment:
Add any other context about the problem here.
-->

View File

@ -2,43 +2,74 @@
[![Crowdin](https://d322cqt584bo4o.cloudfront.net/bitwarden-desktop/localized.svg)](https://crowdin.com/project/bitwarden-desktop)
[![Join the chat at https://gitter.im/bitwarden/Lobby](https://badges.gitter.im/bitwarden/Lobby.svg)](https://gitter.im/bitwarden/Lobby)
> **Archived**
>
> This repository is archived, please go to https://github.com/bitwarden/clients for future development.
# Bitwarden Desktop Application
[![Platforms](https://imgur.com/SLv9paA.png "Windows, macOS, and Linux")](https://bitwarden.com/download/)
The Bitwarden desktop app is written using Electron and Angular. The application installs on Windows, macOS, and Linux distributions.
![Desktop Vault](https://raw.githubusercontent.com/bitwarden/brand/master/screenshots/desktop-macos-vault.png "My Vault")
![Desktop Vault](https://github.com/bitwarden/brand/blob/f09f2fa594c8a020c315296074f18ce0a7b3f171/screenshots/desktop-macos-vault.png "My Vault")
# Build/Run
**Requirements**
## Requirements
- [Node.js](https://nodejs.org/)
- 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. You will also need to install the *Microsoft Build Tools 2015* and *Windows 10 SDK 17134* as additional dependencies in the Visual Studio installer.
- [Node.js](https://nodejs.org) v16.13.1 (LTS) or greater
- NPM v8
- Windows:
- To compile the native node modules used in the app you will need the _Visual C++ toolset_, available through the standard Visual Studio installer. You will also need to install the _Microsoft Build Tools 2015_ and _Windows 10 SDK 17134_ as additional dependencies in the Visual Studio installer.
- Linux:
- The following packages `build-essential libsecret-1-dev libglib2.0-dev`
**Run the app**
## Run the app
```bash
npm install
npm ci
npm run electron
```
**Debug Native Messaging**
### Debug Native Messaging
Native Messaging (communication with the browser extension) works by having the browser start a lightweight proxy application baked into our desktop binary. To setup an environment which allows
for easy debugging you will need to build the application for distribution, i.e. `npm run dist:<platform>`, start the dist version and enable desktop integration. This will write some manifests
to disk, Consult the [native manifests](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_manifests#Manifest_location) documentation for more details of the manifest
format, and the exact locations for the different platforms. *Note* that disabling the desktop integration will delete the manifests, and the files will need to be updated again.
format, and the exact locations for the different platforms. _Note_ that disabling the desktop integration will delete the manifests, and the files will need to be updated again.
The generated manifests are pre-configured with the production ID for the browser extensions. In order to use them with the development builds, the browser extension ID of the development build
needs to be added to the `allowed_extensions` section of the manifest. These IDs are generated by the browser, and can be found in the extension settings within the browser.
needs to be added to the `allowed_extensions` section of the manifest. These IDs are generated by the browser, and can be found in the extension settings within the browser.
It will then be possible to run the desktop application as usual using `npm run electron` and communicate with the browser.
# We're Hiring!
Interested in contributing in a big way? Consider joining our team! We're hiring for many positions. Please take a look at our [Careers page](https://bitwarden.com/careers/) to see what opportunities are currently open as well as what it's like to work at Bitwarden.
# Contribute
Code contributions are welcome! Please commit any pull requests against the `master` branch. Learn more about how to contribute by reading the [`CONTRIBUTING.md`](CONTRIBUTING.md) file.
Security audits and feedback are welcome. Please open an issue or email us privately if the report is sensitive in nature. You can read our security policy in the [`SECURITY.md`](SECURITY.md) file.
## Prettier
We recently migrated to using Prettier as code formatter. All previous branches will need to updated to avoid large merge conflicts using the following steps:
1. Check out your local Branch
2. Run `git merge b4df834b16d4f5d4162a926a5a308bdb3ebc718b`
3. Resolve any merge conflicts, commit.
4. Run `npm run prettier`
5. Commit
6. Run `git merge -Xours 521feae535d83166e620c3c28dfc3e7b0314a00e`
7. Push
### Git blame
We also recommend that you configure git to ignore the prettier revision using:
```bash
git config blame.ignoreRevsFile .git-blame-ignore-revs
```

View File

@ -1,39 +1,11 @@
Bitwarden believes that working with security researchers across the globe is crucial to keeping our
users safe. If you believe you've found a security issue in our product or service, we encourage you to
notify us. We welcome working with you to resolve the issue promptly. Thanks in advance!
Bitwarden believes that working with security researchers across the globe is crucial to keeping our users safe. If you believe you've found a security issue in our product or service, we encourage you to please submit a report through our [HackerOne Program](https://hackerone.com/bitwarden/). We welcome working with you to resolve the issue promptly. Thanks in advance!
# Disclosure Policy
- Let us know as soon as possible upon discovery of a potential security issue, and we'll make every
effort to quickly resolve the issue.
- Provide us a reasonable amount of time to resolve the issue before any disclosure to the public or a
third-party. We may publicly disclose the issue before resolving it, if appropriate.
- Make a good faith effort to avoid privacy violations, destruction of data, and interruption or
degradation of our service. Only interact with accounts you own or with explicit permission of the
account holder.
- If you would like to encrypt your report, please use the PGP key with long ID
`0xDE6887086F892325FEC04CC0D847525B6931381F` (available in the public keyserver pool).
# In-scope
- Security issues in any current release of Bitwarden. This includes the web vault, browser extension,
and mobile apps (iOS and Android). Product downloads are available at https://bitwarden.com. Source
code is available at https://github.com/bitwarden.
# Exclusions
The following bug classes are out-of scope:
- Bugs that are already reported on any of Bitwarden's issue trackers (https://github.com/bitwarden),
or that we already know of. Note that some of our issue tracking is private.
- Issues in an upstream software dependency (ex: Xamarin, ASP.NET) which are already reported to the
upstream maintainer.
- Attacks requiring physical access to a user's device.
- Self-XSS
- Issues related to software or protocols not under Bitwarden's control
- Vulnerabilities in outdated versions of Bitwarden
- Missing security best practices that do not directly lead to a vulnerability
- Issues that do not have any impact on the general public
- Let us know as soon as possible upon discovery of a potential security issue, and we'll make every effort to quickly resolve the issue.
- Provide us a reasonable amount of time to resolve the issue before any disclosure to the public or a third-party. We may publicly disclose the issue before resolving it, if appropriate.
- Make a good faith effort to avoid privacy violations, destruction of data, and interruption or degradation of our service. Only interact with accounts you own or with explicit permission of the account holder.
- If you would like to encrypt your report, please use the PGP key with long ID `0xDE6887086F892325FEC04CC0D847525B6931381F` (available in the public keyserver pool).
While researching, we'd like to ask you to refrain from:
@ -42,4 +14,8 @@ While researching, we'd like to ask you to refrain from:
- Social engineering (including phishing) of Bitwarden staff or contractors
- Any physical attempts against Bitwarden property or data centers
# We want to help you!
If you have something that you feel is close to exploitation, or if you'd like some information regarding the internal API, or generally have any questions regarding the app that would help in your efforts, please email us at https://bitwarden.com/contact and ask for that information. As stated above, Bitwarden wants to help you find issues, and is more than willing to help.
Thank you for helping keep Bitwarden and our users safe!

View File

@ -1,5 +1,9 @@
project_id_env: _CROWDIN_PROJECT_ID
api_token_env: CROWDIN_API_TOKEN
preserve_hierarchy: true
files:
- source: /src/locales/en/messages.json
dest: /src/locales/en/%original_file_name%
translation: /src/locales/%two_letters_code%/%original_file_name%
update_option: update_as_unapproved
languages_mapping:

6
desktop_native/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
target
index.node
**/node_modules
**/.DS_Store
npm-debug.log*
*.node

946
desktop_native/Cargo.lock generated Normal file
View File

@ -0,0 +1,946 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "anyhow"
version = "1.0.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "159bb86af3a200e19a068f4224eae4c8bb2d0fa054c7e5d1cacd5cef95e684cd"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bytes"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]]
name = "cc"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cfg-expr"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e068cb2806bbc15b439846dc16c5f89f8599f2c3e4d73d4449d38f9b2f0b6c5"
dependencies = [
"smallvec",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "codespan-reporting"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
dependencies = [
"termcolor",
"unicode-width",
]
[[package]]
name = "convert_case"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8"
[[package]]
name = "core-foundation"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]]
name = "ctor"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "cxx"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce2295fe8865279f404147e9b2328e5af0ad11a2c016e58c13acfd48a07d8a55"
dependencies = [
"cc",
"cxxbridge-flags",
"cxxbridge-macro",
"link-cplusplus",
]
[[package]]
name = "cxx-build"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0aaaa055d4908326f1b4524b23ae53758019b806c0c4f382ea240982e9766b26"
dependencies = [
"cc",
"codespan-reporting",
"once_cell",
"proc-macro2",
"quote",
"scratch",
"syn",
]
[[package]]
name = "cxxbridge-flags"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a670224c6686471df12560a0b97a08145082e70bd38e2b0b5383b79e46c3da7"
[[package]]
name = "cxxbridge-macro"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b700096ca0dece28d9535fdb17ab784a8ae155d7f29d39c273643e6292c9620"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "desktop_native"
version = "0.0.0"
dependencies = [
"anyhow",
"core-foundation",
"gio",
"keytar",
"libsecret",
"napi",
"napi-build",
"napi-derive",
"scopeguard",
"security-framework",
"security-framework-sys",
"tokio",
"widestring",
"windows 0.32.0",
]
[[package]]
name = "futures-channel"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010"
dependencies = [
"futures-core",
]
[[package]]
name = "futures-core"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3"
[[package]]
name = "futures-executor"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
[[package]]
name = "futures-task"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
[[package]]
name = "futures-util"
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a"
dependencies = [
"futures-core",
"futures-task",
"pin-project-lite",
"pin-utils",
"slab",
]
[[package]]
name = "gio"
version = "0.15.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96efd8a1c00d890f6b45671916e165b5e43ccec61957d443aff6d7e44f62d348"
dependencies = [
"bitflags",
"futures-channel",
"futures-core",
"futures-io",
"gio-sys",
"glib",
"libc",
"once_cell",
"thiserror",
]
[[package]]
name = "gio-sys"
version = "0.15.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d0fa5052773f5a56b8ae47dab09d040f5d9ce1311f4f99006e16e9a08269296"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
"winapi",
]
[[package]]
name = "glib"
version = "0.15.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa570813c504bdf7539a9400180c2dd4b789a819556fb86da7226d7d1b037b49"
dependencies = [
"bitflags",
"futures-channel",
"futures-core",
"futures-executor",
"futures-task",
"glib-macros",
"glib-sys",
"gobject-sys",
"libc",
"once_cell",
"smallvec",
"thiserror",
]
[[package]]
name = "glib-macros"
version = "0.15.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41bfd8d227dead0829ac142454e97531b93f576d0805d779c42bfd799c65c572"
dependencies = [
"anyhow",
"heck",
"proc-macro-crate",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "glib-sys"
version = "0.15.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4366377bd56697de8aaee24e673c575d2694d72e7756324ded2b0428829a7b8"
dependencies = [
"libc",
"system-deps",
]
[[package]]
name = "gobject-sys"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df6859463843c20cf3837e3a9069b6ab2051aeeadf4c899d33344f4aea83189a"
dependencies = [
"glib-sys",
"libc",
"system-deps",
]
[[package]]
name = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "keytar"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d361c55fba09829ac620b040f5425bf239b1030c3d6820a84acac8da867dca4d"
dependencies = [
"keytar-sys",
]
[[package]]
name = "keytar-sys"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe908c6896705a1cb516cd6a5d956c63f08d95ace81b93253a98cd93e1e6a65a"
dependencies = [
"cc",
"cxx",
"cxx-build",
"pkg-config",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
[[package]]
name = "libsecret"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4af5a2342942fa42d706a424e9f9914287fb8317132750fd73a241140ac38c1"
dependencies = [
"bitflags",
"gio",
"glib",
"libc",
"libsecret-sys",
"once_cell",
]
[[package]]
name = "libsecret-sys"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "287d2a0fcd95e4d7b0ac6fc9f802691a790d7e522138713b0cacebc4e63cab91"
dependencies = [
"gio-sys",
"glib-sys",
"gobject-sys",
"libc",
"pkg-config",
"system-deps",
]
[[package]]
name = "link-cplusplus"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8cae2cd7ba2f3f63938b9c724475dfb7b9861b545a90324476324ed21dbc8c8"
dependencies = [
"cc",
]
[[package]]
name = "lock_api"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b"
dependencies = [
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "memchr"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "mio"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba272f85fa0b41fc91872be579b3bbe0f56b792aa361a380eb669469f68dafb2"
dependencies = [
"libc",
"log",
"miow",
"ntapi",
"winapi",
]
[[package]]
name = "miow"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
dependencies = [
"winapi",
]
[[package]]
name = "napi"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17ec66e60f000c78dd7c6215b6fa260e0591e09805024332bc5b3f55acc12244"
dependencies = [
"ctor",
"lazy_static",
"napi-sys",
"tokio",
"windows 0.30.0",
]
[[package]]
name = "napi-build"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebd4419172727423cf30351406c54f6cc1b354a2cfb4f1dba3e6cd07f6d5522b"
[[package]]
name = "napi-derive"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74ac5287a5e94a8728fc82d16c5127acc5eb5b8ad6404ef5f82d6a4ce8d5bdd2"
dependencies = [
"convert_case",
"napi-derive-backend",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "napi-derive-backend"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "427f4f04525635cdf22005d1be62d6d671bcb5550d694a1efb480a315422b4af"
dependencies = [
"convert_case",
"once_cell",
"proc-macro2",
"quote",
"regex",
"syn",
]
[[package]]
name = "napi-sys"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a385494dac3c52cbcacb393bb3b42669e7db8ab240c7ad5115f549eb061f2cc"
[[package]]
name = "ntapi"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f"
dependencies = [
"winapi",
]
[[package]]
name = "num_cpus"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "once_cell"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
[[package]]
name = "parking_lot"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-sys",
]
[[package]]
name = "pin-project-lite"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "pkg-config"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
[[package]]
name = "proc-macro-crate"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a"
dependencies = [
"thiserror",
"toml",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "scratch"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96311ef4a16462c757bb6a39152c40f58f31cd2602a40fceb937e2bc34e6cbab"
[[package]]
name = "security-framework"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc"
dependencies = [
"bitflags",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "serde"
version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
[[package]]
name = "signal-hook-registry"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
dependencies = [
"libc",
]
[[package]]
name = "slab"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
[[package]]
name = "smallvec"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
[[package]]
name = "socket2"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "syn"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "system-deps"
version = "6.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1a45a1c4c9015217e12347f2a411b57ce2c4fc543913b14b6fe40483328e709"
dependencies = [
"cfg-expr",
"heck",
"pkg-config",
"toml",
"version-compare",
]
[[package]]
name = "termcolor"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
dependencies = [
"winapi-util",
]
[[package]]
name = "thiserror"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee"
dependencies = [
"bytes",
"libc",
"memchr",
"mio",
"num_cpus",
"once_cell",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"winapi",
]
[[package]]
name = "tokio-macros"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "toml"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
dependencies = [
"serde",
]
[[package]]
name = "unicode-width"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "version-compare"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe88247b92c1df6b6de80ddc290f3976dbdf2f5f5d3fd049a9fb598c6dd5ca73"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "widestring"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b749ebd2304aa012c5992d11a25d07b406bdbe5f79d371cb7a918ce501a19eb0"
dependencies = [
"windows_aarch64_msvc 0.30.0",
"windows_i686_gnu 0.30.0",
"windows_i686_msvc 0.30.0",
"windows_x86_64_gnu 0.30.0",
"windows_x86_64_msvc 0.30.0",
]
[[package]]
name = "windows"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbedf6db9096bc2364adce0ae0aa636dcd89f3c3f2cd67947062aaf0ca2a10ec"
dependencies = [
"windows_aarch64_msvc 0.32.0",
"windows_i686_gnu 0.32.0",
"windows_i686_msvc 0.32.0",
"windows_x86_64_gnu 0.32.0",
"windows_x86_64_msvc 0.32.0",
]
[[package]]
name = "windows-sys"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6"
dependencies = [
"windows_aarch64_msvc 0.32.0",
"windows_i686_gnu 0.32.0",
"windows_i686_msvc 0.32.0",
"windows_x86_64_gnu 0.32.0",
"windows_x86_64_msvc 0.32.0",
]
[[package]]
name = "windows_aarch64_msvc"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29277a4435d642f775f63c7d1faeb927adba532886ce0287bd985bffb16b6bca"
[[package]]
name = "windows_aarch64_msvc"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5"
[[package]]
name = "windows_i686_gnu"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1145e1989da93956c68d1864f32fb97c8f561a8f89a5125f6a2b7ea75524e4b8"
[[package]]
name = "windows_i686_gnu"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615"
[[package]]
name = "windows_i686_msvc"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4a09e3a0d4753b73019db171c1339cd4362c8c44baf1bcea336235e955954a6"
[[package]]
name = "windows_i686_msvc"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172"
[[package]]
name = "windows_x86_64_gnu"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ca64fcb0220d58db4c119e050e7af03c69e6f4f415ef69ec1773d9aab422d5a"
[[package]]
name = "windows_x86_64_gnu"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc"
[[package]]
name = "windows_x86_64_msvc"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08cabc9f0066848fef4bc6a1c1668e6efce38b661d2aeec75d18d8617eebb5f1"
[[package]]
name = "windows_x86_64_msvc"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316"

43
desktop_native/Cargo.toml Normal file
View File

@ -0,0 +1,43 @@
[package]
edition = "2021"
exclude = ["index.node"]
license = "GPL-3.0"
name = "desktop_native"
version = "0.0.0"
[lib]
crate-type = ["cdylib"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0"
napi = {version = "2", features = ["async"]}
napi-derive = "2"
scopeguard = "1.1.0"
tokio = {version = "1.17.0", features = ["full"]}
[build-dependencies]
napi-build = "1"
[target.'cfg(windows)'.dependencies]
widestring = "0.5.1"
windows = {version = "0.32.0", features = [
"alloc",
"Foundation",
"Storage_Streams",
"Win32_Foundation",
"Win32_Security_Credentials",
]}
[target.'cfg(windows)'.dev-dependencies]
keytar = "0.1.6"
[target.'cfg(target_os = "macos")'.dependencies]
core-foundation = "0.9.3"
security-framework = "2.6.1"
security-framework-sys = "2.6.1"
[target.'cfg(target_os = "linux")'.dependencies]
gio = "0.15.6"
libsecret = "0.1.4"

22
desktop_native/build.js Normal file
View File

@ -0,0 +1,22 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const child_process = require("child_process");
const process = require("process");
let targets = [];
switch (process.platform) {
case "win32":
targets = ["i686-pc-windows-msvc", "x86_64-pc-windows-msvc", "aarch64-pc-windows-msvc"];
break;
case "darwin":
targets = ["x86_64-apple-darwin", "aarch64-apple-darwin"];
break;
default:
targets = ['x86_64-unknown-linux-gnu'];
break;
}
targets.forEach(target => {
child_process.execSync(`npm run build -- --target ${target}`, {stdio: 'inherit'});
});

5
desktop_native/build.rs Normal file
View File

@ -0,0 +1,5 @@
extern crate napi_build;
fn main() {
napi_build::setup();
}

15
desktop_native/index.d.ts vendored Normal file
View File

@ -0,0 +1,15 @@
/* tslint:disable */
/* eslint-disable */
/* auto-generated by NAPI-RS */
export namespace passwords {
/** Fetch the stored password from the keychain. */
export function getPassword(service: string, account: string): Promise<string>
/** Fetch the stored password from the keychain that was stored with Keytar. */
export function getPasswordKeytar(service: string, account: string): Promise<string>
/** Save the password to the keychain. Adds an entry if none exists otherwise updates the existing entry. */
export function setPassword(service: string, account: string, password: string): Promise<void>
/** Delete the stored password from the keychain. */
export function deletePassword(service: string, account: string): Promise<void>
}

241
desktop_native/index.js Normal file
View File

@ -0,0 +1,241 @@
const { existsSync, readFileSync } = require('fs')
const { join } = require('path')
const { platform, arch } = process
let nativeBinding = null
let localFileExisted = false
let loadError = null
function isMusl() {
// For Node 10
if (!process.report || typeof process.report.getReport !== 'function') {
try {
return readFileSync('/usr/bin/ldd', 'utf8').includes('musl')
} catch (e) {
return true
}
} else {
const { glibcVersionRuntime } = process.report.getReport().header
return !glibcVersionRuntime
}
}
switch (platform) {
case 'android':
switch (arch) {
case 'arm64':
localFileExisted = existsSync(join(__dirname, 'desktop_native.android-arm64.node'))
try {
if (localFileExisted) {
nativeBinding = require('./desktop_native.android-arm64.node')
} else {
nativeBinding = require('@bitwarden/desktop_native-android-arm64')
}
} catch (e) {
loadError = e
}
break
case 'arm':
localFileExisted = existsSync(join(__dirname, 'desktop_native.android-arm-eabi.node'))
try {
if (localFileExisted) {
nativeBinding = require('./desktop_native.android-arm-eabi.node')
} else {
nativeBinding = require('@bitwarden/desktop_native-android-arm-eabi')
}
} catch (e) {
loadError = e
}
break
default:
throw new Error(`Unsupported architecture on Android ${arch}`)
}
break
case 'win32':
switch (arch) {
case 'x64':
localFileExisted = existsSync(
join(__dirname, 'desktop_native.win32-x64-msvc.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./desktop_native.win32-x64-msvc.node')
} else {
nativeBinding = require('@bitwarden/desktop_native-win32-x64-msvc')
}
} catch (e) {
loadError = e
}
break
case 'ia32':
localFileExisted = existsSync(
join(__dirname, 'desktop_native.win32-ia32-msvc.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./desktop_native.win32-ia32-msvc.node')
} else {
nativeBinding = require('@bitwarden/desktop_native-win32-ia32-msvc')
}
} catch (e) {
loadError = e
}
break
case 'arm64':
localFileExisted = existsSync(
join(__dirname, 'desktop_native.win32-arm64-msvc.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./desktop_native.win32-arm64-msvc.node')
} else {
nativeBinding = require('@bitwarden/desktop_native-win32-arm64-msvc')
}
} catch (e) {
loadError = e
}
break
default:
throw new Error(`Unsupported architecture on Windows: ${arch}`)
}
break
case 'darwin':
switch (arch) {
case 'x64':
localFileExisted = existsSync(join(__dirname, 'desktop_native.darwin-x64.node'))
try {
if (localFileExisted) {
nativeBinding = require('./desktop_native.darwin-x64.node')
} else {
nativeBinding = require('@bitwarden/desktop_native-darwin-x64')
}
} catch (e) {
loadError = e
}
break
case 'arm64':
localFileExisted = existsSync(
join(__dirname, 'desktop_native.darwin-arm64.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./desktop_native.darwin-arm64.node')
} else {
nativeBinding = require('@bitwarden/desktop_native-darwin-arm64')
}
} catch (e) {
loadError = e
}
break
default:
throw new Error(`Unsupported architecture on macOS: ${arch}`)
}
break
case 'freebsd':
if (arch !== 'x64') {
throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
}
localFileExisted = existsSync(join(__dirname, 'desktop_native.freebsd-x64.node'))
try {
if (localFileExisted) {
nativeBinding = require('./desktop_native.freebsd-x64.node')
} else {
nativeBinding = require('@bitwarden/desktop_native-freebsd-x64')
}
} catch (e) {
loadError = e
}
break
case 'linux':
switch (arch) {
case 'x64':
if (isMusl()) {
localFileExisted = existsSync(
join(__dirname, 'desktop_native.linux-x64-musl.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./desktop_native.linux-x64-musl.node')
} else {
nativeBinding = require('@bitwarden/desktop_native-linux-x64-musl')
}
} catch (e) {
loadError = e
}
} else {
localFileExisted = existsSync(
join(__dirname, 'desktop_native.linux-x64-gnu.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./desktop_native.linux-x64-gnu.node')
} else {
nativeBinding = require('@bitwarden/desktop_native-linux-x64-gnu')
}
} catch (e) {
loadError = e
}
}
break
case 'arm64':
if (isMusl()) {
localFileExisted = existsSync(
join(__dirname, 'desktop_native.linux-arm64-musl.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./desktop_native.linux-arm64-musl.node')
} else {
nativeBinding = require('@bitwarden/desktop_native-linux-arm64-musl')
}
} catch (e) {
loadError = e
}
} else {
localFileExisted = existsSync(
join(__dirname, 'desktop_native.linux-arm64-gnu.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./desktop_native.linux-arm64-gnu.node')
} else {
nativeBinding = require('@bitwarden/desktop_native-linux-arm64-gnu')
}
} catch (e) {
loadError = e
}
}
break
case 'arm':
localFileExisted = existsSync(
join(__dirname, 'desktop_native.linux-arm-gnueabihf.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./desktop_native.linux-arm-gnueabihf.node')
} else {
nativeBinding = require('@bitwarden/desktop_native-linux-arm-gnueabihf')
}
} catch (e) {
loadError = e
}
break
default:
throw new Error(`Unsupported architecture on Linux: ${arch}`)
}
break
default:
throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
}
if (!nativeBinding) {
if (loadError) {
throw loadError
}
throw new Error(`Failed to load native binding`)
}
const { passwords } = nativeBinding
module.exports.passwords = passwords

41
desktop_native/package-lock.json generated Normal file
View File

@ -0,0 +1,41 @@
{
"name": "@bitwarden/desktop_native",
"version": "0.1.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@bitwarden/desktop_native",
"version": "0.1.0",
"hasInstallScript": true,
"license": "GPL-3.0",
"devDependencies": {
"@napi-rs/cli": "^2.6.2"
}
},
"node_modules/@napi-rs/cli": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.6.2.tgz",
"integrity": "sha512-EmH+DQDEBUIoqMim0cc+X96ImtcIZLFjgW5WWORpzYnA9Ug7zNPO7jCLMhIQRd/p5AdWaXrT4SVXc/aip09rKQ==",
"dev": true,
"bin": {
"napi": "scripts/index.js"
},
"engines": {
"node": ">= 10"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Brooooooklyn"
}
}
},
"dependencies": {
"@napi-rs/cli": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-2.6.2.tgz",
"integrity": "sha512-EmH+DQDEBUIoqMim0cc+X96ImtcIZLFjgW5WWORpzYnA9Ug7zNPO7jCLMhIQRd/p5AdWaXrT4SVXc/aip09rKQ==",
"dev": true
}
}
}

View File

@ -0,0 +1,32 @@
{
"name": "@bitwarden/desktop_native",
"version": "0.1.0",
"description": "",
"main": "index.node",
"scripts": {
"build": "napi build --release --platform",
"build:debug": "napi build --platform",
"build:cross-platform": "node build.js",
"test": "cargo test"
},
"author": "",
"license": "GPL-3.0",
"devDependencies": {
"@napi-rs/cli": "^2.6.2"
},
"napi": {
"name": "desktop_native",
"triples": {
"defaults": true,
"additional": [
"x86_64-unknown-linux-musl",
"aarch64-unknown-linux-gnu",
"i686-pc-windows-msvc",
"armv7-unknown-linux-gnueabihf",
"aarch64-apple-darwin",
"aarch64-unknown-linux-musl",
"aarch64-pc-windows-msvc"
]
}
}
}

39
desktop_native/src/lib.rs Normal file
View File

@ -0,0 +1,39 @@
#[macro_use]
extern crate napi_derive;
mod password;
#[napi]
pub mod passwords {
/// Fetch the stored password from the keychain.
#[napi]
pub async fn get_password(service: String, account: String) -> napi::Result<String> {
super::password::get_password(&service, &account)
.map_err(|e| napi::Error::from_reason(e.to_string()))
}
/// Fetch the stored password from the keychain that was stored with Keytar.
#[napi]
pub async fn get_password_keytar(service: String, account: String) -> napi::Result<String> {
super::password::get_password_keytar(&service, &account)
.map_err(|e| napi::Error::from_reason(e.to_string()))
}
/// Save the password to the keychain. Adds an entry if none exists otherwise updates the existing entry.
#[napi]
pub async fn set_password(
service: String,
account: String,
password: String,
) -> napi::Result<()> {
super::password::set_password(&service, &account, &password)
.map_err(|e| napi::Error::from_reason(e.to_string()))
}
/// Delete the stored password from the keychain.
#[napi]
pub async fn delete_password(service: String, account: String) -> napi::Result<()> {
super::password::delete_password(&service, &account)
.map_err(|e| napi::Error::from_reason(e.to_string()))
}
}

View File

@ -0,0 +1,59 @@
use anyhow::Result;
use security_framework::passwords::{
delete_generic_password, get_generic_password, set_generic_password,
};
pub fn get_password(service: &str, account: &str) -> Result<String> {
let result = String::from_utf8(get_generic_password(&service, &account)?)?;
Ok(result)
}
pub fn get_password_keytar(service: &str, account: &str) -> Result<String> {
get_password(service, account)
}
pub fn set_password(service: &str, account: &str, password: &str) -> Result<()> {
let result = set_generic_password(&service, &account, password.as_bytes())?;
Ok(result)
}
pub fn delete_password(service: &str, account: &str) -> Result<()> {
let result = delete_generic_password(&service, &account)?;
Ok(result)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
scopeguard::defer!(delete_password("BitwardenTest", "BitwardenTest").unwrap_or({}););
set_password("BitwardenTest", "BitwardenTest", "Random").unwrap();
assert_eq!(
"Random",
get_password("BitwardenTest", "BitwardenTest").unwrap()
);
delete_password("BitwardenTest", "BitwardenTest").unwrap();
// Ensure password is deleted
match get_password("BitwardenTest", "BitwardenTest") {
Ok(_) => panic!("Got a result"),
Err(e) => assert_eq!(
"The specified item could not be found in the keychain.",
e.to_string()
),
}
}
#[test]
fn test_error_no_password() {
match get_password("Unknown", "Unknown") {
Ok(_) => panic!("Got a result"),
Err(e) => assert_eq!(
"The specified item could not be found in the keychain.",
e.to_string()
),
}
}
}

View File

@ -0,0 +1,5 @@
#[cfg_attr(target_os = "linux", path = "unix.rs")]
#[cfg_attr(target_os = "windows", path = "windows.rs")]
#[cfg_attr(target_os = "macos", path = "macos.rs")]
mod password;
pub use password::*;

View File

@ -0,0 +1,91 @@
use anyhow::{anyhow, Result};
use libsecret::{password_clear_sync, password_lookup_sync, password_store_sync, Schema};
use std::collections::HashMap;
pub fn get_password(service: &str, account: &str) -> Result<String> {
let res = password_lookup_sync(
Some(&get_schema()),
build_attributes(service, account),
gio::Cancellable::NONE,
)?;
match res {
Some(s) => Ok(String::from(s)),
None => Err(anyhow!("No password found")),
}
}
pub fn get_password_keytar(service: &str, account: &str) -> Result<String> {
get_password(service, account)
}
pub fn set_password(service: &str, account: &str, password: &str) -> Result<()> {
let result = password_store_sync(
Some(&get_schema()),
build_attributes(service, account),
Some(&libsecret::COLLECTION_DEFAULT),
&format!("{}/{}", service, account),
password,
gio::Cancellable::NONE,
)?;
Ok(result)
}
pub fn delete_password(service: &str, account: &str) -> Result<()> {
let result = password_clear_sync(
Some(&get_schema()),
build_attributes(service, account),
gio::Cancellable::NONE,
)?;
Ok(result)
}
fn get_schema() -> Schema {
let mut attributes = std::collections::HashMap::new();
attributes.insert("service", libsecret::SchemaAttributeType::String);
attributes.insert("account", libsecret::SchemaAttributeType::String);
libsecret::Schema::new(
"org.freedesktop.Secret.Generic",
libsecret::SchemaFlags::NONE,
attributes,
)
}
fn build_attributes<'a>(service: &'a str, account: &'a str) -> HashMap<&'a str, &'a str> {
let mut attributes = HashMap::new();
attributes.insert("service", service);
attributes.insert("account", account);
attributes
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
scopeguard::defer!(delete_password("BitwardenTest", "BitwardenTest").unwrap_or({}););
set_password("BitwardenTest", "BitwardenTest", "Random").unwrap();
assert_eq!(
"Random",
get_password("BitwardenTest", "BitwardenTest").unwrap()
);
delete_password("BitwardenTest", "BitwardenTest").unwrap();
// Ensure password is deleted
match get_password("BitwardenTest", "BitwardenTest") {
Ok(_) => panic!("Got a result"),
Err(e) => assert_eq!("No password found", e.to_string()),
}
}
#[test]
fn test_error_no_password() {
match get_password("BitwardenTest", "BitwardenTest") {
Ok(_) => panic!("Got a result"),
Err(e) => assert_eq!("No password found", e.to_string()),
}
}
}

View File

@ -0,0 +1,180 @@
use anyhow::{anyhow, Result};
use widestring::{U16CString, U16String};
use windows::Win32::{
Foundation::{GetLastError, ERROR_NOT_FOUND, FILETIME, PWSTR, WIN32_ERROR},
Security::Credentials::{
CredDeleteW, CredFree, CredReadW, CredWriteW, CREDENTIALW, CRED_FLAGS,
CRED_PERSIST_ENTERPRISE, CRED_TYPE_GENERIC,
},
};
const CRED_FLAGS_NONE: u32 = 0;
pub fn get_password<'a>(service: &str, account: &str) -> Result<String> {
let target_name = U16CString::from_str(target_name(service, account))?;
let mut credential: *mut CREDENTIALW = std::ptr::null_mut();
let credential_ptr = &mut credential;
let result = unsafe {
CredReadW(
PWSTR(target_name.as_ptr()),
CRED_TYPE_GENERIC.0,
CRED_FLAGS_NONE,
credential_ptr,
)
};
scopeguard::defer!({
unsafe { CredFree(credential as *mut _) };
});
if !result.as_bool() {
return Err(anyhow!(convert_error(unsafe { GetLastError() })));
}
let password = unsafe {
U16String::from_ptr(
(*credential).CredentialBlob as *const u16,
(*credential).CredentialBlobSize as usize / 2,
)
.to_string_lossy()
};
Ok(String::from(password))
}
// Remove this after sufficient releases
pub fn get_password_keytar<'a>(service: &str, account: &str) -> Result<String> {
let target_name = U16CString::from_str(target_name(service, account))?;
let mut credential: *mut CREDENTIALW = std::ptr::null_mut();
let credential_ptr = &mut credential;
let result = unsafe {
CredReadW(
PWSTR(target_name.as_ptr()),
CRED_TYPE_GENERIC.0,
CRED_FLAGS_NONE,
credential_ptr,
)
};
scopeguard::defer!({
unsafe { CredFree(credential as *mut _) };
});
if !result.as_bool() {
return Err(anyhow!(unsafe { GetLastError() }.0.to_string()));
}
let password = unsafe {
std::str::from_utf8_unchecked(std::slice::from_raw_parts(
(*credential).CredentialBlob,
(*credential).CredentialBlobSize as usize,
))
};
Ok(String::from(password))
}
pub fn set_password(service: &str, account: &str, password: &str) -> Result<()> {
let target_name = U16CString::from_str(target_name(service, account))?;
let user_name = U16CString::from_str(account)?;
let last_written = FILETIME {
dwLowDateTime: 0,
dwHighDateTime: 0,
};
let credential = U16CString::from_str(password)?;
let credential_len = password.len() as u32 * 2;
let credential = CREDENTIALW {
Flags: CRED_FLAGS(CRED_FLAGS_NONE),
Type: CRED_TYPE_GENERIC,
TargetName: PWSTR(target_name.as_ptr()),
Comment: PWSTR::default(),
LastWritten: last_written,
CredentialBlobSize: credential_len,
CredentialBlob: credential.as_ptr() as *mut u8,
Persist: CRED_PERSIST_ENTERPRISE,
AttributeCount: 0,
Attributes: std::ptr::null_mut(),
TargetAlias: PWSTR::default(),
UserName: PWSTR(user_name.as_ptr()),
};
let result = unsafe { CredWriteW(&credential, 0) };
if !result.as_bool() {
return Err(anyhow!(unsafe { GetLastError() }.0.to_string()));
}
Ok(())
}
pub fn delete_password(service: &str, account: &str) -> Result<()> {
let target_name = U16CString::from_str(target_name(service, account))?;
unsafe {
CredDeleteW(
PWSTR(target_name.as_ptr()),
CRED_TYPE_GENERIC.0,
CRED_FLAGS_NONE,
)
.ok()?
};
Ok(())
}
fn target_name(service: &str, account: &str) -> String {
format!("{}/{}", service, account)
}
// Convert the internal WIN32 errors to descriptive messages
fn convert_error(code: WIN32_ERROR) -> String {
match code {
ERROR_NOT_FOUND => String::from("Password not found."),
_ => code.0.to_string(),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
scopeguard::defer!(delete_password("BitwardenTest", "BitwardenTest").unwrap_or({}););
set_password("BitwardenTest", "BitwardenTest", "Random").unwrap();
assert_eq!(
"Random",
get_password("BitwardenTest", "BitwardenTest").unwrap()
);
delete_password("BitwardenTest", "BitwardenTest").unwrap();
// Ensure password is deleted
match get_password("BitwardenTest", "BitwardenTest") {
Ok(_) => panic!("Got a result"),
Err(e) => assert_eq!("Password not found.", e.to_string()),
}
}
#[test]
fn test_get_password_keytar() {
scopeguard::defer!(delete_password("BitwardenTest", "BitwardenTest").unwrap_or({}););
keytar::set_password("BitwardenTest", "BitwardenTest", "HelloFromKeytar").unwrap();
assert_eq!(
"HelloFromKeytar",
get_password_keytar("BitwardenTest", "BitwardenTest").unwrap()
);
}
#[test]
fn test_error_no_password() {
match get_password("BitwardenTest", "BitwardenTest") {
Ok(_) => panic!("Got a result"),
Err(e) => assert_eq!("Password not found.", e.to_string()),
}
}
}

121
electron-builder.json Normal file
View File

@ -0,0 +1,121 @@
{
"extraMetadata": { "name": "bitwarden" },
"productName": "Bitwarden",
"appId": "com.bitwarden.desktop",
"buildDependenciesFromSource": true,
"copyright": "Copyright © 2015-2022 Bitwarden Inc.",
"directories": { "buildResources": "resources", "output": "dist", "app": "build" },
"afterSign": "scripts/after-sign.js",
"asarUnpack": ["**/*.node"],
"files": ["**/*", "!**/node_modules/@bitwarden/desktop-native/**/*"],
"publish": {
"provider": "generic",
"url": "https://artifacts.bitwarden.com/desktop"
},
"mac": {
"electronUpdaterCompatibility": ">=0.0.1",
"category": "public.app-category.productivity",
"darkModeSupport": true,
"gatekeeperAssess": false,
"hardenedRuntime": true,
"entitlements": "resources/entitlements.mac.plist",
"entitlementsInherit": "resources/entitlements.mac.plist",
"extendInfo": {
"ITSAppUsesNonExemptEncryption": false,
"CFBundleLocalizations": [
"en",
"cs",
"da",
"de",
"es",
"et",
"fi",
"fr",
"hr",
"hu",
"id",
"it",
"ja",
"nb",
"nl",
"pl",
"pt-BR",
"pt-PT",
"ro",
"ru",
"sk",
"sv",
"tr",
"uk",
"vi",
"zh-Hans",
"zh-Hant"
],
"CFBundleDevelopmentRegion": "en"
},
"target": ["dmg", "zip"]
},
"win": {
"electronUpdaterCompatibility": ">=0.0.1",
"target": ["portable", "nsis-web", "appx"],
"sign": "./sign.js",
"extraResources": [
{ "from": "node_modules/regedit/vbs", "to": "regedit/vbs", "filter": ["**/*"] },
{ "from": "resources/native-messaging.bat", "to": "native-messaging.bat" }
]
},
"linux": {
"category": "Utility",
"synopsis": "A secure and free password manager for all of your devices.",
"target": ["deb", "freebsd", "rpm", "AppImage", "snap"],
"desktop": { "Name": "Bitwarden", "Type": "Application", "GenericName": "Password Manager" }
},
"dmg": {
"icon": "dmg.icns",
"contents": [
{ "x": 150, "y": 185, "type": "file" },
{ "x": 390, "y": 180, "type": "link", "path": "/Applications" }
],
"window": { "width": 540, "height": 380 }
},
"mas": {
"entitlements": "resources/entitlements.mas.plist",
"entitlementsInherit": "resources/entitlements.mas.inherit.plist",
"hardenedRuntime": false,
"extendInfo": { "LSMinimumSystemVersion": "10.14.0" }
},
"nsisWeb": {
"oneClick": false,
"perMachine": false,
"allowToChangeInstallationDirectory": false,
"artifactName": "${productName}-Installer-${version}.${ext}",
"uninstallDisplayName": "${productName}",
"deleteAppDataOnUninstall": true
},
"portable": { "artifactName": "${productName}-Portable-${version}.${ext}" },
"appx": {
"artifactName": "${productName}-${version}-${arch}.${ext}",
"backgroundColor": "#175DDC",
"applicationId": "bitwardendesktop",
"identityName": "8bitSolutionsLLC.bitwardendesktop",
"publisher": "CN=14D52771-DE3C-4886-B8BF-825BA7690418",
"publisherDisplayName": "8bit Solutions LLC",
"languages": ["en-US"]
},
"deb": {
"artifactName": "${productName}-${version}-${arch}.${ext}",
"depends": ["libnotify4", "libxtst6", "libnss3", "libsecret-1-0", "libxss1"]
},
"appImage": {
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
"rpm": { "artifactName": "${productName}-${version}-${arch}.${ext}" },
"freebsd": { "artifactName": "${productName}-${version}-${arch}.${ext}" },
"snap": {
"autoStart": true,
"confinement": "strict",
"plugs": ["default", "password-manager-service"],
"stagePackages": ["default"]
},
"protocols": [{ "name": "Bitwarden", "schemes": ["bitwarden"] }]
}

View File

@ -1,35 +0,0 @@
const gulp = require('gulp');
const googleWebFonts = require('gulp-google-webfonts');
const del = require('del');
const fs = require('fs');
const paths = {
cssDir: './src/css/',
node_modules: './node_modules/',
dist: './dist/',
resources: './resources/',
};
function clean() {
return del([paths.cssDir]);
}
function webfonts() {
return gulp.src('./webfonts.list')
.pipe(googleWebFonts({
fontsDir: 'webfonts',
cssFilename: 'webfonts.css',
format: 'woff',
}))
.pipe(gulp.dest(paths.cssDir));
}
// ref: https://github.com/angular/angular/issues/22524
function cleanupAotIssue() {
return del(['./node_modules/@types/uglify-js/node_modules/source-map/source-map.d.ts']);
}
exports.clean = clean;
exports.cleanupAotIssue = cleanupAotIssue;
exports.webfonts = gulp.series(clean, webfonts);
exports['prebuild:renderer'] = gulp.parallel(webfonts, cleanupAotIssue);

2
jslib

@ -1 +1 @@
Subproject commit 11fff06b8cd10468ffac617ab8674ba7ea6651a9
Subproject commit 80c834b52a8b00f88250a47a9bbd40c269fc2cba

29371
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,5 @@
{
"name": "bitwarden",
"productName": "Bitwarden",
"name": "@bitwarden/desktop",
"description": "A secure and free password manager for all of your devices.",
"version": "0.0.0",
"keywords": [
@ -22,22 +21,27 @@
"sub:update": "git submodule update --remote",
"sub:pull": "git submodule foreach git pull origin master",
"sub:commit": "npm run sub:pull && git commit -am \"update submodule\"",
"postinstall": "./node_modules/.bin/electron-rebuild && npm run sub:init && patch-package",
"preinstall": "npm run sub:init",
"postinstall": "electron-rebuild",
"symlink:win": "rm -rf ./jslib && cmd /c mklink /J .\\jslib ..\\jslib",
"symlink:mac": "npm run symlink:lin",
"symlink:lin": "rm -rf ./jslib && ln -s ../jslib ./jslib",
"lint": "tslint 'src/**/*.ts'",
"lint:fix": "tslint 'src/**/*.ts' --fix",
"lint": "eslint . && prettier --check .",
"lint:fix": "eslint . --fix",
"build": "concurrently -n Main,Rend -c yellow,cyan \"npm run build:main\" \"npm run build:renderer\"",
"build:main": "webpack --config webpack.main.js",
"build:renderer": "gulp prebuild:renderer && webpack --config webpack.renderer.js",
"build:renderer:watch": "gulp prebuild:renderer && webpack --config webpack.renderer.js --watch",
"electron": "npm run build:main && concurrently -k -n Main,Rend -c yellow,cyan \"electron --inspect=5858 ./build --watch\" \"npm run build:renderer:watch\"",
"build:dev": "concurrently -n Main,Rend -c yellow,cyan \"npm run build:main:dev\" \"npm run build:renderer:dev\"",
"build:main": "cross-env NODE_ENV=production webpack --config webpack.main.js",
"build:main:dev": "cross-env NODE_ENV=development webpack --config webpack.main.js",
"build:renderer": "cross-env NODE_ENV=production webpack --config webpack.renderer.js",
"build:renderer:dev": "cross-env NODE_ENV=development webpack --config webpack.renderer.js",
"build:renderer:watch": "cross-env NODE_ENV=development webpack --config webpack.renderer.js --watch",
"electron": "npm run build:main:dev && concurrently -k -n Main,Rend -c yellow,cyan \"electron --inspect=5858 ./build --watch\" \"npm run build:renderer:watch\"",
"electron:ignore": "npm run build:main:dev && concurrently -k -n Main,Rend -c yellow,cyan \"electron --inspect=5858 --ignore-certificate-errors ./build --watch\" \"npm run build:renderer:watch\"",
"clean:dist": "rimraf ./dist/*",
"clean:l10n": "git push origin --delete l10n_master",
"pack:dir": "npm run clean:dist && electron-builder --dir -p never",
"pack:lin": "npm run clean:dist && electron-builder --linux --x64 -p never",
"pack:mac": "npm run clean:dist && electron-builder --mac -p never",
"pack:mac": "npm run clean:dist && electron-builder --mac --universal -p never",
"pack:mac:arm64": "npm run clean:dist && electron-builder --mac --arm64 -p never",
"pack:mac:mas": "npm run clean:dist && electron-builder --mac mas --universal -p never",
"pack:mac:masdev": "npm run clean:dist && electron-builder --mac mas-dev --universal -p never",
@ -54,276 +58,79 @@
"publish:mac": "npm run build && npm run clean:dist && electron-builder --mac -p always",
"publish:mac:mas": "npm run dist:mac:mas && npm run upload:mas",
"publish:win": "npm run build && npm run clean:dist && electron-builder --win --x64 --arm64 --ia32 -p always -c.win.certificateSubjectName=\"8bit Solutions LLC\"",
"upload:mas": "xcrun altool --upload-app --type osx --file \"$(find ./dist/mas/Bitwarden*.pkg)\" --username $APPLE_ID_USERNAME --password $APPLE_ID_PASSWORD"
},
"build": {
"appId": "com.bitwarden.desktop",
"buildDependenciesFromSource": true,
"copyright": "Copyright © 2015-2021 Bitwarden Inc.",
"directories": {
"buildResources": "resources",
"output": "dist",
"app": "build"
},
"afterSign": "scripts/after-sign.js",
"mac": {
"electronUpdaterCompatibility": ">=0.0.1",
"category": "public.app-category.productivity",
"extraFiles": [
"PlugIns/"
],
"darkModeSupport": true,
"gatekeeperAssess": false,
"hardenedRuntime": true,
"entitlements": "resources/entitlements.mac.plist",
"entitlementsInherit": "resources/entitlements.mac.plist",
"extendInfo": {
"ITSAppUsesNonExemptEncryption": false,
"CFBundleLocalizations": [
"en",
"cs",
"da",
"de",
"es",
"et",
"fi",
"fr",
"hr",
"hu",
"id",
"it",
"ja",
"nb",
"nl",
"pl",
"pt-BR",
"pt-PT",
"ro",
"ru",
"sk",
"sv",
"tr",
"uk",
"vi",
"zh-Hans",
"zh-Hant"
],
"CFBundleDevelopmentRegion": "en"
},
"target": [
"dmg",
"zip"
]
},
"win": {
"electronUpdaterCompatibility": ">=0.0.1",
"target": [
"portable",
"nsis-web",
"appx"
],
"sign": "./sign.js",
"extraResources": [
{
"from": "node_modules/regedit/vbs",
"to": "regedit/vbs",
"filter": [
"**/*"
]
},
{
"from": "resources/native-messaging.bat",
"to": "native-messaging.bat"
}
]
},
"linux": {
"category": "Utility",
"synopsis": "A secure and free password manager for all of your devices.",
"target": [
"deb",
"freebsd",
"rpm",
"AppImage",
"snap"
],
"desktop": {
"Name": "Bitwarden",
"Type": "Application",
"GenericName": "Password Manager"
}
},
"dmg": {
"icon": "dmg.icns",
"contents": [
{
"x": 150,
"y": 185,
"type": "file"
},
{
"x": 390,
"y": 180,
"type": "link",
"path": "/Applications"
}
],
"window": {
"width": 540,
"height": 380
}
},
"mas": {
"entitlements": "resources/entitlements.mas.plist",
"entitlementsInherit": "resources/entitlements.mas.inherit.plist",
"hardenedRuntime": false,
"asarUnpack": [
"node_modules/keytar"
]
},
"nsisWeb": {
"oneClick": false,
"perMachine": true,
"allowToChangeInstallationDirectory": true,
"artifactName": "${productName}-Installer-${version}.${ext}",
"uninstallDisplayName": "${productName}",
"deleteAppDataOnUninstall": true
},
"portable": {
"artifactName": "${productName}-Portable-${version}.${ext}"
},
"appx": {
"artifactName": "${productName}-${version}-${arch}.${ext}",
"backgroundColor": "#175DDC",
"applicationId": "bitwardendesktop",
"identityName": "8bitSolutionsLLC.bitwardendesktop",
"publisher": "CN=14D52771-DE3C-4886-B8BF-825BA7690418",
"publisherDisplayName": "8bit Solutions LLC",
"languages": [
"en-US"
]
},
"deb": {
"artifactName": "${productName}-${version}-${arch}.${ext}",
"depends": [
"libnotify4",
"libxtst6",
"libnss3",
"libsecret-1-0",
"libxss1"
]
},
"appImage": {
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
"rpm": {
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
"freebsd": {
"artifactName": "${productName}-${version}-${arch}.${ext}"
},
"snap": {
"autoStart": true,
"confinement": "strict",
"plugs": [
"default",
"password-manager-service"
],
"stagePackages": [
"default"
],
"publish": [
"github"
]
},
"protocols": [
{
"name": "Bitwarden",
"schemes": [
"bitwarden"
]
}
]
"publish:win:dev": "npm run build && npm run clean:dist && electron-builder --win --x64 --arm64 --ia32 -p always",
"upload:mas": "xcrun altool --upload-app --type osx --file \"$(find ./dist/mas-universal/Bitwarden*.pkg)\" --username $APPLE_ID_USERNAME --password $APPLE_ID_PASSWORD",
"prettier": "prettier --write .",
"prepare": "husky install"
},
"devDependencies": {
"@angular/compiler-cli": "^9.1.12",
"@ngtools/webpack": "^9.1.12",
"@types/lunr": "^2.3.3",
"@types/node": "^10.17.28",
"@types/node-forge": "^0.9.7",
"@types/papaparse": "^5.2.0",
"@types/semver": "^5.5.0",
"@types/webcrypto": "^0.0.28",
"@types/webpack": "^4.4.11",
"@types/zxcvbn": "4.4.0",
"clean-webpack-plugin": "^0.1.19",
"concurrently": "^4.0.1",
"copy-webpack-plugin": "^5.1.1",
"cross-env": "^5.2.0",
"css-loader": "^1.0.0",
"del": "^3.0.0",
"electron": "11.3.0",
"electron-builder": "22.10.5",
"electron-notarize": "^1.0.0",
"electron-rebuild": "^2.3.5",
"@angular/compiler-cli": "^12.2.13",
"@ngtools/webpack": "^12.2.13",
"@types/node": "^16.11.12",
"@types/node-ipc": "^9.1.4",
"@typescript-eslint/eslint-plugin": "^5.12.1",
"@typescript-eslint/parser": "^5.12.1",
"clean-webpack-plugin": "^4.0.0",
"concurrently": "^6.0.2",
"copy-webpack-plugin": "^10.0.0",
"cross-env": "^7.0.3",
"css-loader": "^6.5.1",
"electron-builder": "22.11.7",
"electron-notarize": "^1.1.1",
"electron-rebuild": "^3.2.5",
"electron-reload": "^1.5.0",
"file-loader": "^2.0.0",
"font-awesome": "4.7.0",
"gulp": "^4.0.0",
"gulp-google-webfonts": "^2.0.0",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.9.0",
"ngx-infinite-scroll": "7.0.1",
"node-abi": "^2.9.0",
"node-loader": "^0.6.0",
"node-sass": "^4.13.1",
"patch-package": "^6.4.7",
"rimraf": "^2.6.2",
"sass-loader": "^7.1.0",
"ts-loader": "^8.0.2",
"tslint": "^6.1.3",
"tslint-loader": "^3.5.4",
"typescript": "3.8.3",
"webpack": "^4.29.0",
"webpack-cli": "^3.2.1",
"webpack-merge": "^4.2.1",
"webpack-node-externals": "^1.7.2"
"eslint": "^8.9.0",
"eslint-config-prettier": "^8.4.0",
"eslint-import-resolver-typescript": "^2.5.0",
"eslint-plugin-import": "^2.25.4",
"html-loader": "^3.0.1",
"html-webpack-plugin": "^5.5.0",
"husky": "^7.0.4",
"lint-staged": "^12.1.3",
"mini-css-extract-plugin": "^2.4.5",
"node-loader": "^2.0.0",
"prettier": "^2.5.1",
"rimraf": "^3.0.2",
"sass": "^1.32.11",
"sass-loader": "^12.4.0",
"tapable": "^1.1.3",
"ts-loader": "^9.2.5",
"tsconfig-paths-webpack-plugin": "^3.5.1",
"typescript": "4.3.5",
"webpack": "^5.64.4",
"webpack-cli": "^4.9.1",
"webpack-merge": "^5.8.0"
},
"dependencies": {
"@angular/animations": "9.1.12",
"@angular/cdk": "9.2.4",
"@angular/common": "9.1.12",
"@angular/compiler": "9.1.12",
"@angular/core": "9.1.12",
"@angular/forms": "9.1.12",
"@angular/platform-browser": "9.1.12",
"@angular/platform-browser-dynamic": "9.1.12",
"@angular/router": "9.1.12",
"@angular/upgrade": "9.1.12",
"@microsoft/signalr": "3.1.13",
"@microsoft/signalr-protocol-msgpack": "3.1.13",
"@angular/animations": "^12.2.13",
"@angular/cdk": "^12.2.13",
"@angular/common": "^12.2.13",
"@angular/compiler": "^12.2.13",
"@angular/core": "^12.2.13",
"@angular/forms": "^12.2.13",
"@angular/platform-browser": "^12.2.13",
"@angular/platform-browser-dynamic": "^12.2.13",
"@angular/router": "^12.2.13",
"@bitwarden/jslib-angular": "file:jslib/angular",
"@bitwarden/jslib-common": "file:jslib/common",
"@bitwarden/jslib-electron": "file:jslib/electron",
"@nodert-win10-rs4/windows.security.credentials.ui": "^0.4.4",
"angular2-toaster": "8.0.0",
"big-integer": "1.6.48",
"browser-hrtime": "^1.1.8",
"core-js": "2.6.2",
"duo_web_sdk": "git+https://github.com/duosecurity/duo_web_sdk.git",
"electron-log": "4.3.0",
"electron-store": "6.0.1",
"electron-updater": "4.3.5",
"forcefocus": "^1.1.0",
"keytar": "7.3.0",
"lunr": "2.3.3",
"node-forge": "0.10.0",
"node-ipc": "^9.1.1",
"nord": "0.2.1",
"papaparse": "5.2.0",
"keytar": "^7.9.0",
"ngx-toastr": "14.1.4",
"node-ipc": "^9.1.4",
"nord": "^0.2.1",
"regedit": "^3.0.3",
"rxjs": "6.6.2",
"sweetalert2": "10.15.4",
"tslib": "^2.0.1",
"zone.js": "0.10.3",
"zxcvbn": "4.4.2"
"rxjs": "^7.4.0",
"sweetalert2": "^10.16.6",
"zone.js": "0.11.4"
},
"engines": {
"node": "~16",
"npm": "~8"
},
"lint-staged": {
"./!(jslib)**": "prettier --ignore-unknown --write",
"*.ts": "eslint --fix"
}
}

View File

@ -1,54 +0,0 @@
diff --git a/node_modules/app-builder-lib/out/macPackager.js b/node_modules/app-builder-lib/out/macPackager.js
index 41e067c..cd97293 100644
--- a/node_modules/app-builder-lib/out/macPackager.js
+++ b/node_modules/app-builder-lib/out/macPackager.js
@@ -292,6 +292,23 @@ class MacPackager extends _platformPackager().PlatformPackager {
const appFile = `${this.appInfo.productFilename}.app`;
+ // Bitwarden Patch: Electron-Builder currently does not support including our Safari extension which
+ // is already cross-compiled. Hence we remove it prior to making the universal package, and re-add
+ // it afterwards
+ // https://github.com/electron-userland/electron-builder/issues/5552
+ const rmdir = (0, _fsExtra().remove);
+ try {
+ await rmdir(`${x64AppOutDir}/Bitwarden.app/Contents/PlugIns`, {
+ recursive: true
+ });
+ await rmdir(`${arm64AppOutPath}/Bitwarden.app/Contents/PlugIns`, {
+ recursive: true
+ });
+ } catch (e) {
+ // Catches errors where PlugIns does not exist
+ console.log(e);
+ }
+
const {
makeUniversalApp
} = require('@electron/universal');
@@ -302,7 +319,15 @@ class MacPackager extends _platformPackager().PlatformPackager {
outAppPath: path.join(appOutDir, appFile),
force: true
});
- const rmdir = (0, _util().promisify)(require('fs').rmdir);
+
+ // Bitwarden Patch: Re-add PlugIns dir to Universal binary
+ try {
+ await ((0, _fsExtra().copy)(path.join(this.projectDir, 'PlugIns'), `${path.join(appOutDir, appFile)}/Contents/PlugIns`));
+ } catch (e) {
+ // Catches errors where PlugIns does not exist
+ console.log(e);
+ }
+
await rmdir(x64AppOutDir, {
recursive: true
});
@@ -611,7 +636,7 @@ exports.default = MacPackager;
function getCertificateType(isMas, isDevelopment) {
if (isDevelopment) {
- return "Mac Developer";
+ return "Apple Development";
}
return isMas ? "3rd Party Mac Developer Application" : "Developer ID Application";

View File

@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>

View File

@ -15,6 +15,7 @@
<string>/Library/Application Support/Google/Chrome Beta/NativeMessagingHosts/</string>
<string>/Library/Application Support/Google/Chrome Dev/NativeMessagingHosts/</string>
<string>/Library/Application Support/Google/Chrome Canary/NativeMessagingHosts/</string>
<string>/Library/Application Support/Chromium/NativeMessagingHosts/</string>
<string>/Library/Application Support/Microsoft Edge/NativeMessagingHosts/</string>
<string>/Library/Application Support/Microsoft Edge Beta/NativeMessagingHosts/</string>
<string>/Library/Application Support/Microsoft Edge Dev/NativeMessagingHosts/</string>

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 717 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 KiB

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 510 B

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -1,25 +1,62 @@
require('dotenv').config();
const { notarize } = require('electron-notarize');
/* eslint-disable @typescript-eslint/no-var-requires, no-console */
require("dotenv").config();
const path = require("path");
const { deepAssign } = require("builder-util");
const { notarize } = require("electron-notarize");
const fse = require("fs-extra");
exports.default = run;
async function run(context) {
console.log('## After sign');
// console.log(context);
console.log("## After sign");
// console.log(context);
const appName = context.packager.appInfo.productFilename;
const appPath = `${context.appOutDir}/${appName}.app`;
const macBuild = context.electronPlatformName === 'darwin';
const appName = context.packager.appInfo.productFilename;
const appPath = `${context.appOutDir}/${appName}.app`;
const macBuild = context.electronPlatformName === "darwin";
const copyPlugIn = ["darwin", "mas"].includes(context.electronPlatformName);
if (macBuild) {
console.log('### Notarizing ' + appPath);
const appleId = process.env.APPLE_ID_USERNAME || process.env.APPLEID;
const appleIdPassword = process.env.APPLE_ID_PASSWORD || `@keychain:AC_PASSWORD`;
return await notarize({
appBundleId: 'com.bitwarden.desktop',
appPath: appPath,
appleId: appleId,
appleIdPassword: appleIdPassword,
});
if (copyPlugIn) {
// Copy Safari plugin to work-around https://github.com/electron-userland/electron-builder/issues/5552
const plugIn = path.join(__dirname, "../PlugIns");
if (fse.existsSync(plugIn)) {
fse.mkdirSync(path.join(appPath, "Contents/PlugIns"));
fse.copySync(
path.join(plugIn, "safari.appex"),
path.join(appPath, "Contents/PlugIns/safari.appex")
);
// Resign to sign safari extension
if (context.electronPlatformName === "mas") {
const masBuildOptions = deepAssign(
{},
context.packager.platformSpecificBuildOptions,
context.packager.config.mas
);
if (context.targets.some((e) => e.name === "mas-dev")) {
deepAssign(masBuildOptions, {
type: "development",
});
}
if (context.packager.packagerOptions.prepackaged == null) {
await context.packager.sign(appPath, context.appOutDir, masBuildOptions, context.arch);
}
} else {
await context.packager.signApp(context, true);
}
}
}
if (macBuild) {
console.log("### Notarizing " + appPath);
const appleId = process.env.APPLE_ID_USERNAME || process.env.APPLEID;
const appleIdPassword = process.env.APPLE_ID_PASSWORD || `@keychain:AC_PASSWORD`;
return await notarize({
appBundleId: "com.bitwarden.desktop",
appPath: appPath,
appleId: appleId,
appleIdPassword: appleIdPassword,
});
}
}

1
scripts/dev/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
data

View File

@ -0,0 +1,19 @@
version: "3"
services:
minio:
image: minio/minio
command: server /data --console-address ":9001"
ports:
- "9000:9000"
- "9001:9001"
# environment:
# MINIO_ROOT_USER: minioadmin
# MINIO_ROOT_PASSWORD: minioadmin
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
volumes:
- ./data:/data

33
sign.js
View File

@ -1,22 +1,21 @@
exports.default = async function(configuration) {
if (
parseInt(process.env.ELECTRON_BUILDER_SIGN) === 1 &&
configuration.path.slice(-4) == ".exe"
) {
console.log(`[*] Signing file: ${configuration.path}`)
/* eslint-disable @typescript-eslint/no-var-requires, no-console */
exports.default = async function (configuration) {
if (parseInt(process.env.ELECTRON_BUILDER_SIGN) === 1 && configuration.path.slice(-4) == ".exe") {
console.log(`[*] Signing file: ${configuration.path}`);
require("child_process").execSync(
`azuresigntool sign ` +
`-kvu ${process.env.SIGNING_VAULT_URL} ` +
`-kvi ${process.env.SIGNING_CLIENT_ID} ` +
`-kvt ${process.env.SIGNING_TENANT_ID} ` +
`-kvs ${process.env.SIGNING_CLIENT_SECRET} ` +
`-kvc ${process.env.SIGNING_CERT_NAME} ` +
`-fd ${configuration.hash} ` +
`-du ${configuration.site} ` +
`-tr http://timestamp.digicert.com ` +
`${configuration.path}`,
`azuresigntool sign -v ` +
`-kvu ${process.env.SIGNING_VAULT_URL} ` +
`-kvi ${process.env.SIGNING_CLIENT_ID} ` +
`-kvt ${process.env.SIGNING_TENANT_ID} ` +
`-kvs ${process.env.SIGNING_CLIENT_SECRET} ` +
`-kvc ${process.env.SIGNING_CERT_NAME} ` +
`-fd ${configuration.hash} ` +
`-du ${configuration.site} ` +
`-tr http://timestamp.digicert.com ` +
`${configuration.path}`,
{
stdio: "inherit"
stdio: "inherit",
}
);
}

View File

@ -1,64 +1,93 @@
<div class="modal fade" tabindex="-1" role="dialog" aria-modal="true" attr.aria-label="{{'settings' | i18n}}">
<div class="modal-dialog" role="document">
<form class="modal-content" (ngSubmit)="submit()">
<div class="modal-body">
<div class="box">
<div class="box-header">
{{'selfHostedEnvironment' | i18n}}
</div>
<div class="box-content">
<div class="box-content-row" appBoxRow>
<label for="baseUrl">{{'baseUrl' | i18n}}</label>
<input id="baseUrl" type="text" name="BaseUrl" [(ngModel)]="baseUrl"
placeholder="{{'ex' | i18n}} https://bitwarden.company.com">
</div>
</div>
<div class="box-footer">
{{'selfHostedEnvironmentFooter' | i18n}}
</div>
</div>
<div class="box">
<div class="box-header">
<button type="button" (click)="toggleCustom()" appA11yTitle="{{'toggleVisibility' | i18n}}">
<i class="fa fa-plus-square-o" [hidden]="showCustom" aria-hidden="true"></i>
<i class="fa fa-minus-square-o" [hidden]="!showCustom" aria-hidden="true"></i>
{{'customEnvironment' | i18n}}
</button>
</div>
<div class="box-content" [hidden]="!showCustom">
<div class="box-content-row" appBoxRow>
<label for="webVaultUrl">{{'webVaultUrl' | i18n}}</label>
<input id="webVaultUrl" type="text" name="WebVaultUrl" [(ngModel)]="webVaultUrl">
</div>
<div class="box-content-row" appBoxRow>
<label for="apiUrl">{{'apiUrl' | i18n}}</label>
<input id="apiUrl" type="text" name="ApiUrl" [(ngModel)]="apiUrl">
</div>
<div class="box-content-row" appBoxRow>
<label for="identityUrl">{{'identityUrl' | i18n}}</label>
<input id="identityUrl" type="text" name="IdentityUrl" [(ngModel)]="identityUrl">
</div>
<div class="box-content-row" appBoxRow>
<label for="notificationsUrl">{{'notificationsUrl' | i18n}}</label>
<input id="notificationsUrl" type="text" name="NotificationsUrl"
[(ngModel)]="notificationsUrl">
</div>
<div class="box-content-row" appBoxRow>
<label for="iconsUrl">{{'iconsUrl' | i18n}}</label>
<input id="iconsUrl" type="text" name="IconsUrl" [(ngModel)]="iconsUrl">
</div>
</div>
<div class="box-footer" [hidden]="!showCustom">
{{'customEnvironmentFooter' | i18n}}
</div>
</div>
<div class="modal fade" role="dialog" aria-modal="true" attr.aria-label="{{ 'settings' | i18n }}">
<div class="modal-dialog" role="document">
<form class="modal-content" (ngSubmit)="submit()">
<div class="modal-body">
<div class="box">
<div class="box-header">
{{ "selfHostedEnvironment" | i18n }}
</div>
<div class="box-content">
<div class="box-content-row" appBoxRow>
<label for="baseUrl">{{ "baseUrl" | i18n }}</label>
<input
id="baseUrl"
type="text"
name="BaseUrl"
[(ngModel)]="baseUrl"
placeholder="{{ 'ex' | i18n }} https://bitwarden.company.com"
appInputVerbatim
/>
</div>
<div class="modal-footer">
<button appBlurClick type="submit" class="primary" appA11yTitle="{{'save' | i18n}}">
<i class="fa fa-save fa-lg fa-fw" aria-hidden="true"></i>
</button>
<button type="button" data-dismiss="modal">{{'close' | i18n}}</button>
</div>
<div class="box-footer">
{{ "selfHostedEnvironmentFooter" | i18n }}
</div>
</div>
<div class="box">
<div class="box-header">
<button type="button" (click)="toggleCustom()" [attr.aria-expanded]="showCustom">
<i class="bwi bwi-plus-square" [hidden]="showCustom" aria-hidden="true"></i>
<i class="bwi bwi-minus-square" [hidden]="!showCustom" aria-hidden="true"></i>
{{ "customEnvironment" | i18n }}
</button>
</div>
<div class="box-content" [hidden]="!showCustom">
<div class="box-content-row" appBoxRow>
<label for="webVaultUrl">{{ "webVaultUrl" | i18n }}</label>
<input
id="webVaultUrl"
type="text"
name="WebVaultUrl"
[(ngModel)]="webVaultUrl"
appInputVerbatim
/>
</div>
</form>
</div>
<div class="box-content-row" appBoxRow>
<label for="apiUrl">{{ "apiUrl" | i18n }}</label>
<input id="apiUrl" type="text" name="ApiUrl" [(ngModel)]="apiUrl" appInputVerbatim />
</div>
<div class="box-content-row" appBoxRow>
<label for="identityUrl">{{ "identityUrl" | i18n }}</label>
<input
id="identityUrl"
type="text"
name="IdentityUrl"
[(ngModel)]="identityUrl"
appInputVerbatim
/>
</div>
<div class="box-content-row" appBoxRow>
<label for="notificationsUrl">{{ "notificationsUrl" | i18n }}</label>
<input
id="notificationsUrl"
type="text"
name="NotificationsUrl"
[(ngModel)]="notificationsUrl"
appInputVerbatim
/>
</div>
<div class="box-content-row" appBoxRow>
<label for="iconsUrl">{{ "iconsUrl" | i18n }}</label>
<input
id="iconsUrl"
type="text"
name="IconsUrl"
[(ngModel)]="iconsUrl"
appInputVerbatim
/>
</div>
</div>
<div class="box-footer" [hidden]="!showCustom">
{{ "customEnvironmentFooter" | i18n }}
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="primary" appA11yTitle="{{ 'save' | i18n }}">
<i class="bwi bwi-save-changes bwi-lg bwi-fw" aria-hidden="true"></i>
</button>
<button type="button" data-dismiss="modal">{{ "close" | i18n }}</button>
</div>
</form>
</div>
</div>

View File

@ -1,18 +1,20 @@
import { Component } from '@angular/core';
import { Component } from "@angular/core";
import { EnvironmentService } from 'jslib/abstractions/environment.service';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
import { EnvironmentComponent as BaseEnvironmentComponent } from 'jslib/angular/components/environment.component';
import { EnvironmentComponent as BaseEnvironmentComponent } from "jslib-angular/components/environment.component";
import { EnvironmentService } from "jslib-common/abstractions/environment.service";
import { I18nService } from "jslib-common/abstractions/i18n.service";
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
@Component({
selector: 'app-environment',
templateUrl: 'environment.component.html',
selector: "app-environment",
templateUrl: "environment.component.html",
})
export class EnvironmentComponent extends BaseEnvironmentComponent {
constructor(platformUtilsService: PlatformUtilsService, environmentService: EnvironmentService,
i18nService: I18nService) {
super(platformUtilsService, environmentService, i18nService);
}
constructor(
platformUtilsService: PlatformUtilsService,
environmentService: EnvironmentService,
i18nService: I18nService
) {
super(platformUtilsService, environmentService, i18nService);
}
}

View File

@ -1,23 +1,31 @@
<form id="hint-page" #form (ngSubmit)="submit()" [appApiAction]="formPromise">
<div class="content">
<h1>{{'passwordHint' | i18n}}</h1>
<div class="box last">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<label for="email">{{'emailAddress' | i18n}}</label>
<input id="email" type="text" name="Email" [(ngModel)]="email" required appAutofocus>
</div>
</div>
<div class="box-footer">
{{'enterEmailToGetHint' | i18n}}
</div>
</div>
<div class="buttons">
<button type="submit" class="btn primary block" [disabled]="form.loading" appBlurClick>
<b [hidden]="form.loading">{{'submit' | i18n}}</b>
<i class="fa fa-spinner fa-spin" [hidden]="!form.loading" aria-hidden="true"></i>
</button>
<a routerLink="/login" class="btn block">{{'cancel' | i18n}}</a>
<div class="content">
<h1>{{ "passwordHint" | i18n }}</h1>
<div class="box last">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<label for="email">{{ "emailAddress" | i18n }}</label>
<input
id="email"
type="text"
name="Email"
[(ngModel)]="email"
required
appAutofocus
appInputVerbatim
/>
</div>
</div>
<div class="box-footer">
{{ "enterEmailToGetHint" | i18n }}
</div>
</div>
<div class="buttons">
<button type="submit" class="btn primary block" [disabled]="form.loading">
<b [hidden]="form.loading">{{ "submit" | i18n }}</b>
<i class="bwi bwi-spinner bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
</button>
<button type="button" routerLink="/login" class="btn block">{{ "cancel" | i18n }}</button>
</div>
</div>
</form>

View File

@ -1,19 +1,24 @@
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { Component } from "@angular/core";
import { Router } from "@angular/router";
import { ApiService } from 'jslib/abstractions/api.service';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
import { HintComponent as BaseHintComponent } from 'jslib/angular/components/hint.component';
import { HintComponent as BaseHintComponent } from "jslib-angular/components/hint.component";
import { ApiService } from "jslib-common/abstractions/api.service";
import { I18nService } from "jslib-common/abstractions/i18n.service";
import { LogService } from "jslib-common/abstractions/log.service";
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
@Component({
selector: 'app-hint',
templateUrl: 'hint.component.html',
selector: "app-hint",
templateUrl: "hint.component.html",
})
export class HintComponent extends BaseHintComponent {
constructor(router: Router, platformUtilsService: PlatformUtilsService,
i18nService: I18nService, apiService: ApiService) {
super(router, i18nService, apiService, platformUtilsService);
}
constructor(
router: Router,
platformUtilsService: PlatformUtilsService,
i18nService: I18nService,
apiService: ApiService,
logService: LogService
) {
super(router, i18nService, apiService, platformUtilsService, logService);
}
}

View File

@ -1,47 +1,75 @@
<form id="lock-page" (ngSubmit)="submit()">
<div class="content">
<p aria-hidden="true"><i class="fa fa-lock fa-4x text-muted"></i></p>
<p>{{(pinLock ? 'yourVaultIsLockedPinCode' : 'yourVaultIsLocked') | i18n}}</p>
<div class="box last">
<div class="box-content">
<div class="box-content-row box-content-row-flex" appBoxRow>
<div class="row-main" *ngIf="pinLock">
<label for="pin">{{'pin' | i18n}}</label>
<input id="pin" type="{{showPassword ? 'text' : 'password'}}" name="PIN" class="monospaced"
[(ngModel)]="pin" required appAutofocus>
</div>
<div class="row-main" *ngIf="!pinLock">
<label for="masterPassword">{{'masterPass' | i18n}}</label>
<input id="masterPassword" type="{{showPassword ? 'text' : 'password'}}" name="MasterPassword"
class="monospaced" [(ngModel)]="masterPassword" required appAutofocus>
</div>
<div class="action-buttons">
<a class="row-btn" href="#" appStopClick appBlurClick role="button"
appA11yTitle="{{'toggleVisibility' | i18n}}" (click)="togglePassword()">
<i class="fa fa-lg" aria-hidden="true"
[ngClass]="{'fa-eye': !showPassword, 'fa-eye-slash': showPassword}"></i>
</a>
</div>
</div>
</div>
<div class="box-footer">
{{'loggedInAsOn' | i18n : email : webVaultHostname}}
</div>
</div>
<div class="buttons with-rows">
<div class="buttons-row">
<button type="submit" class="btn primary block" appBlurClick>
<i class="fa fa-unlock-alt" aria-hidden="true"></i> <b>{{'unlock' | i18n}}</b>
</button>
<button type="button" class="btn block" appBlurClick (click)="logOut()">
{{'logOut' | i18n}}
</button>
</div>
<div class="buttons-row" *ngIf="supportsBiometric && biometricLock">
<a class="btn block" appBlurClick (click)="unlockBiometric()">
{{biometricText | i18n}}
</a>
</div>
<div class="content">
<p aria-hidden="true"><i class="bwi bwi-lock bwi-4x text-muted"></i></p>
<p>{{ "yourVaultIsLocked" | i18n }}</p>
<div class="box last">
<div class="box-content">
<div class="box-content-row box-content-row-flex" appBoxRow *ngIf="!hideInput">
<div class="row-main" *ngIf="pinLock">
<label for="pin">{{ "pin" | i18n }}</label>
<input
id="pin"
type="{{ showPassword ? 'text' : 'password' }}"
name="PIN"
class="monospaced"
[(ngModel)]="pin"
required
appInputVerbatim
/>
</div>
<div class="row-main" *ngIf="!pinLock">
<label for="masterPassword">{{ "masterPass" | i18n }}</label>
<input
id="masterPassword"
type="{{ showPassword ? 'text' : 'password' }}"
name="MasterPassword"
class="monospaced"
[(ngModel)]="masterPassword"
required
appInputVerbatim
/>
</div>
<div class="action-buttons">
<button
type="button"
class="row-btn"
appStopClick
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
[attr.aria-pressed]="showPassword"
(click)="togglePassword()"
>
<i
class="bwi bwi-lg"
aria-hidden="true"
[ngClass]="{ 'bwi-eye': !showPassword, 'bwi-eye-slash': showPassword }"
></i>
</button>
</div>
</div>
</div>
<div class="box-footer">
{{ "loggedInAsOn" | i18n: email:webVaultHostname }}
</div>
</div>
<div class="buttons with-rows">
<div class="buttons-row" *ngIf="supportsBiometric && biometricLock">
<button
type="button"
class="btn block"
[ngClass]="{ 'primary font-weight-bold': hideInput }"
(click)="unlockBiometric()"
>
{{ biometricText | i18n }}
</button>
</div>
<div class="buttons-row">
<button type="submit" class="btn primary block" *ngIf="!hideInput">
<i class="bwi bwi-unlock" aria-hidden="true"></i> <b>{{ "unlock" | i18n }}</b>
</button>
<button type="button" class="btn block" (click)="logOut()">
{{ "logOut" | i18n }}
</button>
</div>
</div>
</div>
</form>

View File

@ -1,70 +1,107 @@
import {
Component,
NgZone,
OnDestroy,
} from '@angular/core';
import {
ActivatedRoute,
Router,
} from '@angular/router';
import { Component, NgZone, OnDestroy } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { ipcRenderer } from "electron";
import { ApiService } from 'jslib/abstractions/api.service';
import { CryptoService } from 'jslib/abstractions/crypto.service';
import { EnvironmentService } from 'jslib/abstractions/environment.service';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { MessagingService } from 'jslib/abstractions/messaging.service';
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
import { StateService } from 'jslib/abstractions/state.service';
import { StorageService } from 'jslib/abstractions/storage.service';
import { UserService } from 'jslib/abstractions/user.service';
import { VaultTimeoutService } from 'jslib/abstractions/vaultTimeout.service';
import { LockComponent as BaseLockComponent } from "jslib-angular/components/lock.component";
import { ApiService } from "jslib-common/abstractions/api.service";
import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service";
import { CryptoService } from "jslib-common/abstractions/crypto.service";
import { EnvironmentService } from "jslib-common/abstractions/environment.service";
import { I18nService } from "jslib-common/abstractions/i18n.service";
import { KeyConnectorService } from "jslib-common/abstractions/keyConnector.service";
import { LogService } from "jslib-common/abstractions/log.service";
import { MessagingService } from "jslib-common/abstractions/messaging.service";
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
import { StateService } from "jslib-common/abstractions/state.service";
import { VaultTimeoutService } from "jslib-common/abstractions/vaultTimeout.service";
import { BroadcasterService } from 'jslib/angular/services/broadcaster.service';
import { LockComponent as BaseLockComponent } from 'jslib/angular/components/lock.component';
const BroadcasterSubscriptionId = 'LockComponent';
const BroadcasterSubscriptionId = "LockComponent";
@Component({
selector: 'app-lock',
templateUrl: 'lock.component.html',
selector: "app-lock",
templateUrl: "lock.component.html",
})
export class LockComponent extends BaseLockComponent implements OnDestroy {
constructor(router: Router, i18nService: I18nService,
platformUtilsService: PlatformUtilsService, messagingService: MessagingService,
userService: UserService, cryptoService: CryptoService,
storageService: StorageService, vaultTimeoutService: VaultTimeoutService,
environmentService: EnvironmentService, stateService: StateService,
apiService: ApiService, private route: ActivatedRoute,
private broadcasterService: BroadcasterService, private ngZone: NgZone) {
super(router, i18nService, platformUtilsService, messagingService, userService, cryptoService,
storageService, vaultTimeoutService, environmentService, stateService, apiService);
}
private deferFocus: boolean = null;
async ngOnInit() {
await super.ngOnInit();
this.route.queryParams.subscribe(params => {
if (this.supportsBiometric && params.promptBiometric) {
setTimeout(() => this.unlockBiometric(), 1000);
constructor(
router: Router,
i18nService: I18nService,
platformUtilsService: PlatformUtilsService,
messagingService: MessagingService,
cryptoService: CryptoService,
vaultTimeoutService: VaultTimeoutService,
environmentService: EnvironmentService,
stateService: StateService,
apiService: ApiService,
private route: ActivatedRoute,
private broadcasterService: BroadcasterService,
ngZone: NgZone,
logService: LogService,
keyConnectorService: KeyConnectorService
) {
super(
router,
i18nService,
platformUtilsService,
messagingService,
cryptoService,
vaultTimeoutService,
environmentService,
stateService,
apiService,
logService,
keyConnectorService,
ngZone
);
}
async ngOnInit() {
await super.ngOnInit();
const autoPromptBiometric = !(await this.stateService.getNoAutoPromptBiometrics());
this.route.queryParams.subscribe((params) => {
if (this.supportsBiometric && params.promptBiometric && autoPromptBiometric) {
setTimeout(async () => {
if (await ipcRenderer.invoke("windowVisible")) {
this.unlockBiometric();
}
}, 1000);
}
});
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
this.ngZone.run(() => {
switch (message.command) {
case "windowHidden":
this.onWindowHidden();
break;
case "windowIsFocused":
if (this.deferFocus === null) {
this.deferFocus = !message.windowIsFocused;
if (!this.deferFocus) {
this.focusInput();
}
} else if (this.deferFocus && message.windowIsFocused) {
this.focusInput();
this.deferFocus = false;
}
});
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
this.ngZone.run(() => {
switch (message.command) {
case 'windowHidden':
this.onWindowHidden();
break;
default:
}
});
});
}
break;
default:
}
});
});
this.messagingService.send("getWindowIsFocused");
}
ngOnDestroy() {
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
}
ngOnDestroy() {
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
}
onWindowHidden() {
this.showPassword = false;
}
onWindowHidden() {
this.showPassword = false;
}
private focusInput() {
document.getElementById(this.pinLock ? "pin" : "masterPassword").focus();
}
}

View File

@ -1,53 +1,104 @@
<form id="login-page" #form (ngSubmit)="submit()" [appApiAction]="formPromise" attr.aria-hidden="{{showingModal}}">
<div class="content">
<img class="logo-image" alt="Bitwarden">
<p class="lead">{{'loginOrCreateNewAccount' | i18n}}</p>
<div class="box last">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<label for="email">{{'emailAddress' | i18n}}</label>
<input id="email" type="text" name="Email" [(ngModel)]="email" required>
</div>
<div class="box-content-row box-content-row-flex" appBoxRow>
<div class="row-main">
<label for="masterPassword">{{'masterPass' | i18n}}</label>
<input id="masterPassword" type="{{showPassword ? 'text' : 'password'}}" name="MasterPassword"
class="monospaced" [(ngModel)]="masterPassword" required>
</div>
<div class="action-buttons">
<a class="row-btn" href="#" appStopClick appBlurClick role="button"
appA11yTitle="{{'toggleVisibility' | i18n}}" (click)="togglePassword()">
<i class="fa fa-lg" aria-hidden="true"
[ngClass]="{'fa-eye': !showPassword, 'fa-eye-slash': showPassword}"></i>
</a>
</div>
</div>
<div id="login-page">
<div class="login-header">
<button
type="button"
appStopClick
(click)="settings()"
class="environment-urls-settings-icon"
attr.aria-label="{{ 'settings' | i18n }}"
>
<i class="bwi bwi-cog bwi-lg" aria-hidden="true"></i>
{{ "settings" | i18n }}
</button>
</div>
<form
id="login-page"
#form
(ngSubmit)="submit()"
[appApiAction]="formPromise"
attr.aria-hidden="{{ showingModal }}"
>
<div id="content" class="content">
<img class="logo-image" alt="Bitwarden" />
<p class="lead">{{ "loginOrCreateNewAccount" | i18n }}</p>
<div class="box last">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<label for="email">{{ "emailAddress" | i18n }}</label>
<input
id="email"
type="text"
name="Email"
[(ngModel)]="email"
required
appInputVerbatim="false"
/>
</div>
<div class="box-content-row box-content-row-flex" appBoxRow>
<div class="row-main">
<label for="masterPassword">{{ "masterPass" | i18n }}</label>
<input
id="masterPassword"
type="{{ showPassword ? 'text' : 'password' }}"
name="MasterPassword"
class="monospaced"
[(ngModel)]="masterPassword"
required
appInputVerbatim
/>
</div>
</div>
<div class="buttons with-rows">
<div class="buttons-row">
<button type="submit" class="btn primary block" [disabled]="form.loading" appBlurClick>
<b [hidden]="form.loading"><i class="fa fa-sign-in" aria-hidden="true"></i> {{'logIn' | i18n}}</b>
<i class="fa fa-spinner fa-spin" [hidden]="!form.loading" aria-hidden="true"></i>
</button>
<a routerLink="/register" class="btn block">
<i class="fa fa-pencil-square-o" aria-hidden="true"></i> {{'createAccount' | i18n}}
</a>
</div>
<div class="buttons-row">
<a (click)="launchSsoBrowser('desktop', 'bitwarden://sso-callback')" class="btn block">
<i class="fa fa-bank" aria-hidden="true"></i> {{'enterpriseSingleSignOn' | i18n}}
</a>
<div class="action-buttons">
<button
type="button"
class="row-btn"
appStopClick
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
[attr.aria-pressed]="showPassword"
(click)="togglePassword()"
>
<i
class="bwi bwi-lg"
aria-hidden="true"
[ngClass]="{ 'bwi-eye': !showPassword, 'bwi-eye-slash': showPassword }"
></i>
</button>
</div>
</div>
</div>
<div class="sub-options">
<a routerLink="/hint">{{'getMasterPasswordHint' | i18n}}</a>
</div>
<div class="box last" [hidden]="!showCaptcha()">
<div class="box-content">
<div class="box-content-row">
<iframe id="hcaptcha_iframe" height="80"></iframe>
</div>
</div>
<a href="#" appStopClick (click)="settings()" class="settings-icon" attr.aria-label="{{'settings' | i18n}}">
<i class="fa fa-cog fa-lg" aria-hidden="true"></i><span
aria-hidden="true">&nbsp;{{'settings' | i18n}}</span>
</a>
</div>
<div class="buttons with-rows">
<div class="buttons-row">
<button type="submit" class="btn primary block" [disabled]="form.loading">
<b [hidden]="form.loading"
><i class="bwi bwi-sign-in" aria-hidden="true"></i> {{ "logIn" | i18n }}</b
>
<i class="bwi bwi-spinner bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
</button>
<button type="button" routerLink="/register" class="btn block">
<i class="bwi bwi-pencil-square" aria-hidden="true"></i> {{ "createAccount" | i18n }}
</button>
</div>
<div class="buttons-row">
<button
type="button"
(click)="launchSsoBrowser('desktop', 'bitwarden://sso-callback')"
class="btn block"
>
<i class="bwi bwi-bank" aria-hidden="true"></i> {{ "enterpriseSingleSignOn" | i18n }}
</button>
</div>
</div>
<div class="sub-options">
<button type="button" routerLink="/hint">{{ "getMasterPasswordHint" | i18n }}</button>
</div>
</div>
</form>
</form>
</div>
<ng-template #environment></ng-template>

View File

@ -1,93 +1,128 @@
import {
Component,
ComponentFactoryResolver,
NgZone,
OnDestroy,
ViewChild,
ViewContainerRef,
} from '@angular/core';
import { Component, NgZone, OnDestroy, ViewChild, ViewContainerRef } from "@angular/core";
import { Router } from "@angular/router";
import { Router } from '@angular/router';
import { LoginComponent as BaseLoginComponent } from "jslib-angular/components/login.component";
import { ModalService } from "jslib-angular/services/modal.service";
import { AuthService } from "jslib-common/abstractions/auth.service";
import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service";
import { CryptoFunctionService } from "jslib-common/abstractions/cryptoFunction.service";
import { EnvironmentService } from "jslib-common/abstractions/environment.service";
import { I18nService } from "jslib-common/abstractions/i18n.service";
import { LogService } from "jslib-common/abstractions/log.service";
import { MessagingService } from "jslib-common/abstractions/messaging.service";
import { PasswordGenerationService } from "jslib-common/abstractions/passwordGeneration.service";
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
import { StateService } from "jslib-common/abstractions/state.service";
import { SyncService } from "jslib-common/abstractions/sync.service";
import { EnvironmentComponent } from './environment.component';
import { EnvironmentComponent } from "./environment.component";
import { AuthService } from 'jslib/abstractions/auth.service';
import { CryptoFunctionService } from 'jslib/abstractions/cryptoFunction.service';
import { EnvironmentService } from 'jslib/abstractions/environment.service';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { PasswordGenerationService } from 'jslib/abstractions/passwordGeneration.service';
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
import { StateService } from 'jslib/abstractions/state.service';
import { StorageService } from 'jslib/abstractions/storage.service';
import { SyncService } from 'jslib/abstractions/sync.service';
import { BroadcasterService } from 'jslib/angular/services/broadcaster.service';
import { LoginComponent as BaseLoginComponent } from 'jslib/angular/components/login.component';
import { ModalComponent } from 'jslib/angular/components/modal.component';
const BroadcasterSubscriptionId = 'LoginComponent';
const BroadcasterSubscriptionId = "LoginComponent";
@Component({
selector: 'app-login',
templateUrl: 'login.component.html',
selector: "app-login",
templateUrl: "login.component.html",
})
export class LoginComponent extends BaseLoginComponent implements OnDestroy {
@ViewChild('environment', { read: ViewContainerRef, static: true }) environmentModal: ViewContainerRef;
@ViewChild("environment", { read: ViewContainerRef, static: true })
environmentModal: ViewContainerRef;
showingModal = false;
showingModal = false;
constructor(authService: AuthService, router: Router, i18nService: I18nService,
syncService: SyncService, private componentFactoryResolver: ComponentFactoryResolver,
platformUtilsService: PlatformUtilsService, stateService: StateService,
environmentService: EnvironmentService, passwordGenerationService: PasswordGenerationService,
cryptoFunctionService: CryptoFunctionService, storageService: StorageService,
private broadcasterService: BroadcasterService, private ngZone: NgZone) {
super(authService, router, platformUtilsService, i18nService, stateService, environmentService,
passwordGenerationService, cryptoFunctionService, storageService);
super.onSuccessfulLogin = () => {
return syncService.fullSync(true);
};
}
async ngOnInit() {
await super.ngOnInit();
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
this.ngZone.run(() => {
switch (message.command) {
case 'windowHidden':
this.onWindowHidden();
break;
default:
}
});
});
}
ngOnDestroy() {
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
}
settings() {
const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent);
const modal = this.environmentModal.createComponent(factory).instance;
modal.onShown.subscribe(() => {
this.showingModal = true;
});
modal.onClosed.subscribe(() => {
this.showingModal = false;
modal.onShown.unsubscribe();
modal.onClosed.unsubscribe();
});
const childComponent = modal.show<EnvironmentComponent>(EnvironmentComponent,
this.environmentModal);
childComponent.onSaved.subscribe(() => {
modal.close();
});
}
onWindowHidden() {
this.showPassword = false;
protected alwaysRememberEmail = true;
private deferFocus: boolean = null;
constructor(
authService: AuthService,
router: Router,
i18nService: I18nService,
syncService: SyncService,
private modalService: ModalService,
platformUtilsService: PlatformUtilsService,
stateService: StateService,
environmentService: EnvironmentService,
passwordGenerationService: PasswordGenerationService,
cryptoFunctionService: CryptoFunctionService,
private broadcasterService: BroadcasterService,
ngZone: NgZone,
private messagingService: MessagingService,
logService: LogService
) {
super(
authService,
router,
platformUtilsService,
i18nService,
stateService,
environmentService,
passwordGenerationService,
cryptoFunctionService,
logService,
ngZone
);
super.onSuccessfulLogin = () => {
return syncService.fullSync(true);
};
}
async ngOnInit() {
await super.ngOnInit();
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
this.ngZone.run(() => {
switch (message.command) {
case "windowHidden":
this.onWindowHidden();
break;
case "windowIsFocused":
if (this.deferFocus === null) {
this.deferFocus = !message.windowIsFocused;
if (!this.deferFocus) {
this.focusInput();
}
} else if (this.deferFocus && message.windowIsFocused) {
this.focusInput();
this.deferFocus = false;
}
break;
default:
}
});
});
this.messagingService.send("getWindowIsFocused");
}
ngOnDestroy() {
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
}
async settings() {
const [modal, childComponent] = await this.modalService.openViewRef(
EnvironmentComponent,
this.environmentModal
);
modal.onShown.subscribe(() => {
this.showingModal = true;
});
modal.onClosed.subscribe(() => {
this.showingModal = false;
});
childComponent.onSaved.subscribe(() => {
modal.close();
});
}
onWindowHidden() {
this.showPassword = false;
}
async submit() {
await super.submit();
if (this.captchaSiteKey) {
const content = document.getElementById("content") as HTMLDivElement;
content.setAttribute("style", "width:335px");
}
}
}

View File

@ -1,70 +1,89 @@
<div class="modal fade" tabindex="-1" role="dialog" aria-modal="true" aria-labelledby="premiumTitle">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<div class="box">
<div class="box-header" id="premiumTitle">
{{'premiumMembership' | i18n}}
</div>
<div class="box-content box-content-padded">
<div *ngIf="!isPremium">
<p class="text-center lead">{{'premiumNotCurrentMember' | i18n}}</p>
<p>{{'premiumSignUpAndGet' | i18n}}</p>
<ul class="fa-ul">
<li>
<i class="fa-li fa fa-check text-success" aria-hidden="true"></i>
{{'premiumSignUpStorage' | i18n}}
</li>
<li>
<i class="fa-li fa fa-check text-success" aria-hidden="true"></i>
{{'premiumSignUpTwoStep' | i18n}}
</li>
<li>
<i class="fa-li fa fa-check text-success" aria-hidden="true"></i>
{{'premiumSignUpReports' | i18n}}
</li>
<li>
<i class="fa-li fa fa-check text-success" aria-hidden="true"></i>
{{'premiumSignUpTotp' | i18n}}
</li>
<li>
<i class="fa-li fa fa-check text-success" aria-hidden="true"></i>
{{'premiumSignUpSupport' | i18n}}
</li>
<li>
<i class="fa-li fa fa-check text-success" aria-hidden="true"></i>
{{'premiumSignUpFuture' | i18n}}
</li>
</ul>
<p class="text-center lead no-margin">
{{'premiumPrice' | i18n : (price | currency:'$')}}
</p>
</div>
<div *ngIf="isPremium">
<p class="text-center lead">{{'premiumCurrentMember' | i18n}}</p>
<p class="text-center">{{'premiumCurrentMemberThanks' | i18n}}</p>
</div>
</div>
</div>
<div class="modal fade" role="dialog" aria-modal="true" aria-labelledby="premiumTitle">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<div class="box">
<div class="box-header" id="premiumTitle">
{{ "premiumMembership" | i18n }}
</div>
<div class="box-content box-content-padded">
<div *ngIf="!isPremium">
<p class="text-center lead">{{ "premiumNotCurrentMember" | i18n }}</p>
<p>{{ "premiumSignUpAndGet" | i18n }}</p>
<ul class="bwi-ul">
<li>
<i class="bwi bwi-li bwi-check text-success" aria-hidden="true"></i>
{{ "premiumSignUpStorage" | i18n }}
</li>
<li>
<i class="bwi bwi-li bwi-check text-success" aria-hidden="true"></i>
{{ "premiumSignUpTwoStep" | i18n }}
</li>
<li>
<i class="bwi bwi-li bwi-check text-success" aria-hidden="true"></i>
{{ "premiumSignUpReports" | i18n }}
</li>
<li>
<i class="bwi bwi-li bwi-check text-success" aria-hidden="true"></i>
{{ "premiumSignUpTotp" | i18n }}
</li>
<li>
<i class="bwi bwi-li bwi-check text-success" aria-hidden="true"></i>
{{ "premiumSignUpSupport" | i18n }}
</li>
<li>
<i class="bwi bwi-li bwi-check text-success" aria-hidden="true"></i>
{{ "premiumSignUpFuture" | i18n }}
</li>
</ul>
<p class="text-center lead no-margin">
{{ "premiumPrice" | i18n: (price | currency: "$") }}
</p>
</div>
<div class="modal-footer">
<button type="button" class="primary" appBlurClick (click)="manage()" *ngIf="isPremium">
<b>{{'premiumManage' | i18n}}</b>
</button>
<button #purchaseBtn type="button" class="primary" appBlurClick (click)="purchase()" *ngIf="!isPremium"
[disabled]="purchaseBtn.loading">
<b>{{'premiumPurchase' | i18n}}</b>
</button>
<button type="button" data-dismiss="modal">{{'close' | i18n}}</button>
<div class="right" *ngIf="!isPremium">
<button #refreshBtn type="button" appBlurClick (click)="refresh()" [disabled]="refreshBtn.loading"
appA11yTitle="{{'premiumRefresh' | i18n}}" [appApiAction]="refreshPromise">
<i class="fa fa-refresh fa-lg fa-fw" [hidden]="refreshBtn.loading" aria-hidden="true"></i>
<i class="fa fa-spinner fa-spin fa-lg fa-fw" [hidden]="!refreshBtn.loading"
aria-hidden="true"></i>
</button>
</div>
<div *ngIf="isPremium">
<p class="text-center lead">{{ "premiumCurrentMember" | i18n }}</p>
<p class="text-center">{{ "premiumCurrentMemberThanks" | i18n }}</p>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="primary" (click)="manage()" *ngIf="isPremium">
<b>{{ "premiumManage" | i18n }}</b>
</button>
<button
#purchaseBtn
type="button"
class="primary"
(click)="purchase()"
*ngIf="!isPremium"
[disabled]="purchaseBtn.loading"
>
<b>{{ "premiumPurchase" | i18n }}</b>
</button>
<button type="button" data-dismiss="modal">{{ "close" | i18n }}</button>
<div class="right" *ngIf="!isPremium">
<button
#refreshBtn
type="button"
(click)="refresh()"
[disabled]="refreshBtn.loading"
appA11yTitle="{{ 'premiumRefresh' | i18n }}"
[appApiAction]="refreshPromise"
>
<i
class="bwi bwi-refresh bwi-lg bwi-fw"
[hidden]="refreshBtn.loading"
aria-hidden="true"
></i>
<i
class="bwi bwi-spinner bwi-spin bwi-lg bwi-fw"
[hidden]="!refreshBtn.loading"
aria-hidden="true"
></i>
</button>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,26 +1,24 @@
import {
Component,
NgZone,
} from '@angular/core';
import { Component } from "@angular/core";
import { ApiService } from 'jslib/abstractions/api.service';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { MessagingService } from 'jslib/abstractions/messaging.service';
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
import { SyncService } from 'jslib/abstractions/sync.service';
import { UserService } from 'jslib/abstractions/user.service';
import { PremiumComponent as BasePremiumComponent } from 'jslib/angular/components/premium.component';
import { PremiumComponent as BasePremiumComponent } from "jslib-angular/components/premium.component";
import { ApiService } from "jslib-common/abstractions/api.service";
import { I18nService } from "jslib-common/abstractions/i18n.service";
import { LogService } from "jslib-common/abstractions/log.service";
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
import { StateService } from "jslib-common/abstractions/state.service";
@Component({
selector: 'app-premium',
templateUrl: 'premium.component.html',
selector: "app-premium",
templateUrl: "premium.component.html",
})
export class PremiumComponent extends BasePremiumComponent {
constructor(i18nService: I18nService, platformUtilsService: PlatformUtilsService,
apiService: ApiService, userService: UserService,
private ngZone: NgZone, private messagingService: MessagingService,
private syncService: SyncService) {
super(i18nService, platformUtilsService, apiService, userService);
}
constructor(
i18nService: I18nService,
platformUtilsService: PlatformUtilsService,
apiService: ApiService,
logService: LogService,
stateService: StateService
) {
super(i18nService, platformUtilsService, apiService, logService, stateService);
}
}

View File

@ -1,89 +1,148 @@
<form id="register-page" #form (ngSubmit)="submit()" [appApiAction]="formPromise">
<div class="content">
<h1>{{'createAccount' | i18n}}</h1>
<div class="box">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<label for="email">{{'emailAddress' | i18n}}</label>
<input id="email" type="text" name="Email" [(ngModel)]="email" required
[appAutofocus]="email === ''">
</div>
<div class="box-content-row" appBoxRow>
<div class="box-content-row-flex">
<div class="row-main">
<label for="masterPassword">
{{'masterPass' | i18n}}
<strong class="sub-label text-{{masterPasswordScoreColor}}"
*ngIf="masterPasswordScoreText">
{{masterPasswordScoreText}}
</strong>
</label>
<input id="masterPassword" type="{{showPassword ? 'text' : 'password'}}"
name="MasterPassword" class="monospaced" [(ngModel)]="masterPassword" required
[appAutofocus]="email !== ''" (input)="updatePasswordStrength()">
</div>
<div class="action-buttons">
<a class="row-btn" href="#" appStopClick appBlurClick role="button"
appA11yTitle="{{'toggleVisibility' | i18n}}" (click)="togglePassword(false)">
<i class="fa fa-lg" aria-hidden="true"
[ngClass]="{'fa-eye': !showPassword, 'fa-eye-slash': showPassword}"></i>
</a>
</div>
</div>
<div class="progress">
<div class="progress-bar bg-{{masterPasswordScoreColor}}" role="progressbar" aria-valuenow="0"
aria-valuemin="0" aria-valuemax="100" [ngStyle]="{width: (masterPasswordScoreWidth + '%')}"
attr.aria-valuenow="{{masterPasswordScoreWidth}}"></div>
</div>
</div>
</div>
<div class="box-footer">
{{'masterPassDesc' | i18n}}
</div>
<div class="content">
<h1>{{ "createAccount" | i18n }}</h1>
<div class="box">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<label for="email">{{ "emailAddress" | i18n }}</label>
<input
id="email"
type="text"
name="Email"
[(ngModel)]="email"
required
[appAutofocus]="email === ''"
appInputVerbatim
/>
</div>
<div class="box">
<div class="box-content">
<div class="box-content-row box-content-row-flex" appBoxRow>
<div class="row-main">
<label for="masterPasswordRetype">{{'reTypeMasterPass' | i18n}}</label>
<input id="masterPasswordRetype" type="{{showPassword ? 'text' : 'password'}}"
name="MasterPasswordRetype" class="monospaced" [(ngModel)]="confirmMasterPassword" required>
</div>
<div class="action-buttons">
<a class="row-btn" href="#" appStopClick appBlurClick role="button"
appA11yTitle="{{'toggleVisibility' | i18n}}" (click)="togglePassword(true)">
<i class="fa fa-lg" aria-hidden="true"
[ngClass]="{'fa-eye': !showPassword, 'fa-eye-slash': showPassword}"></i>
</a>
</div>
</div>
<div class="box-content-row" appBoxRow>
<label for="hint">{{'masterPassHint' | i18n}}</label>
<input id="hint" type="text" name="Hint" [(ngModel)]="hint">
</div>
<div class="box-content-row" appBoxRow>
<div class="box-content-row-flex">
<div class="row-main">
<label for="masterPassword">
{{ "masterPass" | i18n }}
<strong
class="sub-label text-{{ masterPasswordScoreColor }}"
*ngIf="masterPasswordScoreText"
>
{{ masterPasswordScoreText }}
</strong>
</label>
<input
id="masterPassword"
type="{{ showPassword ? 'text' : 'password' }}"
name="MasterPassword"
class="monospaced"
[(ngModel)]="masterPassword"
required
[appAutofocus]="email !== ''"
(input)="updatePasswordStrength()"
appInputVerbatim
/>
</div>
<div class="box-footer">
{{'masterPassHintDesc' | i18n}}
<div class="action-buttons">
<button
type="button"
class="row-btn"
appStopClick
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
[attr.aria-pressed]="showPassword"
(click)="togglePassword(false)"
>
<i
class="bwi bwi-lg"
aria-hidden="true"
[ngClass]="{ 'bwi-eye': !showPassword, 'bwi-eye-slash': showPassword }"
></i>
</button>
</div>
</div>
<div class="progress">
<div
class="progress-bar bg-{{ masterPasswordScoreColor }}"
role="progressbar"
aria-valuenow="0"
aria-valuemin="0"
aria-valuemax="100"
[ngStyle]="{ width: masterPasswordScoreWidth + '%' }"
attr.aria-valuenow="{{ masterPasswordScoreWidth }}"
></div>
</div>
</div>
<div class="box last" *ngIf="showTerms">
<div class="box-footer checkbox">
<input type="checkbox" id="acceptPolicies" [(ngModel)]="acceptPolicies" name="AcceptPolicies">
<label for="acceptPolicies">
{{'acceptPolicies' | i18n}}<br>
<a href="https://bitwarden.com/terms/" target="_blank"
rel="noopener">{{'termsOfService' | i18n}}</a>,
<a href="https://bitwarden.com/privacy/" target="_blank"
rel="noopener">{{'privacyPolicy' | i18n}}</a>
</label>
</div>
</div>
<div class="buttons">
<button type="submit" class="btn primary block" [disabled]="form.loading" appBlurClick>
<b [hidden]="form.loading">{{'submit' | i18n}}</b>
<i class="fa fa-spinner fa-spin" [hidden]="!form.loading" aria-hidden="true"></i>
</button>
<a routerLink="/login" class="btn block">{{'cancel' | i18n}}</a>
</div>
</div>
<div class="box-footer">
{{ "masterPassDesc" | i18n }}
</div>
</div>
<div class="box">
<div class="box-content">
<div class="box-content-row box-content-row-flex" appBoxRow>
<div class="row-main">
<label for="masterPasswordRetype">{{ "reTypeMasterPass" | i18n }}</label>
<input
id="masterPasswordRetype"
type="{{ showPassword ? 'text' : 'password' }}"
name="MasterPasswordRetype"
class="monospaced"
[(ngModel)]="confirmMasterPassword"
required
appInputVerbatim
/>
</div>
<div class="action-buttons">
<button
type="button"
class="row-btn"
appStopClick
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
[attr.aria-pressed]="showPassword"
(click)="togglePassword(true)"
>
<i
class="bwi bwi-lg"
aria-hidden="true"
[ngClass]="{ 'bwi-eye': !showPassword, 'bwi-eye-slash': showPassword }"
></i>
</button>
</div>
</div>
<div class="box-content-row" appBoxRow>
<label for="hint">{{ "masterPassHint" | i18n }}</label>
<input id="hint" type="text" name="Hint" [(ngModel)]="hint" />
</div>
<div class="box-content-row" [hidden]="!showCaptcha()">
<iframe id="hcaptcha_iframe" height="80"></iframe>
</div>
</div>
<div class="box-footer">
{{ "masterPassHintDesc" | i18n }}
</div>
</div>
<div class="box last" *ngIf="showTerms">
<div class="box-footer checkbox">
<input
type="checkbox"
id="acceptPolicies"
[(ngModel)]="acceptPolicies"
name="AcceptPolicies"
/>
<label for="acceptPolicies">
{{ "acceptPolicies" | i18n }}<br />
<a href="https://bitwarden.com/terms/" target="_blank" rel="noopener">{{
"termsOfService" | i18n
}}</a
>,
<a href="https://bitwarden.com/privacy/" target="_blank" rel="noopener">{{
"privacyPolicy" | i18n
}}</a>
</label>
</div>
</div>
<div class="buttons">
<button type="submit" class="btn primary block" [disabled]="form.loading">
<b [hidden]="form.loading">{{ "submit" | i18n }}</b>
<i class="bwi bwi-spinner bwi-spin" [hidden]="!form.loading" aria-hidden="true"></i>
</button>
<button type="button" routerLink="/login" class="btn block">{{ "cancel" | i18n }}</button>
</div>
</div>
</form>

View File

@ -1,57 +1,73 @@
import {
Component,
NgZone,
OnDestroy,
OnInit,
} from '@angular/core';
import { Router } from '@angular/router';
import { Component, NgZone, OnDestroy, OnInit } from "@angular/core";
import { Router } from "@angular/router";
import { ApiService } from 'jslib/abstractions/api.service';
import { AuthService } from 'jslib/abstractions/auth.service';
import { CryptoService } from 'jslib/abstractions/crypto.service';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { PasswordGenerationService } from 'jslib/abstractions/passwordGeneration.service';
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
import { StateService } from 'jslib/abstractions/state.service';
import { RegisterComponent as BaseRegisterComponent } from "jslib-angular/components/register.component";
import { ApiService } from "jslib-common/abstractions/api.service";
import { AuthService } from "jslib-common/abstractions/auth.service";
import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service";
import { CryptoService } from "jslib-common/abstractions/crypto.service";
import { EnvironmentService } from "jslib-common/abstractions/environment.service";
import { I18nService } from "jslib-common/abstractions/i18n.service";
import { LogService } from "jslib-common/abstractions/log.service";
import { PasswordGenerationService } from "jslib-common/abstractions/passwordGeneration.service";
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
import { StateService } from "jslib-common/abstractions/state.service";
import { BroadcasterService } from 'jslib/angular/services/broadcaster.service';
import { RegisterComponent as BaseRegisterComponent } from 'jslib/angular/components/register.component';
const BroadcasterSubscriptionId = 'RegisterComponent';
const BroadcasterSubscriptionId = "RegisterComponent";
@Component({
selector: 'app-register',
templateUrl: 'register.component.html',
selector: "app-register",
templateUrl: "register.component.html",
})
export class RegisterComponent extends BaseRegisterComponent implements OnInit, OnDestroy {
constructor(authService: AuthService, router: Router,
i18nService: I18nService, cryptoService: CryptoService,
apiService: ApiService, stateService: StateService,
platformUtilsService: PlatformUtilsService, passwordGenerationService: PasswordGenerationService,
private broadcasterService: BroadcasterService, private ngZone: NgZone) {
super(authService, router, i18nService, cryptoService, apiService, stateService, platformUtilsService,
passwordGenerationService);
}
constructor(
authService: AuthService,
router: Router,
i18nService: I18nService,
cryptoService: CryptoService,
apiService: ApiService,
stateService: StateService,
platformUtilsService: PlatformUtilsService,
passwordGenerationService: PasswordGenerationService,
environmentService: EnvironmentService,
private broadcasterService: BroadcasterService,
private ngZone: NgZone,
logService: LogService
) {
super(
authService,
router,
i18nService,
cryptoService,
apiService,
stateService,
platformUtilsService,
passwordGenerationService,
environmentService,
logService
);
}
async ngOnInit() {
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
this.ngZone.run(() => {
switch (message.command) {
case 'windowHidden':
this.onWindowHidden();
break;
default:
}
});
});
}
async ngOnInit() {
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
this.ngZone.run(() => {
switch (message.command) {
case "windowHidden":
this.onWindowHidden();
break;
default:
}
});
});
ngOnDestroy() {
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
}
super.ngOnInit();
}
onWindowHidden() {
this.showPassword = false;
}
ngOnDestroy() {
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
}
onWindowHidden() {
this.showPassword = false;
}
}

View File

@ -0,0 +1,26 @@
<div id="remove-password-page" *ngIf="!loading">
<div class="content">
<h1>{{ "removeMasterPassword" | i18n }}</h1>
<p>{{ "convertOrganizationEncryptionDesc" | i18n: organization.name }}</p>
<div class="buttons">
<button
type="submit"
class="btn primary block"
[disabled]="actionPromise"
(click)="convert()"
>
<b [hidden]="continuing">{{ "removeMasterPassword" | i18n }}</b>
<i class="bwi bwi-spinner bwi-spin" [hidden]="!continuing" aria-hidden="true"></i>
</button>
<button
type="button"
class="btn secondary block"
[disabled]="actionPromise"
(click)="leave()"
>
<b [hidden]="leaving">{{ "leaveOrganization" | i18n }}</b>
<i class="bwi bwi-spinner bwi-spin" [hidden]="!leaving" aria-hidden="true"></i>
</button>
</div>
</div>
</div>

View File

@ -0,0 +1,9 @@
import { Component } from "@angular/core";
import { RemovePasswordComponent as BaseRemovePasswordComponent } from "jslib-angular/components/remove-password.component";
@Component({
selector: "app-remove-password",
templateUrl: "remove-password.component.html",
})
export class RemovePasswordComponent extends BaseRemovePasswordComponent {}

View File

@ -1,112 +1,157 @@
<form id="set-password-page" #form>
<div class="content">
<img class="logo-image" alt="Bitwarden">
<p class="lead">{{'setMasterPassword' | i18n}}</p>
<div class="box text-center" *ngIf="syncLoading">
<i class="fa fa-spinner fa-spin" title="{{'loading' | i18n}}" aria-hidden="true"></i>
{{'loading' | i18n}}
</div>
<div *ngIf="!syncLoading">
<div class="box">
<app-callout type="tip">{{'ssoCompleteRegistration' | i18n}}</app-callout>
<app-callout type="info" *ngIf="enforcedPolicyOptions">
{{'masterPasswordPolicyInEffect' | i18n}}
<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>
</app-callout>
</div>
<form #form (ngSubmit)="submit()" [appApiAction]="formPromise" ngNativeValidate autocomplete="off">
<div class="box">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<div class="box-content-row-flex">
<div class="row-main">
<label for="masterPassword">{{'masterPass' | i18n}}
<strong class="sub-label text-{{masterPasswordScoreColor}}"
*ngIf="masterPasswordScoreText">
{{masterPasswordScoreText}}
</strong>
</label>
<input id="masterPassword" type="{{showPassword ? 'text' : 'password'}}"
name="MasterPassword" class="monospaced" [(ngModel)]="masterPassword" required
(input)="updatePasswordStrength()" appInputVerbatim>
</div>
<div class="action-buttons">
<a class="row-btn" href="#" appStopClick appBlurClick role="button"
appA11yTitle="{{'toggleVisibility' | i18n}}" (click)="togglePassword(false)">
<i class="fa fa-lg" aria-hidden="true"
[ngClass]="{'fa-eye': !showPassword, 'fa-eye-slash': showPassword}"></i>
</a>
</div>
</div>
<div class="progress">
<div class="progress-bar bg-{{masterPasswordScoreColor}}" role="progressbar"
aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"
[ngStyle]="{width: (masterPasswordScoreWidth + '%')}"
attr.aria-valuenow="{{masterPasswordScoreWidth}}">
</div>
</div>
</div>
</div>
<div class="box-footer">
{{'masterPassDesc' | i18n}}
</div>
</div>
<div class="box">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<div class="box-content-row-flex">
<div class="row-main">
<label for="masterPasswordRetype">{{'reTypeMasterPass' | i18n}}</label>
<input id="masterPasswordRetype" type="password" name="MasterPasswordRetype"
class="monospaced" [(ngModel)]="masterPasswordRetype" required appInputVerbatim
autocomplete="new-password">
</div>
<div class="action-buttons">
<a class="row-btn" href="#" appStopClick appBlurClick role="button"
appA11yTitle="{{'toggleVisibility' | i18n}}" (click)="togglePassword(true)">
<i class="fa fa-lg" aria-hidden="true"
[ngClass]="{'fa-eye': !showPassword, 'fa-eye-slash': showPassword}"></i>
</a>
</div>
</div>
</div>
</div>
</div>
<div class="box last">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<label for="hint">{{'masterPassHint' | i18n}}</label>
<input id="hint" type="text" name="Hint" [(ngModel)]="hint">
</div>
</div>
<div class="box-footer">
{{'masterPassHintDesc' | i18n}}
</div>
</div>
<div class="buttons">
<button type="submit" class="btn primary block" [disabled]="form.loading">
<i *ngIf="form.loading" class="fa fa-spinner fa-spin" title="{{'loading' | i18n}}"
aria-hidden="true"></i>
<span>{{'submit' | i18n}}</span>
</button>
<button class="btn block" (click)="logOut()">
<span>{{'logOut' | i18n}}</span>
</button>
</div>
</form>
</div>
<div class="content">
<img class="logo-image" alt="Bitwarden" />
<p class="lead">{{ "setMasterPassword" | i18n }}</p>
<div class="box text-center" *ngIf="syncLoading">
<i class="bwi bwi-spinner bwi-spin" title="{{ 'loading' | i18n }}" aria-hidden="true"></i>
{{ "loading" | i18n }}
</div>
<div *ngIf="!syncLoading">
<div class="box">
<app-callout type="tip">{{ "ssoCompleteRegistration" | i18n }}</app-callout>
<app-callout
type="warning"
title="{{ 'resetPasswordPolicyAutoEnroll' | i18n }}"
*ngIf="resetPasswordAutoEnroll"
>
{{ "resetPasswordAutoEnrollInviteWarning" | i18n }}
</app-callout>
<app-callout
type="info"
[enforcedPolicyOptions]="enforcedPolicyOptions"
*ngIf="enforcedPolicyOptions"
>
</app-callout>
</div>
<form
#form
(ngSubmit)="submit()"
[appApiAction]="formPromise"
ngNativeValidate
autocomplete="off"
>
<div class="box">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<div class="box-content-row-flex">
<div class="row-main">
<label for="masterPassword"
>{{ "masterPass" | i18n }}
<strong
class="sub-label text-{{ masterPasswordScoreColor }}"
*ngIf="masterPasswordScoreText"
>
{{ masterPasswordScoreText }}
</strong>
</label>
<input
id="masterPassword"
type="{{ showPassword ? 'text' : 'password' }}"
name="MasterPassword"
class="monospaced"
[(ngModel)]="masterPassword"
required
(input)="updatePasswordStrength()"
appInputVerbatim
/>
</div>
<div class="action-buttons">
<button
type="button"
class="row-btn"
appStopClick
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
[attr.aria-pressed]="showPassword"
(click)="togglePassword(false)"
>
<i
class="bwi bwi-lg"
aria-hidden="true"
[ngClass]="{ 'bwi-eye': !showPassword, 'bwi-eye-slash': showPassword }"
></i>
</button>
</div>
</div>
<div class="progress">
<div
class="progress-bar bg-{{ masterPasswordScoreColor }}"
role="progressbar"
aria-valuenow="0"
aria-valuemin="0"
aria-valuemax="100"
[ngStyle]="{ width: masterPasswordScoreWidth + '%' }"
attr.aria-valuenow="{{ masterPasswordScoreWidth }}"
></div>
</div>
</div>
</div>
<div class="box-footer">
{{ "masterPassDesc" | i18n }}
</div>
</div>
<div class="box">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<div class="box-content-row-flex">
<div class="row-main">
<label for="masterPasswordRetype">{{ "reTypeMasterPass" | i18n }}</label>
<input
id="masterPasswordRetype"
type="password"
name="MasterPasswordRetype"
class="monospaced"
[(ngModel)]="masterPasswordRetype"
required
appInputVerbatim
autocomplete="new-password"
/>
</div>
<div class="action-buttons">
<button
type="button"
class="row-btn"
appStopClick
appA11yTitle="{{ 'toggleVisibility' | i18n }}"
[attr.aria-pressed]="showPassword"
(click)="togglePassword(true)"
>
<i
class="bwi bwi-lg"
aria-hidden="true"
[ngClass]="{ 'bwi-eye': !showPassword, 'bwi-eye-slash': showPassword }"
></i>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="box last">
<div class="box-content">
<div class="box-content-row" appBoxRow>
<label for="hint">{{ "masterPassHint" | i18n }}</label>
<input id="hint" type="text" name="Hint" [(ngModel)]="hint" />
</div>
</div>
<div class="box-footer">
{{ "masterPassHintDesc" | i18n }}
</div>
</div>
<div class="buttons">
<button type="submit" class="btn primary block" [disabled]="form.loading">
<i
*ngIf="form.loading"
class="bwi bwi-spinner bwi-spin"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>
<span>{{ "submit" | i18n }}</span>
</button>
<button class="btn block" (click)="logOut()">
<span>{{ "logOut" | i18n }}</span>
</button>
</div>
</form>
</div>
</div>
</form>

View File

@ -1,96 +1,104 @@
import {
Component,
NgZone,
OnDestroy,
} from '@angular/core';
import { Component, NgZone, OnDestroy } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import {
ActivatedRoute,
Router,
} from '@angular/router';
import { SetPasswordComponent as BaseSetPasswordComponent } from "jslib-angular/components/set-password.component";
import { ApiService } from "jslib-common/abstractions/api.service";
import { BroadcasterService } from "jslib-common/abstractions/broadcaster.service";
import { CryptoService } from "jslib-common/abstractions/crypto.service";
import { I18nService } from "jslib-common/abstractions/i18n.service";
import { MessagingService } from "jslib-common/abstractions/messaging.service";
import { PasswordGenerationService } from "jslib-common/abstractions/passwordGeneration.service";
import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service";
import { PolicyService } from "jslib-common/abstractions/policy.service";
import { StateService } from "jslib-common/abstractions/state.service";
import { SyncService } from "jslib-common/abstractions/sync.service";
import { ApiService } from 'jslib/abstractions/api.service';
import { CryptoService } from 'jslib/abstractions/crypto.service';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { MessagingService } from 'jslib/abstractions/messaging.service';
import { PasswordGenerationService } from 'jslib/abstractions/passwordGeneration.service';
import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service';
import { PolicyService } from 'jslib/abstractions/policy.service';
import { SyncService } from 'jslib/abstractions/sync.service';
import { UserService } from 'jslib/abstractions/user.service';
import { BroadcasterService } from 'jslib/angular/services/broadcaster.service';
const BroadcasterSubscriptionId = 'SetPasswordComponent';
import {
SetPasswordComponent as BaseSetPasswordComponent,
} from 'jslib/angular/components/set-password.component';
const BroadcasterSubscriptionId = "SetPasswordComponent";
@Component({
selector: 'app-set-password',
templateUrl: 'set-password.component.html',
selector: "app-set-password",
templateUrl: "set-password.component.html",
})
export class SetPasswordComponent extends BaseSetPasswordComponent implements OnDestroy {
constructor(apiService: ApiService, i18nService: I18nService,
cryptoService: CryptoService, messagingService: MessagingService,
userService: UserService, passwordGenerationService: PasswordGenerationService,
platformUtilsService: PlatformUtilsService, policyService: PolicyService, router: Router,
syncService: SyncService, route: ActivatedRoute,
private broadcasterService: BroadcasterService, private ngZone: NgZone) {
super(i18nService, cryptoService, messagingService, userService, passwordGenerationService,
platformUtilsService, policyService, router, apiService, syncService, route);
}
constructor(
apiService: ApiService,
i18nService: I18nService,
cryptoService: CryptoService,
messagingService: MessagingService,
passwordGenerationService: PasswordGenerationService,
platformUtilsService: PlatformUtilsService,
policyService: PolicyService,
router: Router,
syncService: SyncService,
route: ActivatedRoute,
private broadcasterService: BroadcasterService,
private ngZone: NgZone,
stateService: StateService
) {
super(
i18nService,
cryptoService,
messagingService,
passwordGenerationService,
platformUtilsService,
policyService,
router,
apiService,
syncService,
route,
stateService
);
}
get masterPasswordScoreWidth() {
return this.masterPasswordScore == null ? 0 : (this.masterPasswordScore + 1) * 20;
}
get masterPasswordScoreWidth() {
return this.masterPasswordScore == null ? 0 : (this.masterPasswordScore + 1) * 20;
}
get masterPasswordScoreColor() {
switch (this.masterPasswordScore) {
case 4:
return 'success';
case 3:
return 'primary';
case 2:
return 'warning';
default:
return 'danger';
get masterPasswordScoreColor() {
switch (this.masterPasswordScore) {
case 4:
return "success";
case 3:
return "primary";
case 2:
return "warning";
default:
return "danger";
}
}
get masterPasswordScoreText() {
switch (this.masterPasswordScore) {
case 4:
return this.i18nService.t("strong");
case 3:
return this.i18nService.t("good");
case 2:
return this.i18nService.t("weak");
default:
return this.masterPasswordScore != null ? this.i18nService.t("weak") : null;
}
}
async ngOnInit() {
await super.ngOnInit();
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
this.ngZone.run(() => {
switch (message.command) {
case "windowHidden":
this.onWindowHidden();
break;
default:
}
}
});
});
}
get masterPasswordScoreText() {
switch (this.masterPasswordScore) {
case 4:
return this.i18nService.t('strong');
case 3:
return this.i18nService.t('good');
case 2:
return this.i18nService.t('weak');
default:
return this.masterPasswordScore != null ? this.i18nService.t('weak') : null;
}
}
ngOnDestroy() {
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
}
async ngOnInit() {
await super.ngOnInit();
this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => {
this.ngZone.run(() => {
switch (message.command) {
case 'windowHidden':
this.onWindowHidden();
break;
default:
}
});
});
}
ngOnDestroy() {
this.broadcasterService.unsubscribe(BroadcasterSubscriptionId);
}
onWindowHidden() {
this.showPassword = false;
}
onWindowHidden() {
this.showPassword = false;
}
}

Some files were not shown because too many files have changed in this diff Show More