Skip to content

Commit 59b8950

Browse files
authored
Merge pull request #359 from Authenticator-Extension/autolock
Autolock
2 parents 7a0a28e + 7e8ba62 commit 59b8950

File tree

10 files changed

+101
-69
lines changed

10 files changed

+101
-69
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
env: CACHE_NAME=LINTSPACES
1818
- stage: test
1919
name: Build Firefox and run addons-linter
20-
script: npm install --only=production addons-linter && npm run firefox && addons-linter
20+
script: npm install --only=production -g addons-linter && npm run firefox && addons-linter
2121
firefox
2222
env: CACHE_NAME=FIREFOXLINTER
2323
- stage: test

_locales/en/messages.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,12 @@
304304
"loading": {
305305
"message": "Loading..."
306306
},
307+
"autolock": {
308+
"message": "Lock after"
309+
},
310+
"minutes": {
311+
"message": "minutes"
312+
},
307313
"advanced": {
308314
"message": "Advanced"
309315
},

package-lock.json

Lines changed: 10 additions & 33 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/background.ts

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { EntryStorage, ManagedStorage } from "./models/storage";
99
import { Dropbox, Drive } from "./models/backup";
1010

1111
let cachedPassphrase = "";
12+
let autolockTimeout: number;
13+
1214
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
1315
if (message.action === "position") {
1416
if (!sender.tab) {
@@ -23,13 +25,20 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
2325
message.info.windowWidth
2426
);
2527
} else if (message.action === "cachePassphrase") {
28+
document.cookie = `passphrase="${message.value}${getCookieExpiry()}"`;
2629
cachedPassphrase = message.value;
30+
clearTimeout(autolockTimeout);
31+
setAutolock();
2732
} else if (message.action === "passphrase") {
28-
sendResponse(cachedPassphrase);
33+
sendResponse(getCachedPassphrase());
2934
} else if (["dropbox", "drive"].indexOf(message.action) > -1) {
3035
getBackupToken(message.action);
3136
} else if (message.action === "lock") {
3237
cachedPassphrase = "";
38+
document.cookie = 'passphrase=";expires=Thu, 01 Jan 1970 00:00:00 GMT"';
39+
} else if (message.action === "resetAutolock") {
40+
clearTimeout(autolockTimeout);
41+
setAutolock();
3342
}
3443
});
3544

@@ -276,12 +285,12 @@ function getBackupToken(service: string) {
276285
xhr.open(
277286
"POST",
278287
"https://www.googleapis.com/oauth2/v4/token?client_id=" +
279-
getCredentials().drive.client_id +
280-
"&client_secret=" +
281-
getCredentials().drive.client_secret +
282-
"&code=" +
283-
value +
284-
"&redirect_uri=https://authenticator.cc/oauth&grant_type=authorization_code"
288+
getCredentials().drive.client_id +
289+
"&client_secret=" +
290+
getCredentials().drive.client_secret +
291+
"&code=" +
292+
value +
293+
"&redirect_uri=https://authenticator.cc/oauth&grant_type=authorization_code"
285294
);
286295
xhr.setRequestHeader("Accept", "application/json");
287296
xhr.setRequestHeader(
@@ -395,3 +404,42 @@ chrome.commands.onCommand.addListener(async (command: string) => {
395404
break;
396405
}
397406
});
407+
408+
function setAutolock() {
409+
if (Number(localStorage.autolock) > 0) {
410+
document.cookie = `passphrase="${getCachedPassphrase()}${getCookieExpiry()}"`;
411+
autolockTimeout = setTimeout(() => {
412+
cachedPassphrase = "";
413+
}, Number(localStorage.autolock) * 60000);
414+
}
415+
}
416+
417+
function getCookieExpiry() {
418+
if (localStorage.autolock && Number(localStorage.autolock) > 0) {
419+
const offset = Number(localStorage.autolock) * 60000;
420+
const now = new Date().getTime();
421+
const autolockExpiry = new Date(now + offset).toUTCString();
422+
423+
return `;expires=${autolockExpiry}`;
424+
} else {
425+
return "";
426+
}
427+
}
428+
429+
function getCachedPassphrase() {
430+
if (cachedPassphrase) {
431+
return cachedPassphrase;
432+
}
433+
434+
const cookie = document.cookie;
435+
const cookieMatch = cookie
436+
? document.cookie.match(/passphrase=([^;]*)/)
437+
: null;
438+
const cookiePassphrase =
439+
cookieMatch && cookieMatch.length > 1 ? cookieMatch[1] : null;
440+
if (cookiePassphrase) {
441+
return cookiePassphrase;
442+
}
443+
444+
return "";
445+
}

src/components/Popup/MainHeader.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ export default Vue.extend({
100100
this.$store.commit("accounts/stopFilter");
101101
},
102102
lock() {
103-
document.cookie = 'passphrase=";expires=Thu, 01 Jan 1970 00:00:00 GMT"';
104103
chrome.runtime.sendMessage({ action: "lock" }, window.close);
105104
return;
106105
},

src/components/Popup/PrefrencesPage.vue

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@
2424
<label class="combo-label">{{ i18n.use_high_contrast }}</label>
2525
<input class="checkbox" type="checkbox" v-model="useHighContrast" />
2626
</div>
27+
<div style="display: flex;" v-show="encryption.getEncryptionStatus()">
28+
<label style="margin-left: 20px;">{{ i18n.autolock }}</label>
29+
<input
30+
class="input"
31+
type="number"
32+
min="0"
33+
style="width: 70px;"
34+
v-model="autolock"
35+
/>
36+
<span style="margin-top: 10px;">{{ i18n.minutes }}</span>
37+
</div>
2738
<div class="button" v-on:click="popOut()">{{ i18n.popout }}</div>
2839
</div>
2940
</template>
@@ -55,6 +66,18 @@ export default Vue.extend({
5566
set(useHighContrast: boolean) {
5667
this.$store.commit("menu/setHighContrast", useHighContrast);
5768
}
69+
},
70+
encryption(): IEncryption {
71+
return this.$store.state.accounts.encryption;
72+
},
73+
autolock: {
74+
get(): number {
75+
return this.$store.state.menu.autolock;
76+
},
77+
set(autolock: number) {
78+
this.$store.commit("menu/setAutolock", autolock);
79+
chrome.runtime.sendMessage({ action: "resetAutolock" });
80+
}
5881
}
5982
},
6083
methods: {

src/definitions/module-interface.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ interface VuexConstructor {
2929
interface MenuState {
3030
version: String;
3131
zoom: Number;
32+
autolock: Number;
3233
useAutofill: Boolean;
3334
useHighContrast: Boolean;
3435
backupDisabled: Boolean;

src/import.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,6 @@ init();
3232
function getCachedPassphrase() {
3333
return new Promise(
3434
(resolve: (value: string) => void, reject: (reason: Error) => void) => {
35-
const cookie = document.cookie;
36-
const cookieMatch = cookie
37-
? document.cookie.match(/passphrase=([^;]*)/)
38-
: null;
39-
const cachedPassphrase =
40-
cookieMatch && cookieMatch.length > 1 ? cookieMatch[1] : null;
41-
if (cachedPassphrase) {
42-
return resolve(cachedPassphrase);
43-
}
44-
4535
chrome.runtime.sendMessage(
4636
{ action: "passphrase" },
4737
(passphrase: string) => {

src/store/Accounts.ts

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ export class Accounts implements IModule {
163163
state.commit("style/hideInfo", null, { root: true });
164164

165165
if (!state.getters.currentlyEncrypted) {
166-
document.cookie = "passphrase=" + password;
167166
chrome.runtime.sendMessage({
168167
action: "cachePassphrase",
169168
value: password
@@ -181,7 +180,6 @@ export class Accounts implements IModule {
181180
);
182181

183182
state.state.encryption.updateEncryptionPassword(password);
184-
document.cookie = "passphrase=" + password;
185183
chrome.runtime.sendMessage({
186184
action: "cachePassphrase",
187185
value: password
@@ -354,21 +352,6 @@ export class Accounts implements IModule {
354352
private getCachedPassphrase() {
355353
return new Promise(
356354
(resolve: (value: string) => void, reject: (reason: Error) => void) => {
357-
const cookie = document.cookie;
358-
const cookieMatch = cookie
359-
? document.cookie.match(/passphrase=([^;]*)/)
360-
: null;
361-
const cachedPassphrase =
362-
cookieMatch && cookieMatch.length > 1 ? cookieMatch[1] : null;
363-
const cachedPassphraseLocalStorage = localStorage.encodedPhrase
364-
? CryptoJS.AES.decrypt(localStorage.encodedPhrase, "").toString(
365-
CryptoJS.enc.Utf8
366-
)
367-
: "";
368-
if (cachedPassphrase || cachedPassphraseLocalStorage) {
369-
return resolve(cachedPassphrase || cachedPassphraseLocalStorage);
370-
}
371-
372355
chrome.runtime.sendMessage(
373356
{ action: "passphrase" },
374357
(passphrase: string) => {

src/store/Menu.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export class Menu implements IModule {
88
zoom: Number(localStorage.zoom) || 100,
99
useAutofill: localStorage.autofill === "true",
1010
useHighContrast: localStorage.highContrast === "true",
11+
autolock: Number(localStorage.autolock) || 0,
1112
backupDisabled: await ManagedStorage.get("disableBackup"),
1213
storageArea: await ManagedStorage.get("storageArea"),
1314
feedbackURL: await ManagedStorage.get("feedbackURL")
@@ -25,6 +26,10 @@ export class Menu implements IModule {
2526
setHighContrast(state: MenuState, useHighContrast: boolean) {
2627
state.useHighContrast = useHighContrast;
2728
localStorage.highContrast = useHighContrast;
29+
},
30+
setAutolock(state: MenuState, autolock: number) {
31+
state.autolock = autolock;
32+
localStorage.autolock = autolock;
2833
}
2934
},
3035
namespaced: true

0 commit comments

Comments
 (0)