Subversion-Projekte lars-tiefland.cienc

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
5 lars 1
/*
2
 * bootstrap-session-timeout
3
 * www.orangehilldev.com
4
 *
5
 * Copyright (c) 2014 Vedran Opacic
6
 * Licensed under the MIT license.
7
 */
8
 
9
(function($) {
10
    /*jshint multistr: true */
11
    'use strict';
12
    $.sessionTimeout = function(options) {
13
        var defaults = {
14
            title: 'Your Session is About to Expire!',
15
            message: 'Your session is about to expire.',
16
            logoutButton: 'Logout',
17
            keepAliveButton: 'Stay Connected',
18
            keepAliveUrl: '/keep-alive',
19
            ajaxType: 'POST',
20
            ajaxData: '',
21
            redirUrl: '/timed-out',
22
            logoutUrl: '/log-out',
23
            warnAfter: 900000, // 15 minutes
24
            redirAfter: 1200000, // 20 minutes
25
            keepAliveInterval: 5000,
26
            keepAlive: true,
27
            ignoreUserActivity: false,
28
            onStart: false,
29
            onWarn: false,
30
            onRedir: false,
31
            countdownMessage: false,
32
            countdownBar: false,
33
            countdownSmart: false
34
        };
35
 
36
        var opt = defaults,
37
            timer,
38
            countdown = {};
39
 
40
        // Extend user-set options over defaults
41
        if (options) {
42
            opt = $.extend(defaults, options);
43
        }
44
 
45
        // Some error handling if options are miss-configured
46
        if (opt.warnAfter >= opt.redirAfter) {
47
            console.error('Bootstrap-session-timeout plugin is miss-configured. Option "redirAfter" must be equal or greater than "warnAfter".');
48
            return false;
49
        }
50
 
51
        // Unless user set his own callback function, prepare bootstrap modal elements and events
52
        if (typeof opt.onWarn !== 'function') {
53
            // If opt.countdownMessage is defined add a coundown timer message to the modal dialog
54
            var countdownMessage = opt.countdownMessage ?
55
                '<p>' + opt.countdownMessage.replace(/{timer}/g, '<span class="countdown-holder"></span>') + '</p>' : '';
56
            var coundownBarHtml = opt.countdownBar ?
57
                '<div class="progress"> \
58
                  <div class="progress-bar progress-bar-striped countdown-bar active" role="progressbar" style="min-width: 15px; width: 100%;"> \
59
                    <span class="countdown-holder"></span> \
60
                  </div> \
61
                </div>' : '';
62
 
63
            // Create timeout warning dialog
64
            $('body').append('<div class="modal fade" id="session-timeout-dialog"> \
65
              <div class="modal-dialog"> \
66
                <div class="modal-content"> \
67
                  <div class="modal-header"> \
68
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button> \
69
                    <h4 class="modal-title">' + opt.title + '</h4> \
70
                  </div> \
71
                  <div class="modal-body"> \
72
                    <p>' + opt.message + '</p> \
73
                    ' + countdownMessage + ' \
74
                    ' + coundownBarHtml + ' \
75
                  </div> \
76
                  <div class="modal-footer"> \
77
                    <button id="session-timeout-dialog-logout" type="button" class="btn btn-default">' + opt.logoutButton + '</button> \
78
                    <button id="session-timeout-dialog-keepalive" type="button" class="btn btn-primary" data-dismiss="modal">' + opt.keepAliveButton + '</button> \
79
                  </div> \
80
                </div> \
81
              </div> \
82
             </div>');
83
 
84
            // "Logout" button click
85
            $('#session-timeout-dialog-logout').on('click', function() {
86
                window.location = opt.logoutUrl;
87
            });
88
            // "Stay Connected" button click
89
            $('#session-timeout-dialog').on('hide.bs.modal', function() {
90
                // Restart session timer
91
                startSessionTimer();
92
            });
93
        }
94
 
95
        // Reset timer on any of these events
96
        if (!opt.ignoreUserActivity) {
97
            var mousePosition = [-1, -1];
98
            $(document).on('keyup mouseup mousemove touchend touchmove', function(e) {
99
                if (e.type === 'mousemove') {
100
                    // Solves mousemove even when mouse not moving issue on Chrome:
101
                    // https://code.google.com/p/chromium/issues/detail?id=241476
102
                    if (e.clientX === mousePosition[0] && e.clientY === mousePosition[1]) {
103
                        return;
104
                    }
105
                    mousePosition[0] = e.clientX;
106
                    mousePosition[1] = e.clientY;
107
                }
108
                startSessionTimer();
109
 
110
                // If they moved the mouse not only reset the counter
111
                // but remove the modal too!
112
                if ($('#session-timeout-dialog').length > 0 &&
113
                    $('#session-timeout-dialog').data('bs.modal') &&
114
                    $('#session-timeout-dialog').data('bs.modal').isShown) {
115
                    // http://stackoverflow.com/questions/11519660/twitter-bootstrap-modal-backdrop-doesnt-disappear
116
                    $('#session-timeout-dialog').modal('hide');
117
                    $('body').removeClass('modal-open');
118
                    $('div.modal-backdrop').remove();
119
 
120
                }
121
            });
122
        }
123
 
124
        // Keeps the server side connection live, by pingin url set in keepAliveUrl option.
125
        // KeepAlivePinged is a helper var to ensure the functionality of the keepAliveInterval option
126
        var keepAlivePinged = false;
127
 
128
        function keepAlive() {
129
            if (!keepAlivePinged) {
130
                // Ping keepalive URL using (if provided) data and type from options
131
                $.ajax({
132
                    type: opt.ajaxType,
133
                    url: opt.keepAliveUrl,
134
                    data: opt.ajaxData
135
                });
136
                keepAlivePinged = true;
137
                setTimeout(function() {
138
                    keepAlivePinged = false;
139
                }, opt.keepAliveInterval);
140
            }
141
        }
142
 
143
        function startSessionTimer() {
144
            // Clear session timer
145
            clearTimeout(timer);
146
            if (opt.countdownMessage || opt.countdownBar) {
147
                startCountdownTimer('session', true);
148
            }
149
 
150
            if (typeof opt.onStart === 'function') {
151
                opt.onStart(opt);
152
            }
153
 
154
            // If keepAlive option is set to "true", ping the "keepAliveUrl" url
155
            if (opt.keepAlive) {
156
                keepAlive();
157
            }
158
 
159
            // Set session timer
160
            timer = setTimeout(function() {
161
                // Check for onWarn callback function and if there is none, launch dialog
162
                if (typeof opt.onWarn !== 'function') {
163
                    $('#session-timeout-dialog').modal('show');
164
                } else {
165
                    opt.onWarn(opt);
166
                }
167
                // Start dialog timer
168
                startDialogTimer();
169
            }, opt.warnAfter);
170
        }
171
 
172
        function startDialogTimer() {
173
            // Clear session timer
174
            clearTimeout(timer);
175
            if (!$('#session-timeout-dialog').hasClass('in') && (opt.countdownMessage || opt.countdownBar)) {
176
                // If warning dialog is not already open and either opt.countdownMessage
177
                // or opt.countdownBar are set start countdown
178
                startCountdownTimer('dialog', true);
179
            }
180
            // Set dialog timer
181
            timer = setTimeout(function() {
182
                // Check for onRedir callback function and if there is none, launch redirect
183
                if (typeof opt.onRedir !== 'function') {
184
                    window.location = opt.redirUrl;
185
                } else {
186
                    opt.onRedir(opt);
187
                }
188
            }, (opt.redirAfter - opt.warnAfter));
189
        }
190
 
191
        function startCountdownTimer(type, reset) {
192
            // Clear countdown timer
193
            clearTimeout(countdown.timer);
194
 
195
            if (type === 'dialog' && reset) {
196
                // If triggered by startDialogTimer start warning countdown
197
                countdown.timeLeft = Math.floor((opt.redirAfter - opt.warnAfter) / 1000);
198
            } else if (type === 'session' && reset) {
199
                // If triggered by startSessionTimer start full countdown
200
                // (this is needed if user doesn't close the warning dialog)
201
                countdown.timeLeft = Math.floor(opt.redirAfter / 1000);
202
            }
203
            // If opt.countdownBar is true, calculate remaining time percentage
204
            if (opt.countdownBar && type === 'dialog') {
205
                countdown.percentLeft = Math.floor(countdown.timeLeft / ((opt.redirAfter - opt.warnAfter) / 1000) * 100);
206
            } else if (opt.countdownBar && type === 'session') {
207
                countdown.percentLeft = Math.floor(countdown.timeLeft / (opt.redirAfter / 1000) * 100);
208
            }
209
            // Set countdown message time value
210
            var countdownEl = $('.countdown-holder');
211
            var secondsLeft = countdown.timeLeft >= 0 ? countdown.timeLeft : 0;
212
            if (opt.countdownSmart) {
213
                var minLeft = Math.floor(secondsLeft / 60);
214
                var secRemain = secondsLeft % 60;
215
                var countTxt = minLeft > 0 ? minLeft + 'm' : '';
216
                if (countTxt.length > 0) {
217
                    countTxt += ' ';
218
                }
219
                countTxt += secRemain + 's';
220
                countdownEl.text(countTxt);
221
            } else {
222
                countdownEl.text(secondsLeft + "s");
223
            }
224
 
225
            // Set countdown message time value
226
            if (opt.countdownBar) {
227
                $('.countdown-bar').css('width', countdown.percentLeft + '%');
228
            }
229
 
230
            // Countdown by one second
231
            countdown.timeLeft = countdown.timeLeft - 1;
232
            countdown.timer = setTimeout(function() {
233
                // Call self after one second
234
                startCountdownTimer(type);
235
            }, 1000);
236
        }
237
 
238
        // Start session timer
239
        startSessionTimer();
240
 
241
    };
242
})(jQuery);