From 195345f2493cf865f306ff7f6f6bd2ae0f9172cc Mon Sep 17 00:00:00 2001 From: Brendan Early Date: Mon, 8 Jul 2019 21:41:06 -0500 Subject: [PATCH 1/6] formatter: gts => prettier --- package-lock.json | 22 ++++++++++++++-------- package.json | 1 + scripts/build.sh | 7 +++---- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 980508fb9..323326663 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,7 +50,7 @@ }, "@types/filewriter": { "version": "0.0.28", - "resolved": "http://registry.npm.taobao.org/@types/filewriter/download/@types/filewriter-0.0.28.tgz", + "resolved": "http://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.28.tgz", "integrity": "sha1-wFTor02d11205jq8dviFFocU1LM=", "dev": true }, @@ -83,6 +83,12 @@ "vue-template-es2015-compiler": "^1.9.0" }, "dependencies": { + "prettier": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.3.tgz", + "integrity": "sha512-kn/GU6SMRYPxUakNXhpP0EedT/KmaPzr0H5lIsDogrykbaxOpOfAFfk5XA7DZrJyMAv1wlMV3CPcZruGXVVUZw==", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -503,7 +509,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -522,7 +528,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -4173,7 +4179,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, @@ -4449,9 +4455,9 @@ "dev": true }, "prettier": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.3.tgz", - "integrity": "sha512-kn/GU6SMRYPxUakNXhpP0EedT/KmaPzr0H5lIsDogrykbaxOpOfAFfk5XA7DZrJyMAv1wlMV3CPcZruGXVVUZw==", + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz", + "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==", "dev": true }, "process": { @@ -5268,7 +5274,7 @@ }, "strip-eof": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, diff --git a/package.json b/package.json index 75b6e1f49..38c39b2e2 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "css-loader": "^2.1.1", "fork-ts-checker-webpack-plugin": "^1.3.5", "gts": "^1.0.0", + "prettier": "1.18.2", "sass": "^1.21.0", "ts-loader": "^6.0.2", "typescript": "^3.5.1", diff --git a/scripts/build.sh b/scripts/build.sh index 7bc1c5a35..899feee05 100644 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -10,6 +10,7 @@ PLATFORM=$1 REMOTE=$(git config --get remote.origin.url) CREDS=$(cat ./src/models/credentials.ts | tr -d '\n') CREDREGEX="^.*'.+'.*'.+'.*'.+'.*$" +STYLEFILES="./src/* ./src/**/* ./src/**/**/* ./sass/*.scss" set -e if [[ $PLATFORM != "chrome" ]] && [[ $PLATFORM != "firefox" ]] && [[ $PLATFORM != "prod" ]]; then @@ -20,12 +21,10 @@ fi echo "Removing old build files..." rm -rf build dist rm -rf firefox chrome release -echo "Checking code style..." -if gts check 1> /dev/null ; then +if ./node_modules/prettier/bin-prettier.js --check $STYLEFILES 1> /dev/null ; then true else - echo "Fixing code style..." - gts fix + ./node_modules/prettier/bin-prettier.js --check $STYLEFILES --write fi if ! [[ $CREDS =~ $CREDREGEX ]] ; then From 2e15fe6fd96d1180dc514060210acdd2dc990f8c Mon Sep 17 00:00:00 2001 From: Brendan Early Date: Mon, 8 Jul 2019 21:41:42 -0500 Subject: [PATCH 2/6] format --- sass/_ui.scss | 205 ++- sass/content.scss | 34 +- sass/import.scss | 156 +- sass/popup.scss | 1380 +++++++++--------- src/background.ts | 162 +- src/components/Import.vue | 25 +- src/components/Import/FileImport.vue | 6 +- src/components/Import/TextImport.vue | 11 +- src/components/Popup.vue | 85 +- src/components/Popup/AboutPage.vue | 112 +- src/components/Popup/AddAccountPage.vue | 27 +- src/components/Popup/AddMethodPage.vue | 4 +- src/components/Popup/DrivePage.vue | 20 +- src/components/Popup/DropboxPage.vue | 20 +- src/components/Popup/EnterPasswordPage.vue | 43 +- src/components/Popup/EntryComponent.vue | 23 +- src/components/Popup/ExportPage.vue | 21 +- src/components/Popup/MainBody.vue | 39 +- src/components/Popup/MainHeader.vue | 69 +- src/components/Popup/MenuPage.vue | 223 +-- src/components/Popup/NotificationHandler.vue | 11 +- src/components/Popup/PageHandler.vue | 82 +- src/components/Popup/SetPasswordPage.vue | 11 +- src/components/Popup/StorageSyncConfPage.vue | 26 +- src/content.ts | 158 +- src/definitions/BackupProvider.d.ts | 4 +- src/definitions/i18n.d.ts | 2 +- src/definitions/module-interface.d.ts | 123 +- src/definitions/otp.d.ts | 60 +- src/definitions/shims-vue.d.ts | 10 +- src/definitions/vue.d.ts | 10 +- src/definitions/vue2-dragula.d.ts | 7 +- src/import.ts | 64 +- src/models/backup.ts | 172 +-- src/models/credentials.ts | 8 +- src/models/encryption.ts | 10 +- src/models/key-utilities.ts | 50 +- src/models/otp.ts | 18 +- src/models/storage.ts | 62 +- src/popup.ts | 112 +- src/qr.ts | 2 +- src/qrdebug.ts | 22 +- src/store/Accounts.ts | 104 +- src/store/Backup.ts | 18 +- src/store/CurrentView.ts | 6 +- src/store/Menu.ts | 22 +- src/store/Notification.ts | 24 +- src/store/Qr.ts | 6 +- src/store/Style.ts | 8 +- src/store/i18n.ts | 4 +- src/test/test.ts | 290 ++-- 51 files changed, 2242 insertions(+), 1929 deletions(-) diff --git a/sass/_ui.scss b/sass/_ui.scss index 23177ab47..1d86d2f14 100644 --- a/sass/_ui.scss +++ b/sass/_ui.scss @@ -4,142 +4,135 @@ // go from darkest to lightest $themes: ( - normal: ( - black-1: black, - black-transparent: rgba(0,0,0,0.5), - white-1: white, - white-transparent: rgba(255, 255, 255, 0.5), - - grey-1: grey, - grey-2: #CCC, - grey-3: #EEE, - grey-background: #EEE, - - blue-1: #08C, - - yellow-1: #fff1ba, - yellow-2: #fff4cc, - - red-1: #DD4B39, - red-2: #EEA59C, - - black-search: #2a2a2e, - white-search: #f9f9fa, - grey-search: #b1b1b3, - - blue-menu: #F4FCFF, - ), - accessibility: ( - black-1: white, - black-transparent: rgba(255, 255, 255, 0.5), - white-1: black, - white-transparent: rgba(0,0,0,0.5), - - grey-1: white, - grey-2: white, - grey-3: white, - grey-background: black, - - blue-1: yellow, - - yellow-1: yellow, - yellow-2: yellow, - - red-1: red, - red-2: red, - - black-search: white, - white-search: black, - grey-search: white, - - blue-menu: cyan, - ), + normal: ( + black-1: black, + black-transparent: rgba(0, 0, 0, 0.5), + white-1: white, + white-transparent: rgba(255, 255, 255, 0.5), + grey-1: grey, + grey-2: #ccc, + grey-3: #eee, + grey-background: #eee, + blue-1: #08c, + yellow-1: #fff1ba, + yellow-2: #fff4cc, + red-1: #dd4b39, + red-2: #eea59c, + black-search: #2a2a2e, + white-search: #f9f9fa, + grey-search: #b1b1b3, + blue-menu: #f4fcff + ), + accessibility: ( + black-1: white, + black-transparent: rgba(255, 255, 255, 0.5), + white-1: black, + white-transparent: rgba(0, 0, 0, 0.5), + grey-1: white, + grey-2: white, + grey-3: white, + grey-background: black, + blue-1: yellow, + yellow-1: yellow, + yellow-2: yellow, + red-1: red, + red-2: red, + black-search: white, + white-search: black, + grey-search: white, + blue-menu: cyan + ) ); $theme-map: null; @mixin themify($themes: $themes) { - @each $theme, $map in $themes { - .theme-#{$theme} & { - $theme-map: () !global; - @each $key, $submap in $map { - $value: map-get(map-get($themes, $theme), '#{$key}'); - $theme-map: map-merge($theme-map, ($key: $value)) !global; - } - @content; - $theme-map: null !global; - } + @each $theme, $map in $themes { + .theme-#{$theme} & { + $theme-map: () !global; + @each $key, $submap in $map { + $value: map-get(map-get($themes, $theme), "#{$key}"); + $theme-map: map-merge( + $theme-map, + ( + $key: $value + ) + ) !global; + } + @content; + $theme-map: null !global; } + } } @function themed($key) { - @return map-get($theme-map, $key); + @return map-get($theme-map, $key); } // Shared @mixin hover-black { - &:hover { - svg { - @include themify($themes) { - fill: themed('black-1'); - } - } + &:hover { + svg { + @include themify($themes) { + fill: themed("black-1"); + } } + } } @mixin icon-special($size, $color) { - svg { - vertical-align: middle; - fill: $color; - height: $size; - width: $size; - } + svg { + vertical-align: middle; + fill: $color; + height: $size; + width: $size; + } } // Classes .button { - margin: 10px; - padding: 20px; - border-radius: 2px; - position: relative; - text-align: center; - font-size: 16px; - @include themify($themes) { - background: themed('white-1'); - border: themed('grey-2') 1px solid; - color: themed('grey-1'); - } - cursor: pointer; + margin: 10px; + padding: 20px; + border-radius: 2px; + position: relative; + text-align: center; + font-size: 16px; + @include themify($themes) { + background: themed("white-1"); + border: themed("grey-2") 1px solid; + color: themed("grey-1"); + } + cursor: pointer; - &:hover { - @include themify($themes) { - color: themed('black-1'); - } + &:hover { + @include themify($themes) { + color: themed("black-1"); } + } } .button-small { - @extend .button; - font-size: 12px; - margin: 20px 100px; - padding: 10px; + @extend .button; + font-size: 12px; + margin: 20px 100px; + padding: 10px; } .input { - display: block; - margin: 0 10px 10px 10px; - padding: 10px; - width: 260px; - @include themify($themes) { - color: themed('black-1'); - border: themed('grey-2') 1px solid; - background: themed('white-1'); - } - outline: none; + display: block; + margin: 0 10px 10px 10px; + padding: 10px; + width: 260px; + @include themify($themes) { + color: themed("black-1"); + border: themed("grey-2") 1px solid; + background: themed("white-1"); + } + outline: none; } a { - @include themify($themes) { - color: themed('blue-1'); - } + @include themify($themes) { + color: themed("blue-1"); + } } diff --git a/sass/content.scss b/sass/content.scss index 786d8027a..474269f75 100644 --- a/sass/content.scss +++ b/sass/content.scss @@ -1,25 +1,25 @@ #__ga_grayLayout__ { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: rgba(255, 255, 255, 0.6); - z-index: 1000000; - display: none; - cursor: crosshair; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(255, 255, 255, 0.6); + z-index: 1000000; + display: none; + cursor: crosshair; } #__ga_grayLayout__ .scan { - width: 100%; - height: 100%; - position: absolute; - top: 0; - opacity: 0.5; + width: 100%; + height: 100%; + position: absolute; + top: 0; + opacity: 0.5; } #__ga_captureBox__ { - position: absolute; - border: black 1px dashed; - display: none; + position: absolute; + border: black 1px dashed; + display: none; } diff --git a/sass/import.scss b/sass/import.scss index 798390f16..b2f415e96 100644 --- a/sass/import.scss +++ b/sass/import.scss @@ -1,126 +1,128 @@ -[v-cloak] { display: none } +[v-cloak] { + display: none; +} * { - font-family: arial, 'Microsoft YaHei'; + font-family: arial, "Microsoft YaHei"; } p { - font-size: 16px; + font-size: 16px; } - #import { - width: 600px; - position: relative; - margin: 0 auto; + width: 600px; + position: relative; + margin: 0 auto; } #import_info { - margin: 10px 20px 20px 20px; + margin: 10px 20px 20px 20px; } .import_tab { - text-align: center; - font-size: 0; - - input { - display: none; + text-align: center; + font-size: 0; - &:checked + label { - background: #eee; - } - } + input { + display: none; - label { - width: 250px; - height: 50px; - font-size: 18px; - text-align: center; - display: inline-grid; - align-items: center; - margin: 20px; - cursor: pointer; - border-radius: 2px; - - &:hover { - background: #eee; - } + &:checked + label { + background: #eee; } -} + } -button, .import_file label { - display: inline-grid; - width: 260px; - height: 60px; - border: #CCC 1px solid; - background: white; - border-radius: 2px; - position: relative; + label { + width: 250px; + height: 50px; + font-size: 18px; text-align: center; + display: inline-grid; align-items: center; - font-size: 16px; - color: gray; + margin: 20px; cursor: pointer; - outline: none; + border-radius: 2px; &:hover { - color: black; + background: #eee; } + } +} + +button, +.import_file label { + display: inline-grid; + width: 260px; + height: 60px; + border: #ccc 1px solid; + background: white; + border-radius: 2px; + position: relative; + text-align: center; + align-items: center; + font-size: 16px; + color: gray; + cursor: pointer; + outline: none; + + &:hover { + color: black; + } } .import_file { - text-align: center; + text-align: center; - input { - display: none; - } + input { + display: none; + } } .import_encrypted { - margin-bottom: 20px; + margin-bottom: 20px; - input { - margin-left: 0; - } + input { + margin-left: 0; + } } .import_code { - float: left; - margin-left: 30px; - margin-right: 40px; - - textarea { - width: 250px; - height: 400px; - padding: 10px; - outline: none; - resize: none; - box-sizing: border-box; - } + float: left; + margin-left: 30px; + margin-right: 40px; + + textarea { + width: 250px; + height: 400px; + padding: 10px; + outline: none; + resize: none; + box-sizing: border-box; + } } .error_password { - font-size: 18px; - color: gray; - text-align: center; + font-size: 18px; + color: gray; + text-align: center; } .import_passphrase input, .import_file_passphrase_input input { - padding: 10px; - margin-bottom: 20px; - width: 250px; - border: #CCC 1px solid; - background: white; - outline: none; + padding: 10px; + margin-bottom: 20px; + width: 250px; + border: #ccc 1px solid; + background: white; + outline: none; } .import_file_passphrase { - display: grid; - justify-content: center; + display: grid; + justify-content: center; } .import_file_passphrase_input { - display: inline-grid; - grid-template-rows: min-content min-content; + display: inline-grid; + grid-template-rows: min-content min-content; } diff --git a/sass/popup.scss b/sass/popup.scss index df272e27e..949328672 100644 --- a/sass/popup.scss +++ b/sass/popup.scss @@ -1,414 +1,417 @@ -@import 'ui'; +@import "ui"; // Structure * { - margin: 0; - padding: 0; - box-sizing: border-box; + margin: 0; + padding: 0; + box-sizing: border-box; } -[v-cloak] { - display: none; +[v-cloak] { + display: none; } body { - width: 320px; - height: 480px; - transform-origin: left top; - overflow: hidden; - font-family: arial, 'Microsoft YaHei'; - font-size: 16px; - cursor: default; - user-select: none; + width: 320px; + height: 480px; + transform-origin: left top; + overflow: hidden; + font-family: arial, "Microsoft YaHei"; + font-size: 16px; + cursor: default; + user-select: none; } svg { - pointer-events: none; + pointer-events: none; } .icon { - @include themify($themes) { - fill: themed('grey-1'); - } - vertical-align: middle; - svg { - height: 16px; - width: 16px; - } + @include themify($themes) { + fill: themed("grey-1"); + } + vertical-align: middle; + svg { + height: 16px; + width: 16px; + } } #codeClipboard { - position: absolute; - top: -1000px; + position: absolute; + top: -1000px; } // Header .header { - height: 38px; - line-height: 38px; - position: relative; - text-align: center; - font-size: 16px; - @include themify($themes) { - color: themed('black-1'); - background: themed('white-1'); - border-bottom: themed('grey-2') 1px solid; - } - - .icon { - @include hover-black; - cursor: pointer; + height: 38px; + line-height: 38px; + position: relative; + text-align: center; + font-size: 16px; + @include themify($themes) { + color: themed("black-1"); + background: themed("white-1"); + border-bottom: themed("grey-2") 1px solid; + } + + .icon { + @include hover-black; + cursor: pointer; - svg { - vertical-align: sub; - } + svg { + vertical-align: sub; } + } } #i-menu { - position: absolute; - left: 20px; - bottom: 0; + position: absolute; + left: 20px; + bottom: 0; } #i-lock { - position: absolute; - left: 45px; - bottom: 0; + position: absolute; + left: 45px; + bottom: 0; } #i-sync { - position: absolute; - left: 70px; - bottom: 0; - cursor: default; - @include themify($themes) { - fill: themed('grey-2'); - } - - &:hover { - svg { - fill: inherit; - } + position: absolute; + left: 70px; + bottom: 0; + cursor: default; + @include themify($themes) { + fill: themed("grey-2"); + } + + &:hover { + svg { + fill: inherit; } + } } #i-qr { - position: absolute; - right: 45px; - bottom: 0; + position: absolute; + right: 45px; + bottom: 0; } #i-edit { - position: absolute; - right: 20px; - bottom: 0; + position: absolute; + right: 20px; + bottom: 0; } #i-close { - position: absolute; - left: 20px; - bottom: 0; + position: absolute; + left: 20px; + bottom: 0; } // Search & Filter .under-header { - padding: 0 10px; - margin-left: 10px; - font-size: 12px; - height: 24px; - line-height: 24px; - cursor: pointer; - display: none; + padding: 0 10px; + margin-left: 10px; + font-size: 12px; + height: 24px; + line-height: 24px; + cursor: pointer; + display: none; } #filter { - @include themify($themes) { - background: themed('yellow-2'); - } + @include themify($themes) { + background: themed("yellow-2"); + } - &:hover { - @include themify($themes) { - background: themed('yellow-1'); - } + &:hover { + @include themify($themes) { + background: themed("yellow-1"); } + } } #search { - position: relative; + position: relative; + @include themify($themes) { + background: themed("white-1"); + border: themed("grey-2") 1px solid; + border-top: none; + } + + &:hover { @include themify($themes) { - background: themed('white-1'); - border: themed('grey-2') 1px solid; - border-top: none; + background: themed("white-search"); } + } - &:hover { - @include themify($themes) { - background: themed('white-search'); - } + input { + font-family: arial, "Microsoft YaHei"; + background: none; + border: none; + width: 100%; + height: 100%; + @include themify($themes) { + color: themed("black-search"); } + } - input { - font-family: arial, 'Microsoft YaHei'; - background: none; - border: none; - width: 100%; - height: 100%; - @include themify($themes) { - color: themed('black-search'); - } - } - - #searchHint { - position: absolute; - top: -1px; - right: 0px; - padding-right: 10px; - display: grid; - grid-template-rows: 4.5px 15px 4.5px; - grid-template-columns: 15px; - } - - #searchHintBorder { - @include themify($themes) { - color: themed('white-1'); - background: themed('grey-search'); - } - text-align: center; - border-radius: 1.5px; - line-height: 16px; - font-weight: bolder; + #searchHint { + position: absolute; + top: -1px; + right: 0px; + padding-right: 10px; + display: grid; + grid-template-rows: 4.5px 15px 4.5px; + grid-template-columns: 15px; + } + + #searchHintBorder { + @include themify($themes) { + color: themed("white-1"); + background: themed("grey-search"); } + text-align: center; + border-radius: 1.5px; + line-height: 16px; + font-weight: bolder; + } } // Codes #codes { - height: 442px; - overflow-x: hidden; - overflow-y: hidden; + height: 442px; + overflow-x: hidden; + overflow-y: hidden; + @include themify($themes) { + background: themed("grey-background"); + } + padding-right: 10px; + + .deleteAction { @include themify($themes) { - background: themed('grey-background'); + @include icon-special(20px, themed("red-1")); } - padding-right:10px; + position: absolute; + top: -10px; + left: -10px; + z-index: 10; + display: none; + } - .deleteAction { - @include themify($themes) { - @include icon-special(20px, themed('red-1')); - } - position: absolute; - top: -10px; - left: -10px; - z-index: 10; - display: none; - } - - &:hover { - padding-right: 0; - overflow-y: scroll; - } - - &.edit { - .code { - @include themify($themes) { - color: themed('grey-2')!important; - } - user-select: none; - cursor: default; - } - - .issuer, .showqr, - .showqr.hidden { - display: none; - } - - .issuerEdit, - .movehandle, #add { - display: block; - } + &:hover { + padding-right: 0; + overflow-y: scroll; + } - .deleteAction { - display: block; - cursor: pointer; - } + &.edit { + .code { + @include themify($themes) { + color: themed("grey-2") !important; + } + user-select: none; + cursor: default; + } - .sector, .counter { - position: absolute; - left: -1000px; - opacity: 0; - } + .issuer, + .showqr, + .showqr.hidden { + display: none; } - &.filter .entry[filtered], - &.search .entry[notSearched] { - height: 0; - margin: 0; - padding: 0; - opacity: 0; - border: none; - overflow: hidden; - position: absolute; + .issuerEdit, + .movehandle, + #add { + display: block; } - &.filter #filter, - &.search #search { - display: block; + .deleteAction { + display: block; + cursor: pointer; } - &:not(.edit) { - // Is this used? - .entry[unencrypted="true"]:hover .warning { - height: 24px; - } + .sector, + .counter { + position: absolute; + left: -1000px; + opacity: 0; + } + } - .code.timeout:not(.hotp) { - animation: twinkling 1s infinite ease-in-out; - } + &.filter .entry[filtered], + &.search .entry[notSearched] { + height: 0; + margin: 0; + padding: 0; + opacity: 0; + border: none; + overflow: hidden; + position: absolute; + } + + &.filter #filter, + &.search #search { + display: block; + } + + &:not(.edit) { + // Is this used? + .entry[unencrypted="true"]:hover .warning { + height: 24px; } + + .code.timeout:not(.hotp) { + animation: twinkling 1s infinite ease-in-out; + } + } } .entry { - margin: 10px; - margin-right: 0; - padding: 10px; + margin: 10px; + margin-right: 0; + padding: 10px; + @include themify($themes) { + border: themed("grey-2") 1px solid; + background: themed("white-1"); + } + border-radius: 2px; + position: relative; + + .issuer { + font-size: 12px; @include themify($themes) { - border: themed('grey-2') 1px solid; - background: themed('white-1'); + color: themed("black-1"); } - border-radius: 2px; - position: relative; + width: 80%; + text-overflow: ellipsis; + overflow: hidden; + } - .issuer { - font-size: 12px; - @include themify($themes) { - color: themed('black-1'); - } - width: 80%; - text-overflow: ellipsis; - overflow: hidden; + .code { + font-size: 36px; + @include themify($themes) { + color: themed("blue-1"); } + width: 80%; + user-select: text; + font-family: "Droid Sans Mono"; + cursor: pointer; + } - .code { - font-size: 36px; - @include themify($themes) { - color: themed('blue-1'); - } - width: 80%; - user-select: text; - font-family: 'Droid Sans Mono'; - cursor: pointer; - } + .sector, + .counter { + width: 20px; + height: 20px; + position: absolute; + right: 10px; + bottom: 10px; + } - .sector, .counter { - width: 20px; - height: 20px; - position: absolute; - right: 10px; - bottom: 10px; + .sector { + svg { + width: 16px; + height: 16px; + margin: 2px; + } + + circle { + fill: none; + transform: rotate(-90deg); + transform-origin: 50% 50%; + @include themify($themes) { + stroke: themed("grey-1"); + } + stroke-width: 8px; + stroke-dasharray: 25.12; + animation-name: timer; + animation-iteration-count: infinite; + animation-timing-function: linear; + } + } + + .counter { + @include themify($themes) { + @include icon-special(18px, themed("grey-1")); } - - .sector { - svg { - width: 16px; - height: 16px; - margin: 2px; - } + text-align: center; + cursor: pointer; - circle { - fill: none; - transform: rotate(-90deg); - transform-origin: 50% 50%; - @include themify($themes) { - stroke: themed('grey-1'); - } - stroke-width: 8px; - stroke-dasharray: 25.12; - animation-name: timer; - animation-iteration-count: infinite; - animation-timing-function: linear; + .disabled { + svg { + @include themify($themes) { + fill: themed("grey-2"); } + } + cursor: default; } - .counter { + &:not(.disabled):hover { + svg { @include themify($themes) { - @include icon-special(18px, themed('grey-1')); - } - text-align: center; - cursor: pointer; - - .disabled { - svg { - @include themify($themes) { - fill: themed('grey-2'); - } - } - cursor: default; - } - - &:not(.disabled):hover { - svg { - @include themify($themes) { - fill: themed('black-1'); - } - } + fill: themed("black-1"); } + } } + } - .issuerEdit { - display: none; - - input { - border: none; - height: 14px; - width: 70%; - font-size: 12px; - outline: none; - @include themify($themes) { - background: themed('grey-3'); - } - - } + .issuerEdit { + display: none; + + input { + border: none; + height: 14px; + width: 70%; + font-size: 12px; + outline: none; + @include themify($themes) { + background: themed("grey-3"); + } + } + } + + .movehandle { + @include themify($themes) { + @include icon-special(24px, themed("grey-2")); } + height: 98px; + line-height: 98px; + right: 10px; + top: 0; + position: absolute; + cursor: move; + display: none; + } - .movehandle { - @include themify($themes) { - @include icon-special(24px, themed('grey-2')); - } - height: 98px; - line-height: 98px; - right: 10px; - top: 0; - position: absolute; - cursor: move; - display: none; + .showqr { + @include themify($themes) { + @include icon-special(20px, themed("grey-2")); } + @include hover-black; + right: 10px; + top: 10px; + position: absolute; + cursor: pointer; + opacity: 0; + } + &:hover { .showqr { - @include themify($themes) { - @include icon-special(20px, themed('grey-2')); - } - @include hover-black; - right: 10px; - top: 10px; - position: absolute; - cursor: pointer; - opacity: 0; + opacity: 1; } - &:hover { - .showqr { - opacity: 1; - } - - .movehandle { - svg { - @include themify($themes) { - fill: themed('black-1'); - } - } + .movehandle { + svg { + @include themify($themes) { + fill: themed("black-1"); } + } } - /* + } + /* // Is this used? &[dropOver="true"] { border: $grey-1 1px dashed; @@ -436,480 +439,481 @@ svg { } .no-copy { - cursor: default; + cursor: default; } #add { - @extend .button; - @include hover-black; - margin-right: 0; - line-height: 56px; - display: none; + @extend .button; + @include hover-black; + margin-right: 0; + line-height: 56px; + display: none; } // Modals #notification { - position: absolute; - left: 60px; - top: -1000px; - width: 200px; - height: 60px; - line-height: 60px; - text-align: center; - @include themify($themes) { - background: themed('black-transparent'); - color: themed('white-1'); - } - font-size: 20px; - border-radius: 2px; - - &.fadein { - top: 190px; - animation: fadeshow 0.2s 1 ease-out; - } - - &.fadeout { - top: 190px; - animation: fadehide 0.2s 1 ease-in; - } + position: absolute; + left: 60px; + top: -1000px; + width: 200px; + height: 60px; + line-height: 60px; + text-align: center; + @include themify($themes) { + background: themed("black-transparent"); + color: themed("white-1"); + } + font-size: 20px; + border-radius: 2px; + + &.fadein { + top: 190px; + animation: fadeshow 0.2s 1 ease-out; + } + + &.fadeout { + top: 190px; + animation: fadehide 0.2s 1 ease-in; + } } .message-box { - position: absolute; - width: 300px; - padding: 10px; - @include themify($themes) { - color: themed('black-1'); - border: themed('grey-1') 1px solid; - background: themed('white-1'); - box-shadow: 1px 1px 3px themed('grey-1'); - } - border-radius: 2px; - left: 10px; - top: 150px; - z-index: 1000; - - .button-small { - margin-top: 10px; - margin-bottom: 10px; - } + position: absolute; + width: 300px; + padding: 10px; + @include themify($themes) { + color: themed("black-1"); + border: themed("grey-1") 1px solid; + background: themed("white-1"); + box-shadow: 1px 1px 3px themed("grey-1"); + } + border-radius: 2px; + left: 10px; + top: 150px; + z-index: 1000; + + .button-small { + margin-top: 10px; + margin-bottom: 10px; + } } .buttons { - text-align: center; + text-align: center; - .button-small { - display: inline-block; - margin: 10px; - padding: 5px 20px; - } + .button-small { + display: inline-block; + margin: 10px; + padding: 5px 20px; + } } #qr { - width: 320px; - height: 480px; - top: -1000px; - left: 0; - position: absolute; - z-index: 10; - @include themify($themes) { - background-color: themed('white-transparent'); - } - background-repeat: no-repeat; - background-position: center; - - canvas { - display: none; - } + width: 320px; + height: 480px; + top: -1000px; + left: 0; + position: absolute; + z-index: 10; + @include themify($themes) { + background-color: themed("white-transparent"); + } + background-repeat: no-repeat; + background-position: center; + + canvas { + display: none; + } - &.qrfadein { - top: 0; - animation: fadeshow 0.2s 1 ease-out; - } + &.qrfadein { + top: 0; + animation: fadeshow 0.2s 1 ease-out; + } - &.qrfadeout { - top: 0; - animation: fadehide 0.2s 1 ease-in; - } + &.qrfadeout { + top: 0; + animation: fadehide 0.2s 1 ease-in; + } } #overlay { - position: absolute; - width: 100%; - height: 100%; - top: 0; - left: 0; - z-index: 900; + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + z-index: 900; } // Info #info { - position: absolute; - height: 460px; - width: 300px; - padding: 10px; - @include themify($themes) { - color: themed('black-1'); - border: themed('grey-1'); - background: themed('white-1'); - box-shadow: 1px 1px 3px themed('grey-1'); - } - left: 10px; - top: -1000px; - z-index: 100; - - #infoContent { - height: 420px; - overflow-y: auto; - overflow-x: hidden; - - p { - margin-bottom: 20px; - } - } + position: absolute; + height: 460px; + width: 300px; + padding: 10px; + @include themify($themes) { + color: themed("black-1"); + border: themed("grey-1"); + background: themed("white-1"); + box-shadow: 1px 1px 3px themed("grey-1"); + } + left: 10px; + top: -1000px; + z-index: 100; + + #infoContent { + height: 420px; + overflow-y: auto; + overflow-x: hidden; - #infoClose { - @include hover-black; - @include themify($themes) { - @include icon-special(14px, themed('grey-1')); - } - height: 20px; - width: 20px; - cursor: pointer; + p { + margin-bottom: 20px; } + } - label { - display: block; - margin: 10px 0 0 10px; + #infoClose { + @include hover-black; + @include themify($themes) { + @include icon-special(14px, themed("grey-1")); } + height: 20px; + width: 20px; + cursor: pointer; + } - .combo-label { - display: inline-block; - margin: 20px; - margin-right: 0px; - font-size: 16px; - } + label { + display: block; + margin: 10px 0 0 10px; + } - .checkbox { - margin: 20px; - } + .combo-label { + display: inline-block; + margin: 20px; + margin-right: 0px; + font-size: 16px; + } - select { - margin: 20px; - font-size: 12px; - } + .checkbox { + margin: 20px; + } - a { - text-decoration: none; - } + select { + margin: 20px; + font-size: 12px; + } - .button { - display: block; - } + a { + text-decoration: none; + } - .text { - display: block; - margin: 10px 0 0 10px; - } + .button { + display: block; + } - .warning { - @include themify($themes) { - color: themed('red-1'); - } - } - - // Security - @mixin security-button($margin-left) { - @extend .button-small; - font-size: 12px; - margin: 20px 100px; - padding: 10px; - display: inline-block; - width: 80px; - margin-left: $margin-left; - margin-right: 0; - } + .text { + display: block; + margin: 10px 0 0 10px; + } - #security-save { - @include security-button(40px); + .warning { + @include themify($themes) { + color: themed("red-1"); } + } - #security-remove { - @include security-button(30px); - } + // Security + @mixin security-button($margin-left) { + @extend .button-small; + font-size: 12px; + margin: 20px 100px; + padding: 10px; + display: inline-block; + width: 80px; + margin-left: $margin-left; + margin-right: 0; + } - &.fadein { - top: 10px; - animation: fadein 0.2s 1 ease-out; - } + #security-save { + @include security-button(40px); + } - &.fadeout { - top: 110px; - animation: fadeout 0.2s 1 ease-in; - } + #security-remove { + @include security-button(30px); + } + + &.fadein { + top: 10px; + animation: fadein 0.2s 1 ease-out; + } + + &.fadeout { + top: 110px; + animation: fadeout 0.2s 1 ease-in; + } } // Menu #menu { - width: 320px; - height: 480px; - position: absolute; - left: -1000px; - top: 0; + width: 320px; + height: 480px; + position: absolute; + left: -1000px; + top: 0; - &.slidein { - left: 0; - animation: slidein 0.2s 1 ease-out; - opacity: 1; + &.slidein { + left: 0; + animation: slidein 0.2s 1 ease-out; + opacity: 1; + } + + &.slideout { + left: -55px; + animation: slideout 0.2s 1 ease-in; + opacity: 0; + } + + #menuBody { + overflow-y: auto; + height: 442px; + width: inherit; + position: absolute; + @include themify($themes) { + background: themed("grey-background"); } + } - &.slideout { - left: -55px; - animation: slideout 0.2s 1 ease-in; - opacity: 0; - } + .menuList { + margin: 10px; + border-radius: 2px; + @include themify($themes) { + border: themed("grey-2") 1px solid; + background: themed("white-1"); + } + + p { + position: relative; + padding: 10px; + font-size: 16px; + cursor: pointer; + display: grid; + grid-template-columns: 30px auto; + @include themify($themes) { + border-bottom: themed("grey-2") 1px solid; + color: themed("grey-1"); + } + + span { + display: flex; + align-items: center; - #menuBody { - overflow-y: auto; - height: 442px; - width: inherit; - position: absolute; - @include themify($themes) { - background: themed('grey-background'); + svg { + @include themify($themes) { + fill: themed("grey-1"); + } + height: 16px; + width: 16px; } - } + } - .menuList { - margin: 10px; - border-radius: 2px; + &:hover { @include themify($themes) { - border: themed('grey-2') 1px solid; - background: themed('white-1'); + background: themed("blue-menu"); + color: themed("black-1"); } - - p { - position: relative; - padding: 10px; - font-size: 16px; - cursor: pointer; - display: grid; - grid-template-columns: 30px auto; - @include themify($themes) { - border-bottom: themed('grey-2') 1px solid; - color: themed('grey-1'); - } - - span { - display: flex; - align-items: center; - - svg { - @include themify($themes) { - fill: themed('grey-1'); - } - height: 16px; - width: 16px; - } - } - - &:hover { - @include themify($themes) { - background: themed('blue-menu'); - color: themed('black-1'); - } - - svg { - @include themify($themes) { - fill: themed('black-1'); - } - } - } - - &:last-child { - border-bottom: none; - } + + svg { + @include themify($themes) { + fill: themed("black-1"); + } } + } + + &:last-child { + border-bottom: none; + } } + } } #version { - text-align: center; - margin: 10px; - @include themify($themes) { - color: themed('grey-1'); - } + text-align: center; + margin: 10px; + @include themify($themes) { + color: themed("grey-1"); + } } // Animations @keyframes timer { - to { - stroke-dashoffset: -25.12; - } -} - -@keyframes twinkling{ - 0%{ - color: #EEA59C; - } - 100%{ - color: #DD4B39; - } -} - -@keyframes fadeshow{ - 0%{ - opacity:0; - } - 100%{ - opacity:1; - } -} - -@keyframes fadehide{ - 0%{ - opacity:1; - } - 100%{ - opacity:0; - } -} - -@keyframes fadein{ - 0%{ - opacity:0; - top:110px; - } - 100%{ - opacity:1; - top:10px; - } -} - -@keyframes fadeout{ - 0%{ - opacity:1; - top:10px; - } - 100%{ - opacity:0; - top:110px; - } -} - -@keyframes slidein{ - 0%{ - opacity:0; - left:-55px; - } - 100%{ - opacity:1; - left:0; - } + to { + stroke-dashoffset: -25.12; + } +} + +@keyframes twinkling { + 0% { + color: #eea59c; + } + 100% { + color: #dd4b39; + } +} + +@keyframes fadeshow { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@keyframes fadehide { + 0% { + opacity: 1; + } + 100% { + opacity: 0; + } +} + +@keyframes fadein { + 0% { + opacity: 0; + top: 110px; + } + 100% { + opacity: 1; + top: 10px; + } +} + +@keyframes fadeout { + 0% { + opacity: 1; + top: 10px; + } + 100% { + opacity: 0; + top: 110px; + } +} + +@keyframes slidein { + 0% { + opacity: 0; + left: -55px; + } + 100% { + opacity: 1; + left: 0; + } } -@keyframes slideout{ - 0%{ - opacity:1; - left:0; - } - 100%{ - opacity:0; - left:-55px; - } +@keyframes slideout { + 0% { + opacity: 1; + left: 0; + } + 100% { + opacity: 0; + left: -55px; + } } // Misc @font-face { - font-family: 'Droid Sans Mono'; - font-style: normal; - font-weight: 400; - src: url(DroidSansMono.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; + font-family: "Droid Sans Mono"; + font-style: normal; + font-weight: 400; + src: url(DroidSansMono.woff2) format("woff2"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, + U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; } .gu-mirror { - display: none; + display: none; } ::-webkit-scrollbar { - width: 10px; - @include themify($themes) { - background: themed('grey-3'); - } + width: 10px; + @include themify($themes) { + background: themed("grey-3"); + } } ::-webkit-scrollbar-thumb { - @include themify($themes) { - background-color: themed('grey-1'); - border: 2px solid themed('grey-3'); - } - border-radius: 5px; + @include themify($themes) { + background-color: themed("grey-1"); + border: 2px solid themed("grey-3"); + } + border-radius: 5px; } // Accessibility overrides .theme-accessibility { - select { - border-color: white; + select { + border-color: white; + color: white; + background-color: black; + } + .entry { + .issuerEdit { + input { color: white; - background-color: black; - } - .entry { - .issuerEdit { - input { - color: white; - background: black; - border: white 1px solid; - } - } + background: black; + border: white 1px solid; + } + } - .showqr { - svg { - fill: yellow; - } + .showqr { + svg { + fill: yellow; + } - &:hover { - svg { - fill: yellow; - } - } + &:hover { + svg { + fill: yellow; } + } } + } - #menu { - .menuList { - p:hover { - color: black; + #menu { + .menuList { + p:hover { + color: black; - svg { - fill: black; - } - } + svg { + fill: black; } + } } + } + + .header { + .icon { + svg { + fill: yellow; + } - .header { - .icon { - svg { - fill: yellow; - } - - &#i-sync { - svg { - fill: white; - } - - &:hover { - svg { - fill: white; - } - } - } - - &:hover { - svg { - fill: yellow; - } - } + &#i-sync { + svg { + fill: white; + } + + &:hover { + svg { + fill: white; + } + } + } + + &:hover { + svg { + fill: yellow; } + } } + } } diff --git a/src/background.ts b/src/background.ts index 23c49b4aa..b0c79cbaa 100644 --- a/src/background.ts +++ b/src/background.ts @@ -1,16 +1,16 @@ -import * as CryptoJS from 'crypto-js'; +import * as CryptoJS from "crypto-js"; // tslint:disable-next-line:ban-ts-ignore // @ts-ignore -import QRCode from 'qrcode-reader'; +import QRCode from "qrcode-reader"; -import { getCredentials } from './models/credentials'; -import { Encryption } from './models/encryption'; -import { EntryStorage, ManagedStorage } from './models/storage'; -import { Dropbox, Drive } from './models/backup'; +import { getCredentials } from "./models/credentials"; +import { Encryption } from "./models/encryption"; +import { EntryStorage, ManagedStorage } from "./models/storage"; +import { Dropbox, Drive } from "./models/backup"; -let cachedPassphrase = ''; +let cachedPassphrase = ""; chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { - if (message.action === 'position') { + if (message.action === "position") { if (!sender.tab) { return; } @@ -22,14 +22,14 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { message.info.height, message.info.windowWidth ); - } else if (message.action === 'cachePassphrase') { + } else if (message.action === "cachePassphrase") { cachedPassphrase = message.value; - } else if (message.action === 'passphrase') { + } else if (message.action === "passphrase") { sendResponse(cachedPassphrase); - } else if (['dropbox', 'drive'].indexOf(message.action) > -1) { + } else if (["dropbox", "drive"].indexOf(message.action) > -1) { getBackupToken(message.action); - } else if (message.action === 'lock') { - cachedPassphrase = ''; + } else if (message.action === "lock") { + cachedPassphrase = ""; } }); @@ -43,16 +43,16 @@ function getQr( height: number, windowWidth: number ) { - chrome.tabs.captureVisibleTab(tab.windowId, { format: 'png' }, dataUrl => { + chrome.tabs.captureVisibleTab(tab.windowId, { format: "png" }, dataUrl => { contentTab = tab; const qr = new Image(); qr.src = dataUrl; qr.onload = () => { const devicePixelRatio = qr.width / windowWidth; - const captureCanvas = document.createElement('canvas'); + const captureCanvas = document.createElement("canvas"); captureCanvas.width = width * devicePixelRatio; captureCanvas.height = height * devicePixelRatio; - const ctx = captureCanvas.getContext('2d'); + const ctx = captureCanvas.getContext("2d"); if (!ctx) { return; } @@ -87,7 +87,7 @@ function getQr( if (!id) { return; } - chrome.tabs.sendMessage(id, { action: 'errorqr' }); + chrome.tabs.sendMessage(id, { action: "errorqr" }); } else { getTotp(text.result); } @@ -103,24 +103,24 @@ async function getTotp(text: string) { return; } - if (text.indexOf('otpauth://') !== 0) { - if (text === 'error decoding QR Code') { - chrome.tabs.sendMessage(id, { action: 'errorqr' }); + if (text.indexOf("otpauth://") !== 0) { + if (text === "error decoding QR Code") { + chrome.tabs.sendMessage(id, { action: "errorqr" }); } else { - chrome.tabs.sendMessage(id, { action: 'text', text }); + chrome.tabs.sendMessage(id, { action: "text", text }); } } else { - let uri = text.split('otpauth://')[1]; + let uri = text.split("otpauth://")[1]; let type = uri.substr(0, 4).toLowerCase(); uri = uri.substr(5); - let label = uri.split('?')[0]; - const parameterPart = uri.split('?')[1]; + let label = uri.split("?")[0]; + const parameterPart = uri.split("?")[1]; if (!label || !parameterPart) { - chrome.tabs.sendMessage(id, { action: 'errorqr' }); + chrome.tabs.sendMessage(id, { action: "errorqr" }); } else { - let account = ''; - let secret = ''; - let issuer = ''; + let account = ""; + let secret = ""; + let issuer = ""; let period: number | undefined = undefined; try { @@ -128,27 +128,27 @@ async function getTotp(text: string) { } catch (error) { console.error(error); } - if (label.indexOf(':') !== -1) { - issuer = label.split(':')[0]; - account = label.split(':')[1]; + if (label.indexOf(":") !== -1) { + issuer = label.split(":")[0]; + account = label.split(":")[1]; } else { account = label; } - const parameters = parameterPart.split('&'); + const parameters = parameterPart.split("&"); parameters.forEach(item => { - const parameter = item.split('='); - if (parameter[0].toLowerCase() === 'secret') { + const parameter = item.split("="); + if (parameter[0].toLowerCase() === "secret") { secret = parameter[1]; - } else if (parameter[0].toLowerCase() === 'issuer') { + } else if (parameter[0].toLowerCase() === "issuer") { try { issuer = decodeURIComponent(parameter[1]); } catch { issuer = parameter[1]; } - } else if (parameter[0].toLowerCase() === 'counter') { + } else if (parameter[0].toLowerCase() === "counter") { let counter = Number(parameter[1]); counter = isNaN(counter) || counter < 0 ? 0 : counter; - } else if (parameter[0].toLowerCase() === 'period') { + } else if (parameter[0].toLowerCase() === "period") { period = Number(parameter[1]); period = isNaN(period) || period < 0 || period > 60 || 60 % period !== 0 @@ -158,27 +158,27 @@ async function getTotp(text: string) { }); if (!secret) { - chrome.tabs.sendMessage(id, { action: 'errorqr' }); + chrome.tabs.sendMessage(id, { action: "errorqr" }); } else if ( !/^[0-9a-f]+$/i.test(secret) && !/^[2-7a-z]+=*$/i.test(secret) ) { - chrome.tabs.sendMessage(id, { action: 'secretqr', secret }); + chrome.tabs.sendMessage(id, { action: "secretqr", secret }); } else { const encryption = new Encryption(cachedPassphrase); const hash = CryptoJS.MD5(secret).toString(); if ( !/^[2-7a-z]+=*$/i.test(secret) && /^[0-9a-f]+$/i.test(secret) && - type === 'totp' + type === "totp" ) { - type = 'hex'; + type = "hex"; } else if ( !/^[2-7a-z]+=*$/i.test(secret) && /^[0-9a-f]+$/i.test(secret) && - type === 'hotp' + type === "hotp" ) { - type = 'hhex'; + type = "hhex"; } const entryData: { [hash: string]: OTPStorage } = {}; entryData[hash] = { @@ -189,13 +189,13 @@ async function getTotp(text: string) { type, encrypted: false, index: 0, - counter: 0, + counter: 0 }; if (period) { entryData[hash].period = period; } await EntryStorage.import(encryption, entryData); - chrome.tabs.sendMessage(id, { action: 'added', account }); + chrome.tabs.sendMessage(id, { action: "added", account }); } } } @@ -203,32 +203,32 @@ async function getTotp(text: string) { } function getBackupToken(service: string) { - if (navigator.userAgent.indexOf('Chrome') !== -1 && service === 'drive') { + if (navigator.userAgent.indexOf("Chrome") !== -1 && service === "drive") { chrome.identity.getAuthToken( { interactive: true, - scopes: ['https://www.googleapis.com/auth/drive.file'], + scopes: ["https://www.googleapis.com/auth/drive.file"] }, value => { localStorage.driveToken = value; - chrome.runtime.sendMessage({ action: 'drivetoken', value }); + chrome.runtime.sendMessage({ action: "drivetoken", value }); return true; } ); } else { - let authUrl = ''; - if (service === 'dropbox') { + let authUrl = ""; + if (service === "dropbox") { authUrl = - 'https://www.dropbox.com/oauth2/authorize?response_type=token&client_id=' + + "https://www.dropbox.com/oauth2/authorize?response_type=token&client_id=" + getCredentials().dropbox.client_id + - '&redirect_uri=' + + "&redirect_uri=" + encodeURIComponent(chrome.identity.getRedirectURL()); - } else if (service === 'drive') { + } else if (service === "drive") { authUrl = - 'https://accounts.google.com/o/oauth2/v2/auth?response_type=code&access_type=offline&client_id=' + + "https://accounts.google.com/o/oauth2/v2/auth?response_type=code&access_type=offline&client_id=" + getCredentials().drive.client_id + - '&scope=https%3A//www.googleapis.com/auth/drive.file&prompt=consent&redirect_uri=' + - encodeURIComponent('https://authenticator.cc/oauth'); + "&scope=https%3A//www.googleapis.com/auth/drive.file&prompt=consent&redirect_uri=" + + encodeURIComponent("https://authenticator.cc/oauth"); } chrome.identity.launchWebAuthFlow( { url: authUrl, interactive: true }, @@ -236,9 +236,9 @@ function getBackupToken(service: string) { if (!url) { return; } - let hashMatches = url.split('#'); - if (service === 'drive') { - hashMatches = url.slice(0, -1).split('?'); + let hashMatches = url.split("#"); + if (service === "drive") { + hashMatches = url.slice(0, -1).split("?"); } if (hashMatches.length < 2) { return; @@ -246,7 +246,7 @@ function getBackupToken(service: string) { const hash = hashMatches[1]; - const resData = hash.split('&'); + const resData = hash.split("&"); for (let i = 0; i < resData.length; i++) { const kv = resData[i]; if (/^(.*?)=(.*?)$/.test(kv)) { @@ -256,14 +256,14 @@ function getBackupToken(service: string) { } const key = kvMatches[1]; const value = kvMatches[2]; - if (key === 'access_token') { - if (service === 'dropbox') { + if (key === "access_token") { + if (service === "dropbox") { localStorage.dropboxToken = value; - uploadBackup('dropbox'); + uploadBackup("dropbox"); return; } - } else if (key === 'code') { - if (service === 'drive') { + } else if (key === "code") { + if (service === "drive") { const xhr = new XMLHttpRequest(); // Need to trade code we got from launchWebAuthFlow for a // token & refresh token @@ -273,19 +273,19 @@ function getBackupToken(service: string) { reject: (reason: Error) => void ) => { xhr.open( - 'POST', - 'https://www.googleapis.com/oauth2/v4/token?client_id=' + + "POST", + "https://www.googleapis.com/oauth2/v4/token?client_id=" + getCredentials().drive.client_id + - '&client_secret=' + + "&client_secret=" + getCredentials().drive.client_secret + - '&code=' + + "&code=" + value + - '&redirect_uri=https://authenticator.cc/oauth&grant_type=authorization_code' + "&redirect_uri=https://authenticator.cc/oauth&grant_type=authorization_code" ); - xhr.setRequestHeader('Accept', 'application/json'); + xhr.setRequestHeader("Accept", "application/json"); xhr.setRequestHeader( - 'Content-Type', - 'application/x-www-form-urlencoded' + "Content-Type", + "application/x-www-form-urlencoded" ); xhr.onreadystatechange = () => { if (xhr.readyState === 4) { @@ -309,7 +309,7 @@ function getBackupToken(service: string) { xhr.send(); } ); - uploadBackup('drive'); + uploadBackup("drive"); } } } @@ -324,12 +324,12 @@ async function uploadBackup(service: string) { const encryption = new Encryption(cachedPassphrase); switch (service) { - case 'dropbox': + case "dropbox": const dbox = new Dropbox(); await dbox.upload(encryption); break; - case 'drive': + case "drive": const drive = new Drive(); await drive.upload(encryption); break; @@ -341,19 +341,19 @@ async function uploadBackup(service: string) { // Show issue page after first install chrome.runtime.onInstalled.addListener(async details => { - if (details.reason !== 'install') { + if (details.reason !== "install") { return; - } else if (await ManagedStorage.get('disableInstallHelp')) { + } else if (await ManagedStorage.get("disableInstallHelp")) { return; } let url: string | null = null; - if (navigator.userAgent.indexOf('Chrome') !== -1) { - url = 'https://authenticator.cc/docs/en/chrome-issues'; + if (navigator.userAgent.indexOf("Chrome") !== -1) { + url = "https://authenticator.cc/docs/en/chrome-issues"; } if (url) { - window.open(url, '_blank'); + window.open(url, "_blank"); } }); diff --git a/src/components/Import.vue b/src/components/Import.vue index 01a5ca1ec..24a7692c6 100644 --- a/src/components/Import.vue +++ b/src/components/Import.vue @@ -2,9 +2,19 @@
- + - +
@@ -13,12 +23,15 @@ {{ i18n.otp_backup_learn }} + >{{ i18n.otp_backup_learn }}

-
{{ i18n.import_error_password }}
+
+ {{ i18n.import_error_password }} +
- diff --git a/src/components/Import/TextImport.vue b/src/components/Import/TextImport.vue index 104be3997..67dab9e42 100644 --- a/src/components/Import/TextImport.vue +++ b/src/components/Import/TextImport.vue @@ -9,9 +9,15 @@
- +
- + - diff --git a/src/components/Popup.vue b/src/components/Popup.vue index 4fdc9384d..f77999845 100644 --- a/src/components/Popup.vue +++ b/src/components/Popup.vue @@ -1,60 +1,89 @@ diff --git a/src/components/Popup/AboutPage.vue b/src/components/Popup/AboutPage.vue index 4fa05019d..3613cff22 100644 --- a/src/components/Popup/AboutPage.vue +++ b/src/components/Popup/AboutPage.vue @@ -1,26 +1,96 @@ diff --git a/src/components/Popup/AddAccountPage.vue b/src/components/Popup/AddAccountPage.vue index d5d493a6c..49f0b47d8 100644 --- a/src/components/Popup/AddAccountPage.vue +++ b/src/components/Popup/AddAccountPage.vue @@ -1,9 +1,9 @@ diff --git a/src/components/Popup/SetPasswordPage.vue b/src/components/Popup/SetPasswordPage.vue index 218aebc53..2dc776719 100644 --- a/src/components/Popup/SetPasswordPage.vue +++ b/src/components/Popup/SetPasswordPage.vue @@ -4,9 +4,16 @@ - +
{{ i18n.ok }}
-
{{ i18n.remove }}
+
+ {{ i18n.remove }} +
+ diff --git a/src/components/Import/TextImport.vue b/src/components/Import/TextImport.vue index 67dab9e42..104be3997 100644 --- a/src/components/Import/TextImport.vue +++ b/src/components/Import/TextImport.vue @@ -9,15 +9,9 @@
- +
- + + diff --git a/src/components/Popup.vue b/src/components/Popup.vue index f77999845..4fdc9384d 100644 --- a/src/components/Popup.vue +++ b/src/components/Popup.vue @@ -1,89 +1,60 @@ diff --git a/src/components/Popup/AboutPage.vue b/src/components/Popup/AboutPage.vue index 3613cff22..4fa05019d 100644 --- a/src/components/Popup/AboutPage.vue +++ b/src/components/Popup/AboutPage.vue @@ -1,96 +1,26 @@ diff --git a/src/components/Popup/AddAccountPage.vue b/src/components/Popup/AddAccountPage.vue index 49f0b47d8..d5d493a6c 100644 --- a/src/components/Popup/AddAccountPage.vue +++ b/src/components/Popup/AddAccountPage.vue @@ -1,9 +1,9 @@ diff --git a/src/components/Popup/SetPasswordPage.vue b/src/components/Popup/SetPasswordPage.vue index 2dc776719..218aebc53 100644 --- a/src/components/Popup/SetPasswordPage.vue +++ b/src/components/Popup/SetPasswordPage.vue @@ -4,16 +4,9 @@ - +
{{ i18n.ok }}
-
- {{ i18n.remove }} -
+
{{ i18n.remove }}