Skip to content

Commit

Permalink
feat(webapps): add login plugin point (camunda#3461)
Browse files Browse the repository at this point in the history
related to camunda#3412
  • Loading branch information
tasso94 authored Jul 18, 2023
1 parent 335734d commit 87e52cd
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 63 deletions.
16 changes: 15 additions & 1 deletion webapps/frontend/camunda-commons-ui/lib/auth/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,24 @@ var commonsUtil = require('../util/index'),
var ngModule = angular.module('cam.commons.auth', [
angular.module('ngRoute').name,
commonsUtil.name,
'pascalprecht.translate'
'pascalprecht.translate',
'webapps.plugin',
'camunda.common.services'
]);

ngModule
.config([
'ViewsProvider',
'canonicalAppNameProvider',
function(ViewsProvider, {$get: canonicalAppName}) {
ViewsProvider.registerDefaultView(`${canonicalAppName()}.login`, {
id: 'default-login-form',
controller: require('./page/form'),
template: require('./page/form.html?raw'),
priority: 0
});
}
])
.config(loginPage)

// redirect after login support
Expand Down
27 changes: 27 additions & 0 deletions webapps/frontend/camunda-commons-ui/lib/auth/page/form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!-- # CE - camunda-commons-ui/lib/auth/page/form.html -->
<form ng-submit="login()"
name="signinForm"
request-aware>

<input autofocus
tabindex="1"
type="text"
class="form-control"
placeholder="{{ 'PAGE_LOGIN_USERNAME' | translate }}"
auto-fill
required
ng-model="username"></input>
<input tabindex="2"
type="password"
class="form-control"
placeholder="{{ 'PAGE_LOGIN_PASSWORD' | translate }}"
auto-fill
required
ng-model="password"></input>
<button tabindex="3"
class="btn btn-lg btn-primary"
type="submit"
ng-disabled="status === 'LOADING'">{{ 'PAGE_LOGIN_SIGN_IN_ACTION' | translate }}
</button>
</form>
<!-- / CE - camunda-commons-ui/lib/auth/page/form.html -->
80 changes: 80 additions & 0 deletions webapps/frontend/camunda-commons-ui/lib/auth/page/form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. Camunda licenses this file to you under the Apache License,
* Version 2.0; you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

const $ = require('jquery');
module.exports = [
'$scope',
'AuthenticationService',
'Notifications',
'$translate',
'Views',
'canonicalAppName',
function(
$scope,
AuthenticationService,
Notifications,
$translate,
views,
canonicalAppName
) {
$scope.status = 'INIT';

// ensure focus on username input
var autofocusField = $('form[name="signinForm"] [autofocus]')[0];
if (autofocusField) {
autofocusField.focus();
}

const loginDataPlugins = views.getProviders({
component: `${canonicalAppName}.login.data`
});

$scope.login = function() {
$scope.status = 'LOADING';
const loginDataPromise = AuthenticationService.login(
$scope.username,
$scope.password
);

loginDataPlugins.forEach(loginDataPlugin => {
loginDataPlugin.result &&
loginDataPlugin.result(loginDataPromise, $scope);
});

return loginDataPromise
.then(function() {
$scope.status = 'DONE';
Notifications.clearAll();
$scope.$root.$broadcast('first-visit-info-box-dismissed');
})
.catch(function(error) {
$scope.status = 'ERROR';
delete $scope.username;
delete $scope.password;

Notifications.addError({
status: $translate.instant('PAGE_LOGIN_FAILED'),
message:
(error.data && error.data.message) ||
$translate.instant('PAGE_LOGIN_ERROR_MSG'),
scope: $scope,
exclusive: true
});
});
};
}
];
30 changes: 6 additions & 24 deletions webapps/frontend/camunda-commons-ui/lib/auth/page/login.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
<!-- # CE - camunda-commons-ui/lib/auth/page/login.html -->
<div class="form-signin-container">
<form class="form-signin"
ng-submit="login()"
name="signinForm"
request-aware>
<div class="form-signin">

<div class="login-header">
<div class="login-logo" ng-bind-html="logo"></div>
Expand All @@ -17,25 +14,10 @@
ng-if="signinForm.$dirty"
class="notifications-panel"></div>

<input autofocus
tabindex="1"
type="text"
class="form-control"
placeholder="{{ 'PAGE_LOGIN_USERNAME' | translate }}"
auto-fill
required
ng-model="username"></input>
<input tabindex="2"
type="password"
class="form-control"
placeholder="{{ 'PAGE_LOGIN_PASSWORD' | translate }}"
auto-fill
required
ng-model="password"></input>
<button tabindex="3"
class="btn btn-lg btn-primary"
type="submit"
ng-disabled="status === 'LOADING'">{{ 'PAGE_LOGIN_SIGN_IN_ACTION' | translate }}</button>
<view
ng-repeat="plugin in loginPlugins"
data-plugin-id="{{ plugin.id }}"
provider="plugin"></view>

<div ng-if="showFirstLogin"
class="alert-info alert">
Expand All @@ -45,6 +27,6 @@
<span class="message" ng-bind-html="FirstLoginMessage"></span>
</div>
</div>
</form>
</div>
</div>
<!-- / CE - camunda-commons-ui/lib/auth/page/login.html -->
53 changes: 18 additions & 35 deletions webapps/frontend/camunda-commons-ui/lib/auth/page/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,35 +20,39 @@
var template = require('./login.html?raw');
var logo = require('svg-inline-loader?classPrefix&removeSVGTagAttrs=false!./logo.svg');

var $ = require('jquery');

var Controller = [
'$scope',
'$rootScope',
'AuthenticationService',
'Notifications',
'$location',
'$translate',
'widgetLocalConf',
'$sce',
'configuration',
'$http',
'Views',
'canonicalAppName',
function(
$scope,
$rootScope,
AuthenticationService,
Notifications,
$location,
$translate,
localConf,
$sce,
configuration,
$http
$http,
views,
canonicalAppName
) {
$scope.logo = $sce.trustAsHtml(logo);
$scope.status = 'INIT';
$scope.appName = configuration.getAppName();

$scope.loginPlugins = views.getProviders({
component: `${canonicalAppName}.login`
});

if ($rootScope.authentication) {
return $location.path('/');
}
Expand All @@ -72,6 +76,15 @@ var Controller = [
}
localConf.set('firstVisit', true);
$scope.showFirstLogin = true;

const unregisterListener = $scope.$on(
'first-visit-info-box-dismissed',
$scope.dismissInfoBox
);

$scope.$on('$destroy', function() {
unregisterListener();
});
})
.catch($scope.dismissInfoBox);
}
Expand All @@ -84,36 +97,6 @@ var Controller = [
$scope.showFirstLogin = false;
localConf.set('firstVisit', false);
};

// ensure focus on username input
var autofocusField = $('form[name="signinForm"] [autofocus]')[0];
if (autofocusField) {
autofocusField.focus();
}

$scope.login = function() {
$scope.status = 'LOADING';
return AuthenticationService.login($scope.username, $scope.password)
.then(function() {
$scope.status = 'DONE';
Notifications.clearAll();
$scope.dismissInfoBox();
})
.catch(function(error) {
$scope.status = 'ERROR';
delete $scope.username;
delete $scope.password;

Notifications.addError({
status: $translate.instant('PAGE_LOGIN_FAILED'),
message:
(error.data && error.data.message) ||
$translate.instant('PAGE_LOGIN_ERROR_MSG'),
scope: $scope,
exclusive: true
});
});
};
}
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@

.btn-primary {
width: 100%;
float: right;
}

.alert-info {
Expand Down
2 changes: 1 addition & 1 deletion webapps/frontend/camunda-commons-ui/lib/plugin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var angular = require('camunda-bpm-sdk-js/vendor/angular'),
view = require('./view'),
service = require('./service');

var pluginModule = angular.module('cockpit.plugin', []);
var pluginModule = angular.module('webapps.plugin', []);

// this module is a bit different, so we handle it differently...
view(pluginModule);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. Camunda licenses this file to you under the Apache License,
* Version 2.0; you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

'use strict';

const base = document.querySelector('base');
const canonicalAppName = base.getAttribute('app-name');

module.exports = function() {
this.$get = function() {
return canonicalAppName;
};
};
4 changes: 3 additions & 1 deletion webapps/frontend/camunda-commons-ui/lib/services/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ var angular = require('camunda-bpm-sdk-js/vendor/angular'),
fixDate = require('./fixDate'),
ifUnauthorizedForwardToWelcomeApp = require('./ifUnauthorizedForwardToWelcomeApp'),
unfixDate = require('./unfixDate'),
shouldDisplayAuthenticationError = require('./shouldDisplayAuthenticationError');
shouldDisplayAuthenticationError = require('./shouldDisplayAuthenticationError'),
canonicalAppName = require('./canocialAppName');

var ngModule = angular.module('camunda.common.services', [
// `ResourceResolver` relies on cam.commons.util for Notifications
Expand All @@ -56,6 +57,7 @@ ngModule.factory(
'shouldDisplayAuthenticationError',
shouldDisplayAuthenticationError
);
ngModule.provider('canonicalAppName', canonicalAppName);

/**
* Register http status interceptor per default
Expand Down

0 comments on commit 87e52cd

Please sign in to comment.