1 /***************************************************************
4 * (c) 2009-2010 Steffen Kamper <info@sk-typo3.de>
7 * This script is part of the TYPO3 project. The TYPO3 project is
8 * free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * The GNU General Public License can be found at
14 * http://www.gnu.org/copyleft/gpl.html.
15 * A copy is found in the textfile GPL.txt and important notices to the license
16 * from the author is found in LICENSE.txt distributed with these scripts.
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
28 * AJAX login refresh box
30 Ext
.namespace('Ext.ux.TYPO3');
32 Ext
.ux
.TYPO3
.loginRefresh
= Ext
.extend(Ext
.util
.Observable
, {
36 constructor: function(config
) {
37 config
= config
|| {};
38 Ext
.apply(this, config
);
39 this.initComponents();
46 "ajaxID": "BackendLogin::isTimedOut",
47 "skipSessionUpdate": 1
50 success: function(response
, options
) {
51 var result
= Ext
.util
.JSON
.decode(response
.responseText
);
52 if (result
.login
.locked
) {
55 title
: TYPO3
.LLL
.core
.please_wait
,
56 msg
: TYPO3
.LLL
.core
.be_locked
,
58 icon
: Ext
.MessageBox
.INFO
,
62 if (this.locked
=== 1) {
64 Ext
.MessageBox
.hide();
67 if ((result
.login
.timed_out
|| result
.login
.will_time_out
) && Ext
.getCmp("loginformWindow")) {
68 Ext
.getCmp("login_username").value
= TYPO3
.configuration
.username
;
70 if (result
.login
.timed_out
) {
73 this.progressWindow
.show();
83 interval
: this.interval
* 1000,
87 Ext
.ux
.TYPO3
.loginRefresh
.superclass
.constructor.call(this, config
);
90 initComponents: function() {
91 var loginPanel
= new Ext
.FormPanel({
94 title
: TYPO3
.LLL
.core
.refresh_login_title
,
95 defaultType
: 'textfield',
98 bodyStyle
: "padding: 5px 5px 3px 5px; border-width: 0; margin-bottom: 7px;",
102 bodyStyle
: "margin-bottom: 7px; border: none;",
103 html
: TYPO3
.LLL
.core
.login_expired
105 fieldLabel
: TYPO3
.LLL
.core
.refresh_login_password
,
109 inputType
: "password"
113 id
: "login_username",
128 key
: Ext
.EventObject
.ENTER
,
129 fn
: this.triggerSubmitForm
,
133 text
: TYPO3
.LLL
.core
.refresh_login_button
,
135 handler
: this.triggerSubmitForm
137 text
: TYPO3
.LLL
.core
.refresh_logout_button
,
139 handler: function() {
140 top
.location
.href
= TYPO3
.configuration
.siteUrl
+ TYPO3
.configuration
.TYPO3_mainDir
+ "logout.php";
144 this.loginRefreshWindow
= new Ext
.Window({
145 id
: "loginformWindow",
156 activate: function() {
157 Ext
.getCmp('password').focus(false, 800);
162 var progressControl
= new Ext
.ProgressBar({
168 this.progressWindow
= new Ext
.Window({
173 id
: "loginRefreshWindow",
176 bodyStyle
: "padding: 5px 5px 3px 5px; border-width: 0; margin-bottom: 7px;",
180 html
: TYPO3
.LLL
.core
.login_about_to_expire
184 title
: TYPO3
.LLL
.core
.login_about_to_expire_title
,
188 text
: TYPO3
.LLL
.core
.refresh_login_refresh_button
,
189 handler: function() {
190 var refresh
= Ext
.Ajax
.request({
193 "ajaxID": "BackendLogin::isTimedOut"
198 TYPO3
.loginRefresh
.progressWindow
.hide();
199 progressControl
.reset();
200 TYPO3
.loginRefresh
.startTimer();
203 text
: TYPO3
.LLL
.core
.refresh_direct_logout_button
,
204 handler: function() {
205 top
.location
.href
= TYPO3
.configuration
.siteUrl
+ TYPO3
.configuration
.TYPO3_mainDir
+ "logout.php";
209 this.progressWindow
.on('show', function(){
210 progressControl
.wait({
214 text
: String
.format(TYPO3
.LLL
.core
.refresh_login_countdown
, '30'),
216 TYPO3
.loginRefresh
.showLoginForm();
221 progressControl
.on('update', function(control
, value
, text
) {
222 var rest
= parseInt(30 - (value
* 30), 10);
224 control
.updateText(String
.format(TYPO3
.LLL
.core
.refresh_login_countdown_singular
, rest
));
226 control
.updateText(String
.format(TYPO3
.LLL
.core
.refresh_login_countdown
, rest
));
230 this.loginRefreshWindow
.on('close', function(){
231 TYPO3
.loginRefresh
.startTimer();
235 showLoginForm: function() {
236 if (TYPO3
.configuration
.showRefreshLoginPopup
) {
241 "ajaxID": "BackendLogin::logout"
245 success: function(response
, opts
) {
246 TYPO3
.loginRefresh
.showLoginPopup();
248 failure: function(response
, opts
) {
249 alert("something went wrong");
253 Ext
.getCmp("loginRefreshWindow").hide();
254 Ext
.getCmp("loginformWindow").show();
258 showLoginPopup: function() {
259 Ext
.getCmp("loginRefreshWindow").hide();
260 var vHWin
= window
.open("login_frameset.php","relogin_" + TS
.uniqueID
,"height=450,width=700,status=0,menubar=0,location=1");
264 startTimer: function() {
265 Ext
.TaskMgr
.start(this.loadingTask
);
268 stopTimer: function() {
269 Ext
.TaskMgr
.stop(this.loadingTask
);
272 submitForm: function(challenge
) {
273 var form
= Ext
.getCmp("loginform").getForm();
274 var fields
= form
.getValues();
275 if (fields
.p_field
=== "") {
276 Ext
.Msg
.alert(TYPO3
.LLL
.core
.refresh_login_failed
, TYPO3
.LLL
.core
.refresh_login_emptyPassword
);
278 if (TS
.securityLevel
=== "superchallenged") {
279 fields
.p_field
= MD5(fields
.p_field
);
281 if (TS
.securityLevel
=== "superchallenged" || TS
.securityLevel
=== "challenged") {
282 fields
.challenge
= challenge
;
283 fields
.userident
= MD5(fields
.username
+ ":" + fields
.p_field
+ ":" + challenge
);
285 fields
.userident
= fields
.p_field
;
288 form
.setValues(fields
);
292 waitTitle
: TYPO3
.LLL
.core
.waitTitle
,
295 "ajaxID": "BackendLogin::login",
296 "login_status": "login"
298 success: function(form
, action
) {
299 // response object is "login" so real result will be available in failure handler
300 Ext
.getCmp("loginformWindow").hide();
301 TYPO3
.loginRefresh
.startTimer();
303 failure: function(form
, action
) {
304 var result
= Ext
.util
.JSON
.decode(action
.response
.responseText
).login
;
305 if (result
.success
) {
307 Ext
.getCmp("loginformWindow").hide();
308 TYPO3
.loginRefresh
.startTimer();
309 TYPO3
.loginRefresh
.refreshTokens(result
.accessToken
);
311 // TODO: add failure to notification system instead of alert
312 Ext
.Msg
.alert(TYPO3
.LLL
.core
.refresh_login_failed
, TYPO3
.LLL
.core
.refresh_login_failed_message
);
319 triggerSubmitForm: function() {
320 if (TS
.securityLevel
=== 'superchallenged' || TS
.securityLevel
=== 'challenged') {
324 'ajaxID': 'BackendLogin::getChallenge',
325 'skipSessionUpdate': 1
328 success: function(response
) {
329 var result
= Ext
.util
.JSON
.decode(response
.responseText
);
330 if (result
.challenge
) {
331 Ext
.getCmp('challenge').value
= result
.challenge
;
332 TYPO3
.loginRefresh
.submitForm(result
.challenge
);
342 getOutdatedTokens: function() {
344 var searchTokenPlaces
= [top
, top
.content
.document
];
346 if (top
.nav
instanceof TYPO3
.iframePanel
) {
347 searchTokenPlaces
.push(top
.nav
.getIframe());
350 Ext
.each(searchTokenPlaces
, function(searchPlace
) {
351 var links
= searchPlace
.Ext
.query('a[href*=formToken]');
352 Ext
.each(links
, function(linkTag
) {
353 tokens
.push(Ext
.urlDecode(linkTag
.href
).formToken
);
356 var formFields
= searchPlace
.Ext
.query("form input[name=formToken]");
357 Ext
.each(formFields
, function(inputField
) {
358 tokens
.push(inputField
.value
);
361 var linksOnclick
= searchPlace
.Ext
.query('a[onclick*=formToken]');
362 Ext
.each(linksOnclick
, function(linkTag
) {
363 tokens
.push(linkTag
.attributes
.onclick
.value
.match(/&formToken=([^&]*)&/).pop());
366 if (Ext
.isString(searchPlace
.TYPO3
.ExtDirectToken
)) {
367 tokens
.push(searchPlace
.TYPO3
.ExtDirectToken
);
375 replaceOutdatedTokens: function(newTokens
) {
376 var searchTokenPlaces
= [top
, top
.content
.document
];
378 if (top
.nav
instanceof TYPO3
.iframePanel
) {
379 searchTokenPlaces
.push(top
.nav
.getIframe());
382 Ext
.each(searchTokenPlaces
, function(searchPlace
) {
383 var links
= searchPlace
.Ext
.query('a[href*=formToken]');
384 Ext
.each(links
, function(linkTag
) {
385 var url
= Ext
.urlDecode(linkTag
.href
);
386 url
.formToken
= newTokens
[url
.formToken
];
387 linkTag
.href
= unescape(Ext
.urlEncode(url
));
390 var formFields
= searchPlace
.Ext
.query("form input[name=formToken]");
391 Ext
.each(formFields
, function(inputField
) {
392 inputField
.value
= newTokens
[inputField
.value
];
395 var linksOnclick
= searchPlace
.Ext
.query('a[onclick*=formToken]');
396 Ext
.each(linksOnclick
, function(linkTag
) {
397 var token
= linkTag
.attributes
.onclick
.value
.match(/&formToken=([^&]*)&/).pop();
398 linkTag
.attributes
.onclick
.value
= linkTag
.attributes
.onclick
.value
.replace(new RegExp(token
), newTokens
[token
]);
401 if (Ext
.isString(searchPlace
.TYPO3
.ExtDirectToken
)) {
402 searchPlace
.TYPO3
.ExtDirectToken
= newTokens
[searchPlace
.TYPO3
.ExtDirectToken
];
407 refreshTokens: function(accessToken
) {
411 "ajaxID": "BackendLogin::refreshTokens",
412 "accessToken": accessToken
,
413 "tokens": Ext
.encode(this.getOutdatedTokens())
417 success: function(response
, opts
) {
418 var result
= Ext
.util
.JSON
.decode(response
.responseText
);
419 TYPO3
.loginRefresh
.replaceOutdatedTokens(result
.newTokens
);
421 failure: function(response
, opts
) {
422 TYPO3
.Flashmessage
.display(
423 TYPO3
.Severity
.error
,
425 'Refreshing tokens after relogin faild. Please reload the backend.',
437 * Initialize login expiration warning object
439 Ext
.onReady(function() {
440 TYPO3
.loginRefresh
= new Ext
.ux
.TYPO3
.loginRefresh();