diff --git a/build-chrome.ps1 b/build-chrome.ps1
new file mode 100644
index 000000000..6511c941d
--- /dev/null
+++ b/build-chrome.ps1
@@ -0,0 +1,205 @@
+# Authenticator Chrome Extension Build Script
+# Save as UTF-8 without BOM
+
+# Set error handling
+$ErrorActionPreference = "Stop"
+
+Write-Host "===== Authenticator Chrome Extension Build Script =====" -ForegroundColor Cyan
+
+# Check if dependencies are installed
+Write-Host ">> Checking dependencies..." -ForegroundColor Yellow
+if (-not (Test-Path -Path "node_modules")) {
+ Write-Host "Node modules not found. Installing dependencies..." -ForegroundColor Yellow
+ npm install
+ if ($LASTEXITCODE -ne 0) {
+ Write-Host "❌ Failed to install dependencies. Please run 'npm install' manually and try again." -ForegroundColor Red
+ exit
+ }
+ Write-Host "✓ Dependencies installed successfully" -ForegroundColor Green
+}
+
+# Check if webpack-cli is installed
+if (-not (Get-Command "npx webpack" -ErrorAction SilentlyContinue)) {
+ Write-Host "webpack-cli not found. Installing webpack-cli..." -ForegroundColor Yellow
+ npm install -D webpack-cli
+ if ($LASTEXITCODE -ne 0) {
+ Write-Host "❌ Failed to install webpack-cli. Please run 'npm install -D webpack-cli' manually and try again." -ForegroundColor Red
+ exit
+ }
+ Write-Host "✓ webpack-cli installed successfully" -ForegroundColor Green
+}
+
+# Check if sass is installed
+$sassPkgPath = "node_modules\sass"
+if (-not (Test-Path -Path $sassPkgPath)) {
+ Write-Host "sass not found. Installing sass..." -ForegroundColor Yellow
+ npm install -D sass
+ if ($LASTEXITCODE -ne 0) {
+ Write-Host "❌ Failed to install sass. Please run 'npm install -D sass' manually and try again." -ForegroundColor Red
+ exit
+ }
+ Write-Host "✓ sass installed successfully" -ForegroundColor Green
+}
+
+# Check chrome directory
+Write-Host ">> Checking chrome directory status..." -ForegroundColor Yellow
+if (Test-Path -Path "chrome") {
+ $chromeFiles = Get-ChildItem -Path "chrome" -Force
+
+ if ($chromeFiles.Count -gt 0) {
+ Write-Host "Chrome directory is not empty, contains $($chromeFiles.Count) files/folders" -ForegroundColor Yellow
+ $confirmClear = Read-Host "Clear chrome directory and continue? (Y/N)"
+
+ if ($confirmClear -eq "Y" -or $confirmClear -eq "y") {
+ Write-Host ">> Clearing chrome directory..." -ForegroundColor Yellow
+ Remove-Item -Path "chrome\*" -Recurse -Force
+ Write-Host "✓ Chrome directory cleared" -ForegroundColor Green
+ }
+ else {
+ Write-Host "❌ Build canceled" -ForegroundColor Red
+ exit
+ }
+ }
+ else {
+ Write-Host "✓ Chrome directory exists and is empty" -ForegroundColor Green
+ }
+}
+else {
+ Write-Host ">> Creating chrome directory..." -ForegroundColor Yellow
+ New-Item -Path "chrome" -ItemType Directory | Out-Null
+ Write-Host "✓ Chrome directory created" -ForegroundColor Green
+}
+
+# Create necessary subdirectories
+Write-Host ">> Creating necessary subdirectories..." -ForegroundColor Yellow
+$subDirs = @("dist", "css", "images", "view", "_locales")
+foreach ($dir in $subDirs) {
+ if (-not (Test-Path -Path "chrome\$dir")) {
+ New-Item -Path "chrome\$dir" -ItemType Directory | Out-Null
+ }
+}
+Write-Host "✓ Subdirectory structure created" -ForegroundColor Green
+
+# Compile JavaScript files
+Write-Host ">> Compiling JavaScript files..." -ForegroundColor Yellow
+npx webpack
+if ($LASTEXITCODE -ne 0) {
+ Write-Host "❌ JavaScript compilation failed" -ForegroundColor Red
+ Write-Host "If this is your first time running the script, try running 'npm install' and then 'npm install -D webpack-cli' manually." -ForegroundColor Yellow
+ exit
+}
+Write-Host "✓ JavaScript files compiled successfully" -ForegroundColor Green
+
+# Check if dist directory was created
+if (-not (Test-Path -Path "dist")) {
+ Write-Host ">> dist directory not found, creating it..." -ForegroundColor Yellow
+ New-Item -Path "dist" -ItemType Directory | Out-Null
+ Write-Host "✓ dist directory created" -ForegroundColor Green
+}
+
+# Compile SCSS files
+Write-Host ">> Compiling SCSS files..." -ForegroundColor Yellow
+npx sass sass:css
+if ($LASTEXITCODE -ne 0) {
+ Write-Host "❌ SCSS compilation failed" -ForegroundColor Red
+ Write-Host "If this is your first time running the script, try running 'npm install -D sass' manually." -ForegroundColor Yellow
+ exit
+}
+Write-Host "✓ SCSS files compiled successfully" -ForegroundColor Green
+
+# Check if css directory was created
+if (-not (Test-Path -Path "css")) {
+ Write-Host ">> css directory not found, creating it..." -ForegroundColor Yellow
+ New-Item -Path "css" -ItemType Directory | Out-Null
+ Write-Host "✓ css directory created" -ForegroundColor Green
+}
+
+# Copy files to chrome directory
+Write-Host ">> Copying files to Chrome extension directory..." -ForegroundColor Yellow
+
+# Copy files
+try {
+ if (Test-Path -Path "dist\*") {
+ Copy-Item -Path "dist\*" -Destination "chrome\dist" -Recurse -Force
+ Write-Host "✓ JavaScript files copied" -ForegroundColor Green
+ } else {
+ Write-Host "⚠️ No JavaScript files found to copy" -ForegroundColor Yellow
+ }
+
+ if (Test-Path -Path "css\*") {
+ Copy-Item -Path "css\*" -Destination "chrome\css" -Recurse -Force
+ Write-Host "✓ CSS files copied" -ForegroundColor Green
+ } else {
+ Write-Host "⚠️ No CSS files found to copy" -ForegroundColor Yellow
+ }
+
+ if (Test-Path -Path "view\*") {
+ Copy-Item -Path "view\*" -Destination "chrome\view" -Recurse -Force
+ Write-Host "✓ HTML files copied" -ForegroundColor Green
+ } else {
+ Write-Host "⚠️ No HTML files found to copy" -ForegroundColor Yellow
+ }
+
+ if (Test-Path -Path "_locales\*") {
+ Copy-Item -Path "_locales\*" -Destination "chrome\_locales" -Recurse -Force
+ Write-Host "✓ Localization files copied" -ForegroundColor Green
+ } else {
+ Write-Host "⚠️ No localization files found to copy" -ForegroundColor Yellow
+ }
+
+ if (Test-Path -Path "images\*") {
+ Copy-Item -Path "images\*" -Destination "chrome\images" -Recurse -Force
+ Write-Host "✓ Image files copied" -ForegroundColor Green
+ } else {
+ Write-Host "⚠️ No image files found to copy" -ForegroundColor Yellow
+ }
+
+ # Copy special files
+ if (Test-Path -Path "manifests\manifest-chrome.json") {
+ Copy-Item -Path "manifests\manifest-chrome.json" -Destination "chrome\manifest.json" -Force
+ Write-Host "✓ Manifest file copied" -ForegroundColor Green
+ } else {
+ Write-Host "❌ Manifest file not found: manifests\manifest-chrome.json" -ForegroundColor Red
+ exit
+ }
+
+ if (Test-Path -Path "manifests\manifest-pwa.json") {
+ Copy-Item -Path "manifests\manifest-pwa.json" -Destination "chrome\manifest-pwa.json" -Force
+ Write-Host "✓ PWA Manifest file copied" -ForegroundColor Green
+ } else {
+ Write-Host "⚠️ PWA Manifest file not found: manifests\manifest-pwa.json" -ForegroundColor Yellow
+ }
+
+ if (Test-Path -Path "manifests\schema-chrome.json") {
+ Copy-Item -Path "manifests\schema-chrome.json" -Destination "chrome\schema.json" -Force
+ Write-Host "✓ Schema file copied" -ForegroundColor Green
+ } else {
+ Write-Host "⚠️ Schema file not found: manifests\schema-chrome.json" -ForegroundColor Yellow
+ }
+
+ if (Test-Path -Path "LICENSE") {
+ Copy-Item -Path "LICENSE" -Destination "chrome\LICENSE" -Force
+ Write-Host "✓ LICENSE file copied" -ForegroundColor Green
+ } else {
+ Write-Host "⚠️ LICENSE file not found" -ForegroundColor Yellow
+ }
+
+ if (Test-Path -Path "sass\DroidSansMono.woff2") {
+ Copy-Item -Path "sass\DroidSansMono.woff2" -Destination "chrome\css" -Force
+ Write-Host "✓ Font file copied" -ForegroundColor Green
+ } else {
+ Write-Host "⚠️ Font file not found: sass\DroidSansMono.woff2" -ForegroundColor Yellow
+ }
+}
+catch {
+ Write-Host "❌ File copy failed: $_" -ForegroundColor Red
+ exit
+}
+
+# Build complete
+$extensionPath = (Get-Item -Path ".\chrome").FullName
+Write-Host "`n===== Build Complete =====" -ForegroundColor Cyan
+Write-Host "Chrome extension is ready at:" -ForegroundColor Green
+Write-Host $extensionPath -ForegroundColor Cyan
+Write-Host "`nIn Chrome extensions page (chrome://extensions/), enable Developer mode," -ForegroundColor Green
+Write-Host "then click 'Load unpacked' and select the directory above." -ForegroundColor Green
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 1bb8b48a7..0b842368c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -57,7 +57,7 @@
"vue-svg-loader": "^0.16.0",
"vue-template-compiler": "^2.7.16",
"webpack": "^5.94.0",
- "webpack-cli": "^5.0.0",
+ "webpack-cli": "^5.1.4",
"webpack-merge": "^5.0.0"
}
},
@@ -1559,10 +1559,11 @@
}
},
"node_modules/@webpack-cli/configtest": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz",
- "integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz",
+ "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=14.15.0"
},
@@ -1572,10 +1573,11 @@
}
},
"node_modules/@webpack-cli/info": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz",
- "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz",
+ "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=14.15.0"
},
@@ -1585,10 +1587,11 @@
}
},
"node_modules/@webpack-cli/serve": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.1.tgz",
- "integrity": "sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==",
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz",
+ "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=14.15.0"
},
@@ -9027,17 +9030,18 @@
}
},
"node_modules/webpack-cli": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.1.tgz",
- "integrity": "sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==",
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz",
+ "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@discoveryjs/json-ext": "^0.5.0",
- "@webpack-cli/configtest": "^2.0.1",
- "@webpack-cli/info": "^2.0.1",
- "@webpack-cli/serve": "^2.0.1",
+ "@webpack-cli/configtest": "^2.1.1",
+ "@webpack-cli/info": "^2.0.2",
+ "@webpack-cli/serve": "^2.0.5",
"colorette": "^2.0.14",
- "commander": "^9.4.1",
+ "commander": "^10.0.1",
"cross-spawn": "^7.0.3",
"envinfo": "^7.7.3",
"fastest-levenshtein": "^1.0.12",
@@ -9072,12 +9076,13 @@
}
},
"node_modules/webpack-cli/node_modules/commander": {
- "version": "9.5.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
- "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
"dev": true,
+ "license": "MIT",
"engines": {
- "node": "^12.20.0 || >=14"
+ "node": ">=14"
}
},
"node_modules/webpack-merge": {
diff --git a/package.json b/package.json
index 4970fa5be..32e6b8c2d 100644
--- a/package.json
+++ b/package.json
@@ -60,7 +60,7 @@
"vue-svg-loader": "^0.16.0",
"vue-template-compiler": "^2.7.16",
"webpack": "^5.94.0",
- "webpack-cli": "^5.0.0",
+ "webpack-cli": "^5.1.4",
"webpack-merge": "^5.0.0"
},
"dependencies": {
diff --git a/sass/popup.scss b/sass/popup.scss
index 6849dd8c3..6aace64e4 100644
--- a/sass/popup.scss
+++ b/sass/popup.scss
@@ -414,6 +414,7 @@ svg {
}
.showqr,
+ .favorite,
.pin {
@include themify($themes) {
@include icon-special(20px, themed("grey-2"));
@@ -423,16 +424,30 @@ svg {
top: 10px;
position: absolute;
cursor: pointer;
- opacity: 0;
}
.showqr {
+ right: 60px;
+ opacity: 0;
+ }
+
+ .favorite {
right: 35px;
+ opacity: 0;
+
+ svg.active {
+ fill: #FFC107 !important;
+ }
+ }
+
+ .pin {
+ opacity: 0;
}
&:hover {
.showqr,
- .pin {
+ .pin,
+ .favorite {
opacity: 1;
}
@@ -471,6 +486,22 @@ svg {
*/
}
+.favoriteEntry {
+ .favorite {
+ opacity: 1;
+
+ svg {
+ fill: #FFC107 !important;
+ }
+ }
+
+ @include themify($themes) {
+ background-color: rgba(255, 193, 7, 0.25) !important;
+ border-left: 4px solid #FFC107 !important;
+ padding-left: 6px !important;
+ }
+}
+
.pinnedEntry {
.pin {
opacity: 1;
diff --git a/src/components/Popup/EntryComponent.vue b/src/components/Popup/EntryComponent.vue
index 92099b5b1..3e95bdb39 100644
--- a/src/components/Popup/EntryComponent.vue
+++ b/src/components/Popup/EntryComponent.vue
@@ -6,6 +6,7 @@
v-bind:class="{
entry: true,
pinnedEntry: entry.pinned,
+ favoriteEntry: entry.favorite,
'no-copy': noCopy(entry.code),
}"
v-on:click="copyCode(entry)"
@@ -76,6 +77,9 @@
>