mirror of
https://github.com/sismics/docs.git
synced 2025-12-13 01:36:18 +00:00
Closes #309: store onboarding status server side
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
api.current_version=${project.version}
|
||||
api.min_version=1.0
|
||||
db.version=22
|
||||
db.version=23
|
||||
@@ -101,6 +101,7 @@ public class UserResource extends BaseResource {
|
||||
user.setPassword(password);
|
||||
user.setEmail(email);
|
||||
user.setStorageQuota(storageQuota);
|
||||
user.setOnboarding(true);
|
||||
|
||||
// Create the user
|
||||
UserDao userDao = new UserDao();
|
||||
@@ -622,6 +623,7 @@ public class UserResource extends BaseResource {
|
||||
* @apiGroup User
|
||||
* @apiSuccess {Boolean} anonymous True if no user is connected
|
||||
* @apiSuccess {Boolean} is_default_password True if the admin has the default password
|
||||
* @apiSuccess {Boolean} onboarding True if the UI needs to display the onboarding
|
||||
* @apiSuccess {String} username Username
|
||||
* @apiSuccess {String} email E-mail
|
||||
* @apiSuccess {Number} storage_quota Storage quota (in bytes)
|
||||
@@ -665,8 +667,9 @@ public class UserResource extends BaseResource {
|
||||
.add("email", user.getEmail())
|
||||
.add("storage_quota", user.getStorageQuota())
|
||||
.add("storage_current", user.getStorageCurrent())
|
||||
.add("totp_enabled", user.getTotpKey() != null);
|
||||
|
||||
.add("totp_enabled", user.getTotpKey() != null)
|
||||
.add("onboarding", user.isOnboarding());
|
||||
|
||||
// Base functions
|
||||
JsonArrayBuilder baseFunctions = Json.createArrayBuilder();
|
||||
for (String baseFunction : ((UserPrincipal) principal).getBaseFunctionSet()) {
|
||||
@@ -898,6 +901,39 @@ public class UserResource extends BaseResource {
|
||||
.add("status", "ok");
|
||||
return Response.ok().entity(response.build()).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the onboarding experience as passed.
|
||||
*
|
||||
* @api {post} /user/onboarded Mark the onboarding experience as passed
|
||||
* @apiDescription Once the onboarding experience has been passed by the user, this resource prevent it from being displayed again.
|
||||
* @apiName PostUserOnboarded
|
||||
* @apiGroup User
|
||||
* @apiSuccess {String} status Status OK
|
||||
* @apiError (client) ForbiddenError Access denied
|
||||
* @apiPermission user
|
||||
* @apiVersion 1.7.0
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
@POST
|
||||
@Path("onboarded")
|
||||
public Response onboarded() {
|
||||
if (!authenticate()) {
|
||||
throw new ForbiddenClientException();
|
||||
}
|
||||
|
||||
// Save it
|
||||
UserDao userDao = new UserDao();
|
||||
User user = userDao.getActiveByUsername(principal.getName());
|
||||
user.setOnboarding(false);
|
||||
userDao.updateOnboarding(user);
|
||||
|
||||
// Always return OK
|
||||
JsonObjectBuilder response = Json.createObjectBuilder()
|
||||
.add("status", "ok");
|
||||
return Response.ok().entity(response.build()).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable time-based one-time password.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
/**
|
||||
* Document default controller.
|
||||
*/
|
||||
angular.module('docs').controller('DocumentDefault', function ($scope, $rootScope, $state, Restangular, Upload, $translate, $uibModal, $dialog) {
|
||||
angular.module('docs').controller('DocumentDefault', function ($scope, $rootScope, $state, Restangular, Upload, $translate, $uibModal, $dialog, User) {
|
||||
// Load user audit log
|
||||
Restangular.one('auditlog').get().then(function (data) {
|
||||
$scope.logs = data.logs;
|
||||
@@ -145,48 +145,51 @@ angular.module('docs').controller('DocumentDefault', function ($scope, $rootScop
|
||||
|
||||
// Onboarding
|
||||
$translate('onboarding.step1.title').then(function () {
|
||||
if (localStorage.onboardingDisplayed || $(window).width() < 1000) {
|
||||
return;
|
||||
}
|
||||
localStorage.onboardingDisplayed = true;
|
||||
|
||||
$rootScope.onboardingEnabled = true;
|
||||
|
||||
$rootScope.onboardingSteps = [
|
||||
{
|
||||
title: $translate.instant('onboarding.step1.title'),
|
||||
description: $translate.instant('onboarding.step1.description'),
|
||||
position: 'centered',
|
||||
width: 300
|
||||
},
|
||||
{
|
||||
title: $translate.instant('onboarding.step2.title'),
|
||||
description: $translate.instant('onboarding.step2.description'),
|
||||
attachTo: '#document-add-btn',
|
||||
position: 'right',
|
||||
width: 300
|
||||
},
|
||||
{
|
||||
title: $translate.instant('onboarding.step3.title'),
|
||||
description: $translate.instant('onboarding.step3.description'),
|
||||
attachTo: '#quick-upload-zone',
|
||||
position: 'left',
|
||||
width: 300
|
||||
},
|
||||
{
|
||||
title: $translate.instant('onboarding.step4.title'),
|
||||
description: $translate.instant('onboarding.step4.description'),
|
||||
attachTo: '#search-box',
|
||||
position: 'right',
|
||||
width: 300
|
||||
},
|
||||
{
|
||||
title: $translate.instant('onboarding.step5.title'),
|
||||
description: $translate.instant('onboarding.step5.description'),
|
||||
attachTo: '#navigation-tag',
|
||||
position: "right",
|
||||
width: 300
|
||||
User.userInfo().then(function(userData) {
|
||||
if (!userData.onboarding || $(window).width() < 1000) {
|
||||
return;
|
||||
}
|
||||
];
|
||||
Restangular.one('user').post('onboarded');
|
||||
$rootScope.userInfo.onboarding = false;
|
||||
|
||||
$rootScope.onboardingEnabled = true;
|
||||
|
||||
$rootScope.onboardingSteps = [
|
||||
{
|
||||
title: $translate.instant('onboarding.step1.title'),
|
||||
description: $translate.instant('onboarding.step1.description'),
|
||||
position: 'centered',
|
||||
width: 300
|
||||
},
|
||||
{
|
||||
title: $translate.instant('onboarding.step2.title'),
|
||||
description: $translate.instant('onboarding.step2.description'),
|
||||
attachTo: '#document-add-btn',
|
||||
position: 'right',
|
||||
width: 300
|
||||
},
|
||||
{
|
||||
title: $translate.instant('onboarding.step3.title'),
|
||||
description: $translate.instant('onboarding.step3.description'),
|
||||
attachTo: '#quick-upload-zone',
|
||||
position: 'left',
|
||||
width: 300
|
||||
},
|
||||
{
|
||||
title: $translate.instant('onboarding.step4.title'),
|
||||
description: $translate.instant('onboarding.step4.description'),
|
||||
attachTo: '#search-box',
|
||||
position: 'right',
|
||||
width: 300
|
||||
},
|
||||
{
|
||||
title: $translate.instant('onboarding.step5.title'),
|
||||
description: $translate.instant('onboarding.step5.description'),
|
||||
attachTo: '#navigation-tag',
|
||||
position: "right",
|
||||
width: 300
|
||||
}
|
||||
];
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,3 +1,3 @@
|
||||
api.current_version=${project.version}
|
||||
api.min_version=1.0
|
||||
db.version=22
|
||||
db.version=23
|
||||
@@ -1,3 +1,3 @@
|
||||
api.current_version=${project.version}
|
||||
api.min_version=1.0
|
||||
db.version=22
|
||||
db.version=23
|
||||
@@ -172,7 +172,7 @@ public class TestUserResource extends BaseJerseyTest {
|
||||
.get();
|
||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||
json = response.readEntity(JsonObject.class);
|
||||
Assert.assertEquals(true, json.getBoolean("anonymous"));
|
||||
Assert.assertTrue(json.getBoolean("anonymous"));
|
||||
|
||||
// Check alice user information
|
||||
json = target().path("/user").request()
|
||||
@@ -187,8 +187,20 @@ public class TestUserResource extends BaseJerseyTest {
|
||||
json = target().path("/user").request()
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, bobToken)
|
||||
.get(JsonObject.class);
|
||||
Assert.assertTrue(json.getBoolean("onboarding"));
|
||||
Assert.assertEquals("bob@docs.com", json.getString("email"));
|
||||
|
||||
|
||||
// Pass onboarding
|
||||
target().path("/user/onboarded").request()
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, bobToken)
|
||||
.post(Entity.form(new Form()), JsonObject.class);
|
||||
|
||||
// Check bob user information
|
||||
json = target().path("/user").request()
|
||||
.cookie(TokenBasedSecurityFilter.COOKIE_NAME, bobToken)
|
||||
.get(JsonObject.class);
|
||||
Assert.assertFalse(json.getBoolean("onboarding"));
|
||||
|
||||
// Test login KO (user not found)
|
||||
response = target().path("/user/login").request()
|
||||
.post(Entity.form(new Form()
|
||||
|
||||
Reference in New Issue
Block a user