Completed
Push — master ( 4e8691...51d7d6 )
by Sander
55s
created

js/background/inject/inject.js (2 issues)

Check to flag assignments that are superseded in all possible execution paths

Unused Code Minor
1
/* global API */
2
var $j = jQuery.noConflict();
3
4
$j(document).ready(function () {
5
6
    $j(document).click(function (event) {
7
        var passwordPickerRef = '.passwordPickerIframe';
8
        if (!$j(event.target).closest(passwordPickerRef).length) {
9
            if ($j(passwordPickerRef).is(":visible")) {
10
                removePasswordPicker();
11
            }
12
        }
13
    });
14
15
    var _this = this;
16
    Array.prototype.findUrl = function (match) {
17
        return this.filter(function (item) {
18
            return typeof item === 'string' && item.indexOf(match) > -1;
19
        });
20
    };
21
22
    function removePasswordPicker() {
23
        activeForm = undefined;
24
        $j('.passwordPickerIframe').remove();
25
    }
26
27
    _this.removePasswordPicker = removePasswordPicker;
28
29
    function enterLoginDetails(login, allowSubmit) {
30
        var username;
31
32
        if (login.hasOwnProperty('username')) {
33
            username = (login.username !== '' ) ? login.username : login.email;
34
        }
35
        if (!username) {
36
            username = null;
37
        }
38
39
        fillPassword(username, login.password);
40
41
        if (activeForm) {
42
            API.runtime.sendMessage(API.runtime.id, {method: 'isAutoSubmitEnabled'}).then(function (isEnabled) {
43
                if (isEnabled && allowSubmit) {
44
                    submitLoginForm(username);
45
                }
46
            });
47
        }
48
    }
49
50
    _this.enterLoginDetails = enterLoginDetails;
51
52
    function submitLoginForm(username) {
53
        if (!activeForm) {
54
            // @TODO detect login form on the current page
55
            return;
56
        }
57
58
        var formEl = $j(activeForm).closest('form');
59
        var iframeUrl = API.extension.getURL('/html/inject/auto_login.html');
60
        $j('#loginPopupIframe').remove();
61
        var loginPopup = $j('<iframe class="loginPopupIframe" scrolling="no" frameborder="0" src="' + iframeUrl + '"></iframe>');
62
        var padding = parseInt($j(formEl).css('padding').replace('px', ''));
63
        var margin = parseInt($j(formEl).css('margin').replace('px', ''));
64
        var height = Math.round($j(formEl).height() + (padding * 2) + (margin * 2));
65
        var width = Math.round($j(formEl).width() + (padding * 2) + (margin * 2));
66
        loginPopup.attr('height', height);
67
        loginPopup.attr('width', width);
68
        loginPopup.css('position', 'absolute');
69
        loginPopup.css('z-index', getMaxZ() + 1);
70
        loginPopup.css('background-color', 'rgba(0, 0, 0, 0.73)');
71
        loginPopup.css('left', Math.floor($j(formEl).offset().left - padding - margin));
72
        loginPopup.css('top', Math.floor($j(formEl).offset().top - padding - margin));
73
        removePasswordPicker();
74
        $j(document.body).prepend(loginPopup);
75
        API.runtime.sendMessage(API.runtime.id, {'setIframeUsername': username}).then(function () {
76
            $j(formEl).submit();
77
            setTimeout(function () {
78
                loginPopup.remove();
79
            }, 2000);
80
        });
81
    }
82
83
    function getMaxZ() {
84
        return Math.max.apply(null,
85
            $j.map($j('body *'), function (e) {
86
                if ($j(e).css('position') !== 'static')
87
                    return parseInt($j(e).css('z-index')) || 1;
88
            }));
89
    }
90
91
    var activeForm;
92
93
    function showPasswordPicker(form) {
94
        var jPasswordPicker = $j('.passwordPickerIframe');
95
        if (jPasswordPicker.length > 1) {
96
            return;
97
        }
98
        var loginField = $j(form[0]);
99
        var loginFieldPos = loginField.offset();
100
        var loginFieldVisible = loginField.is(':visible');
101
102
        var position = $j(form[1]).position();
0 ignored issues
show
The assignment to variable position seems to be never used. Consider removing it.
Loading history...
103
        var passwordField = $j(form[1]);
104
        var passwordFieldPos = passwordField.offset();
105
        var passwordFieldVisible = loginField.is(':visible');
106
        var left = (loginFieldPos) ? loginFieldPos.left : passwordFieldPos.left;
107
        var top = (loginFieldPos) ? loginFieldPos.top : passwordFieldPos.top;
108
        var maxZ = getMaxZ();
109
110
        if (loginFieldPos && passwordFieldPos.top > loginFieldPos.top) {
111
            //console.log('login fields below each other')
112
            top = passwordFieldPos.top + passwordField.height() + 10;
113
        } else {
114
            // console.log('login fields next to each other')
115
            if (loginFieldPos) {
116
                top = top + loginField.height() + 10;
117
            } else {
118
                top = top + passwordField.height() + 10;
119
            }
120
        }
121
        if (!loginFieldVisible) {
122
            left = passwordFieldPos.left;
123
        }
124
125
        var pickerUrl = API.extension.getURL('/html/inject/password_picker.html');
126
127
        var picker = $j('<iframe class="passwordPickerIframe" scrolling="no" height="385" width="350" frameborder="0" src="' + pickerUrl + '"></iframe>');
128
        picker.css('position', 'absolute');
129
        picker.css('left', left);
130
        picker.css('z-index', maxZ + 10);
131
        picker.css('top', top);
132
        $j('body').prepend($j(picker));
133
        activeForm = form;
134
        // picker.css('width', $j(form).width());
135
        $j('.passwordPickerIframe:not(:last)').remove();
136
    }
137
138
    function onFormIconClick(e) {
139
        e.preventDefault();
140
        e.stopPropagation();
141
        var offsetX = e.offsetX;
142
        var offsetRight = (e.data.width - offsetX);
143
        if (offsetRight < e.data.height) {
144
            showPasswordPicker(e.data.form);
145
        }
146
    }
147
148
    function createFormIcon(el, form) {
149
        var offset = el.offset();
0 ignored issues
show
The assignment to variable offset seems to be never used. Consider removing it.
Loading history...
150
        var width = el.width();
151
        var height = el.height() * 1;
152
        var margin = (el.css('margin')) ? parseInt(el.css('margin').replace('px', '')) : 0;
153
        var padding = (el.css('padding')) ? parseInt(el.css('padding').replace('px', '')) : 0;
154
155
        var pickerIcon = API.extension.getURL('/icons/icon.svg');
156
        $j(el).css('background-image', 'url("' + pickerIcon + '")');
157
        $j(el).css('background-repeat', 'no-repeat');
158
        //$j(el).css('background-position', '');
159
        $j(el).css('cssText', el.attr('style') + ' background-position: right 3px center !important;');
160
161
        $j(el).unbind('click', onFormIconClick);
162
        $j(el).click({width: width, height: height, form: form}, onFormIconClick);
163
    }
164
165
    function createPasswordPicker(form) {
166
        for (var i = 0; i < form.length; i++) {
167
            var el = $j(form[i]);
168
            createFormIcon(el, form);
169
        }
170
    }
171
172
    function formSubmitted(fields) {
173
        var user = fields[0].value;
174
        var pass = fields[1].value;
175
        var params = {
176
            username: user,
177
            password: pass
178
        };
179
        //Disable password mining
180
        //$j(fields[1]).attr('type', 'hidden');
181
        API.runtime.sendMessage(API.runtime.id, {method: "minedForm", args: params});
182
183
    }
184
185
    function inIframe() {
186
        try {
187
            return window.self !== window.top;
188
        } catch (e) {
189
            return true;
190
        }
191
    }
192
193
    function showDoorhanger(data) {
194
        if (inIframe()) {
195
            return;
196
        }
197
        data.data.currentLocation = window.location.href;
198
        API.runtime.sendMessage(API.runtime.id, {method: "setDoorhangerData", args: data});
199
        var pickerUrl = API.extension.getURL('/html/inject/doorhanger.html');
200
201
        var doorhanger = $j('<iframe id="password-toolbarIframe" style="display: none;" scrolling="no" height="60" width="100%" frameborder="0" src="' + pickerUrl + '"></iframe>');
202
        $j('#password-toolbarIframe').remove();
203
        doorhanger.css('z-index', getMaxZ() + 1);
204
        $j('body').prepend(doorhanger);
205
        $j('#password-toolbarIframe').fadeIn();
206
    }
207
208
    _this.showDoorhanger = showDoorhanger;
209
210
    function showUrlUpdateDoorhanger(data) {
211
        var buttons = ['cancel', 'updateUrl'];
212
        showDoorhanger({
213
            data: data.data,
214
            buttons: buttons
215
        });
216
    }
217
218
    _this.showUrlUpdateDoorhanger = showUrlUpdateDoorhanger;
219
220
    function checkForMined() {
221
        if (inIframe()) {
222
            return;
223
        }
224
225
        API.runtime.sendMessage(API.runtime.id, {method: "getMinedData"}).then(function (data) {
226
            if (!data) {
227
                return;
228
            }
229
            if (data.hasOwnProperty('username') && data.hasOwnProperty('password') && data.hasOwnProperty('url')) {
230
                var buttons = ['cancel', 'ignore', 'save'];
231
                showDoorhanger({data: data, buttons: buttons});
232
            }
233
        });
234
    }
235
236
237
    function closeDoorhanger() {
238
        $j('#password-toolbarIframe').hide(400);
239
        $j('#password-toolbarIframe').remove();
240
    }
241
242
    _this.closeDoorhanger = closeDoorhanger;
243
244
    function initForms() {
245
        API.runtime.sendMessage(API.runtime.id, {method: 'getRuntimeSettings'}).then(function (settings) {
246
            var enablePasswordPicker = settings.enablePasswordPicker;
247
            var url = window.location.href;
248
            var loginFields = getLoginFields();
249
            if (loginFields.length > 0) {
250
                for (var i = 0; i < loginFields.length; i++) {
251
                    var form = getFormFromElement(loginFields[i][0]);
252
                    if (enablePasswordPicker) {
253
                        createPasswordPicker(loginFields[i], form);
254
                    }
255
                    //Password miner
256
                    /* jshint ignore:start */
257
                    if (!settings.hasOwnProperty('ignored_sites') || settings.ignored_sites.findUrl(url) !== -1) {
258
                        $j(form).submit((function (loginFields) {
259
                            return function () {
260
                                formSubmitted(loginFields);
261
                            };
262
                        })(loginFields[i]));
263
                    }
264
                    /* jshint ignore:end */
265
                }
266
267
                API.runtime.sendMessage(API.runtime.id, {
268
                    method: "getCredentialsByUrl",
269
                    args: url
270
                }).then(function (logins) {
271
                    console.log('Found ' + logins.length + ' logins for this site');
272
                    if (logins.length === 1) {
273
                        API.runtime.sendMessage(API.runtime.id, {method: 'isAutoFillEnabled'}).then(function (isEnabled) {
274
                            if (isEnabled) {
275
                                enterLoginDetails(logins[0], false);
276
                            }
277
                        });
278
                    }
279
280
                });
281
            }
282
283
        });
284
    }
285
286
    function minedLoginSaved(args) {
287
        // If the login added by the user then this is true
288
        if (args.selfAdded) {
289
            enterLoginDetails(args.credential, false);
290
        }
291
    }
292
293
    _this.minedLoginSaved = minedLoginSaved;
294
295
    function resizeIframe(height) {
296
        $j('#password-toolbarIframe').height(60 + height);
297
    }
298
299
    _this.resizeIframe = resizeIframe;
300
301
    function copyText(text) {
302
        var txtToCopy = document.createElement('input');
303
        txtToCopy.style.left = '-300px';
304
        txtToCopy.style.position = 'absolute';
305
        txtToCopy.value = text;
306
        document.body.appendChild(txtToCopy);
307
        txtToCopy.select();
308
        document.execCommand('copy');
309
        txtToCopy.parentNode.removeChild(txtToCopy);
310
    }
311
312
    _this.copyText = copyText;
313
314
    function init() {
315
        checkForMined();
316
        initForms();
317
    }
318
319
    var readyStateCheckInterval = setInterval(function () {
320
        if (document.readyState === "complete") {
321
            clearInterval(readyStateCheckInterval);
322
            API.runtime.sendMessage(API.runtime.id, {method: 'getMasterPasswordSet'}).then(function (result) {
323
                if (result) {
324
                    init();
325
                    var body = document.getElementsByTagName('body')[0];
326
                    observeDOM(body, initForms);
327
                } else {
328
                    console.log('[Passman extension] Stopping, vault key not set');
329
                }
330
            });
331
        }
332
    }, 10);
333
334
    API.runtime.onMessage.addListener(function (msg, sender) {
335
        //console.log('Method call', msg.method);
336
        if (_this[msg.method]) {
337
            _this[msg.method](msg.args, sender);
338
        }
339
    });
340
});
341