Skip to content

Warn users that their tokens have expired #4634

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion frontend/src/js/controllers/profileCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@
vm.jsonResponse = response.data;
vm.token = response.data['token'];
vm.expiresAt = moment.utc(response.data['expires_at']).local().format("MMM D, YYYY h:mm:ss A");
var expirationDateStr = response.data['expires_at'];
var expirationDate = new Date(expirationDateStr);
var currentDate = new Date();
if (expirationDate < currentDate) {
vm.showTokenExpiredDialog();
}
let expiresAtOffset = new Date(vm.expiresAt).getTimezoneOffset();
var timezone = moment.tz.guess();
vm.expiresAtTimezone = moment.tz.zone(timezone).abbr(expiresAtOffset);
Expand Down Expand Up @@ -182,7 +188,24 @@
}
return (url.length <= 200);
};


vm.showTokenExpiredDialog = function() {
$mdDialog.show({
templateUrl: 'dist/views/web/auth/auth-token-expired-dialog.html',
controller: ['$scope', '$mdDialog', function($scope, $mdDialog) {
$scope.refreshToken = function() {
$mdDialog.hide();
vm.refreshToken();
};

$scope.dismiss = function() {
$mdDialog.hide();
};
}]
});

};

vm.editprofileDialog = function(ev) {
switch (ev.currentTarget.id) {
case "first_name":
Expand Down
16 changes: 16 additions & 0 deletions frontend/src/views/web/auth/auth-token-expired-dialog.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<md-dialog class="ev-md-container ev-card-body update-profile-card">
<md-dialog-content class="ev-card-body">
<h4 class="pass-title">Auth Token Expired</h4>
<p class="text-light-black">
Your authentication token has expired. Please refresh it to continue.
</p>
</md-dialog-content>
<md-dialog-actions class="align-left reg-control">
<md-button class="dark-link pointer" ng-click="dismiss()">
Cancel
</md-button>
<md-button class="btn ev-btn-dark waves-effect waves-dark grad-btn grad-btn-dark fs-14" ng-click="refreshToken()">
Refresh
</md-button>
</md-dialog-actions>
</md-dialog>
81 changes: 81 additions & 0 deletions frontend/tests/controllers-test/profileCtrl.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -313,4 +313,85 @@ describe('Unit tests for profile controller', function () {
expect($rootScope.notify).toHaveBeenCalledWith("error", errorResponse.error);
});
});

describe('Unit tests for isURLValid function', function () {
it('should allow empty URLs', function () {
var result = vm.isURLValid('');
expect(result).toBeTruthy();

result = vm.isURLValid(null);
expect(result).toBeTruthy();

result = vm.isURLValid(undefined);
expect(result).toBeTruthy();
});

it('should return true for valid URLs within 200 characters', function () {
var result = vm.isURLValid('https://github.com');
expect(result).toBeTruthy();

result = vm.isURLValid('http://example.com/path?query=param');
expect(result).toBeTruthy();

result = vm.isURLValid('https://sub.domain.example.com/long-path/to/resource?query=1&more=2');
expect(result).toBeTruthy();
});

it('should return false for invalid URLs or overly long ones', function () {
var result = vm.isURLValid('invalid-url');
expect(result).toBeFalsy();

result = vm.isURLValid('htp://missing-schema.com');
expect(result).toBeFalsy();

var longUrl = 'http://example.com/' + 'a'.repeat(201);
result = vm.isURLValid(longUrl);
expect(result).toBeFalsy();
});
});

describe('Unit tests for showTokenExpiredDialog function', function () {
beforeEach(function () {
spyOn($mdDialog, 'show').and.callFake(function (options) {
var fakeScope = $rootScope.$new();

var controllerFn = Array.isArray(options.controller)
? options.controller[options.controller.length - 1]
: options.controller;

controllerFn(fakeScope, $mdDialog);

expect(typeof fakeScope.refreshToken).toBe('function');
expect(typeof fakeScope.dismiss).toBe('function');

return {
then: function (confirmCallback, cancelCallback) {
if (confirmCallback) confirmCallback();
}
};
});

spyOn(vm, 'refreshToken');
});

it('should open token expired dialog with correct config and call refreshToken', function () {
vm.showTokenExpiredDialog();

expect($mdDialog.show).toHaveBeenCalled();

var dialogArgs = $mdDialog.show.calls.mostRecent().args[0];
expect(dialogArgs.templateUrl).toBe('dist/views/web/auth/auth-token-expired-dialog.html');

var testScope = $rootScope.$new();
var controllerFn = Array.isArray(dialogArgs.controller)
? dialogArgs.controller[dialogArgs.controller.length - 1]
: dialogArgs.controller;

controllerFn(testScope, $mdDialog);
testScope.refreshToken();

expect(vm.refreshToken).toHaveBeenCalled();
});
});

});