support redirection on successful login (#2306)

This commit is contained in:
Denys Vuika
2017-09-07 13:01:16 +01:00
committed by Eugenio Romano
parent acef0c1159
commit bee166c982
7 changed files with 90 additions and 49 deletions

View File

@@ -45,15 +45,16 @@
<md-icon>settings</md-icon> <md-icon>settings</md-icon>
</a> </a>
<alfresco-login #alfrescologin <alfresco-login
[providers]="providers" #alfrescologin
[fieldsValidation]="customValidation" [providers]="providers"
[disableCsrf]="disableCsrf" [fieldsValidation]="customValidation"
[showLoginActions]="showFooter" [disableCsrf]="disableCsrf"
[showRememberMe]="showFooter" [showLoginActions]="showFooter"
copyrightText="© 2016 Alfresco Software, Inc. All Rights Reserved. (customised text)" [showRememberMe]="showFooter"
(onSuccess)="onLogin($event)" copyrightText="© 2016 Alfresco Software, Inc. All Rights Reserved. (customised text)"
(onError)="onError($event)"> (onSuccess)="onLogin($event)"
(onError)="onError($event)">
<div class="mobile-settings"> <div class="mobile-settings">
<p> <p>
<md-slide-toggle <md-slide-toggle

View File

@@ -35,11 +35,46 @@ Authenticates to Alfresco Content Services and Alfresco Process Services.
### Basic usage ### Basic usage
```html
<adf-login
providers="ECM"
successRoute="/home">
</adf-login>
```
#### Properties
| Name | Type | Default Value | Description |
| --- | --- | --- | --- |
| providers | string | | Possible valid values are ECM, BPM or ALL. The default behaviour of this component will log in only in the ECM . If you want to log in in both systems the correct value to use is ALL. |
| successRoute | string | | Route to redirect to upon successful login. |
| disableCsrf | boolean | false | To prevent the CSRF Token from being submitted. Only for Alfresco Process Services call |
| needHelpLink | string | | It will change the url of the NEED HELP link in the footer |
| registerLink | string | | It will change the url of the REGISTER link in the footer |
| logoImageUrl | string | \<ADF logo image> | To change the logo image with a customised image |
| copyrightText | string | \<ADF copyright string> | The copyright text below the login box |
| backgroundImageUrl | string | \<ADF background image> | To change the background image with a customised image |
| fieldsValidation | { [key: string]: any; }, extra?: { [key: string]: any; } | | Use it to customise the validation rules of the login form |
| showRememberMe | boolean | false | Toggle `Remember me` checkbox visibility |
| showLoginActions | boolean | false | Toggle extra actions visibility (`Need Help`, `Register`, etc.) |
#### Events
| Name | Description |
| --- | --- |
| onSuccess | Raised when the login is done |
| onError | Raised when the login fails |
| executeSubmit | Raised when the form is submitted |
### Details
#### Handling events
**app.component.html** **app.component.html**
```html ```html
<adf-login <adf-login
[providers]="'ALL'" providers="ALL"
(onSuccess)="mySuccessMethod($event)" (onSuccess)="mySuccessMethod($event)"
(onError)="myErrorMethod($event)"> (onError)="myErrorMethod($event)">
</adf-login> </adf-login>
@@ -60,31 +95,6 @@ export class AppComponent {
} }
``` ```
#### Properties
| Name | Type | Default Value | Description |
| --- | --- | --- | --- |
| providers | string | ECM | Possible valid values are ECM, BPM or ALL. The default behaviour of this component will log in only in the ECM . If you want to log in in both systems the correct value to use is ALL |
| disableCsrf | boolean | false | To prevent the CSRF Token from being submitted. Only for Alfresco Process Services call |
| needHelpLink | string | | It will change the url of the NEED HELP link in the footer |
| registerLink | string | | It will change the url of the REGISTER link in the footer |
| logoImageUrl | string | Alfresco logo image | To change the logo image with a customised image |
| copyrightText | string | © 2017 Alfresco Software, Inc. All Rights Reserved. | The copyright text below the login box |
| backgroundImageUrl | string | Alfresco background image | To change the background image with a customised image |
| fieldsValidation | { [key: string]: any; }, extra?: { [key: string]: any; } | | Use it to customise the validation rules of the login form |
| showRememberMe | boolean | false | Toggle `Remember me` checkbox visibility |
| showLoginActions | boolean | false | Toggle extra actions visibility (`Need Help`, `Register`, etc.) |
#### Events
| Name | Description |
| --- | --- |
| onSuccess | Raised when the login is done |
| onError | Raised when the login fails |
| executeSubmit | Raised when the form is submitted |
### Details
#### Change footer content #### Change footer content
<img src="assets/custom-footer.png" width="400" /> <img src="assets/custom-footer.png" width="400" />
@@ -280,4 +290,4 @@ npm start
### License ### License
[Apache Version 2.0](https://github.com/Alfresco/alfresco-ng2-components/blob/master/LICENSE) [Apache Version 2.0](https://github.com/Alfresco/alfresco-ng2-components/blob/master/LICENSE)

View File

@@ -16,6 +16,7 @@
*/ */
import { ModuleWithProviders, NgModule } from '@angular/core'; import { ModuleWithProviders, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { CoreModule, TRANSLATION_PROVIDER } from 'ng2-alfresco-core'; import { CoreModule, TRANSLATION_PROVIDER } from 'ng2-alfresco-core';
import { LoginComponent } from './src/components/login.component'; import { LoginComponent } from './src/components/login.component';
@@ -42,6 +43,7 @@ export const ALFRESCO_LOGIN_DIRECTIVES: any[] = [
@NgModule({ @NgModule({
imports: [ imports: [
RouterModule,
CoreModule, CoreModule,
MaterialModule MaterialModule
], ],

View File

@@ -17,9 +17,12 @@
import { DebugElement } from '@angular/core'; import { DebugElement } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MdCheckboxModule, MdInputModule } from '@angular/material'; import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { AlfrescoAuthenticationService, CoreModule } from 'ng2-alfresco-core'; import { AlfrescoAuthenticationService, CoreModule } from 'ng2-alfresco-core';
import { AlfrescoTranslationService } from 'ng2-alfresco-core'; import { AlfrescoTranslationService } from 'ng2-alfresco-core';
import { MaterialModule } from '../material.module';
import { AuthenticationMock } from './../assets/authentication.service.mock'; import { AuthenticationMock } from './../assets/authentication.service.mock';
import { TranslationMock } from './../assets/translation.service.mock'; import { TranslationMock } from './../assets/translation.service.mock';
import { LoginComponent } from './login.component'; import { LoginComponent } from './login.component';
@@ -29,6 +32,8 @@ describe('AlfrescoLogin', () => {
let fixture: ComponentFixture<LoginComponent>; let fixture: ComponentFixture<LoginComponent>;
let debug: DebugElement; let debug: DebugElement;
let element: any; let element: any;
let authService: AlfrescoAuthenticationService;
let router: Router;
let usernameInput, passwordInput; let usernameInput, passwordInput;
@@ -38,14 +43,16 @@ describe('AlfrescoLogin', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
MdInputModule, RouterTestingModule,
MdCheckboxModule, MaterialModule,
CoreModule.forRoot() CoreModule
],
declarations: [
LoginComponent
], ],
declarations: [LoginComponent],
providers: [ providers: [
{provide: AlfrescoAuthenticationService, useClass: AuthenticationMock}, { provide: AlfrescoAuthenticationService, useClass: AuthenticationMock },
{provide: AlfrescoTranslationService, useClass: TranslationMock} { provide: AlfrescoTranslationService, useClass: TranslationMock }
] ]
}).compileComponents(); }).compileComponents();
})); }));
@@ -62,6 +69,9 @@ describe('AlfrescoLogin', () => {
usernameInput = element.querySelector('#username'); usernameInput = element.querySelector('#username');
passwordInput = element.querySelector('#password'); passwordInput = element.querySelector('#password');
authService = TestBed.get(AlfrescoAuthenticationService);
router = TestBed.get(Router);
fixture.detectChanges(); fixture.detectChanges();
}); });
@@ -78,6 +88,14 @@ describe('AlfrescoLogin', () => {
fixture.detectChanges(); fixture.detectChanges();
} }
it('should redirect to route on successful login', () => {
const redirect = '/home';
component.successRoute = redirect;
spyOn(router, 'navigate');
loginWithCredentials('fake-username', 'fake-password');
expect(router.navigate).toHaveBeenCalledWith([redirect]);
});
describe('Login button', () => { describe('Login button', () => {
const getLoginButton = () => element.querySelector('#login-button'); const getLoginButton = () => element.querySelector('#login-button');
@@ -89,7 +107,6 @@ describe('AlfrescoLogin', () => {
}); });
it('should be changed to the "checking key" after a login attempt', () => { it('should be changed to the "checking key" after a login attempt', () => {
const authService = TestBed.get(AlfrescoAuthenticationService);
spyOn(authService, 'login').and.returnValue({ subscribe: () => { } }); spyOn(authService, 'login').and.returnValue({ subscribe: () => { } });
loginWithCredentials('fake-username', 'fake-password'); loginWithCredentials('fake-username', 'fake-password');
@@ -130,7 +147,6 @@ describe('AlfrescoLogin', () => {
}); });
it('should be taken into consideration during login attempt', () => { it('should be taken into consideration during login attempt', () => {
const authService = TestBed.get(AlfrescoAuthenticationService);
spyOn(authService, 'login').and.returnValue({ subscribe: () => { } }); spyOn(authService, 'login').and.returnValue({ subscribe: () => { } });
component.rememberMe = false; component.rememberMe = false;
@@ -161,7 +177,7 @@ describe('AlfrescoLogin', () => {
it('should render the default copyright text', () => { it('should render the default copyright text', () => {
expect(element.querySelector('[data-automation-id="login-copyright"]')).toBeDefined(); expect(element.querySelector('[data-automation-id="login-copyright"]')).toBeDefined();
expect(element.querySelector('[data-automation-id="login-copyright"]').innerText).toEqual('&#169; 2016 Alfresco Software, Inc. All Rights Reserved.'); expect(element.querySelector('[data-automation-id="login-copyright"]').innerText).toEqual('\u00A9 2016 Alfresco Software, Inc. All Rights Reserved.');
}); });
it('should render the customised copyright text', () => { it('should render the customised copyright text', () => {

View File

@@ -17,6 +17,7 @@
import { Component, ElementRef, EventEmitter, Input, OnInit, Output, TemplateRef, ViewEncapsulation } from '@angular/core'; import { Component, ElementRef, EventEmitter, Input, OnInit, Output, TemplateRef, ViewEncapsulation } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms'; import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { AlfrescoAuthenticationService, AlfrescoSettingsService, AlfrescoTranslationService, LogService } from 'ng2-alfresco-core'; import { AlfrescoAuthenticationService, AlfrescoSettingsService, AlfrescoTranslationService, LogService } from 'ng2-alfresco-core';
import { FormSubmitEvent } from '../models/form-submit-event.model'; import { FormSubmitEvent } from '../models/form-submit-event.model';
@@ -58,7 +59,7 @@ export class LoginComponent implements OnInit {
backgroundImageUrl: string = require('../assets/images/background.svg'); backgroundImageUrl: string = require('../assets/images/background.svg');
@Input() @Input()
copyrightText: string = '&#169; 2016 Alfresco Software, Inc. All Rights Reserved.'; copyrightText: string = '\u00A9 2016 Alfresco Software, Inc. All Rights Reserved.';
@Input() @Input()
providers: string; providers: string;
@@ -69,6 +70,9 @@ export class LoginComponent implements OnInit {
@Input() @Input()
disableCsrf: boolean; disableCsrf: boolean;
@Input()
successRoute: string = null;
@Output() @Output()
onSuccess = new EventEmitter(); onSuccess = new EventEmitter();
@@ -105,7 +109,8 @@ export class LoginComponent implements OnInit {
private settingsService: AlfrescoSettingsService, private settingsService: AlfrescoSettingsService,
private translateService: AlfrescoTranslationService, private translateService: AlfrescoTranslationService,
private logService: LogService, private logService: LogService,
private elementRef: ElementRef) { private elementRef: ElementRef,
private router: Router) {
this.initFormError(); this.initFormError();
this.initFormFieldsMessages(); this.initFormFieldsMessages();
} }
@@ -179,6 +184,9 @@ export class LoginComponent implements OnInit {
this.actualLoginStep = LoginSteps.Welcome; this.actualLoginStep = LoginSteps.Welcome;
this.success = true; this.success = true;
this.onSuccess.emit({token: token, username: values.username, password: values.password}); this.onSuccess.emit({token: token, username: values.username, password: values.password});
if (this.successRoute) {
this.router.navigate([this.successRoute]);
}
}, },
(err: any) => { (err: any) => {
this.actualLoginStep = LoginSteps.Landing; this.actualLoginStep = LoginSteps.Landing;

View File

@@ -16,10 +16,11 @@
*/ */
import { async, TestBed } from '@angular/core/testing'; import { async, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { CoreModule } from 'ng2-alfresco-core'; import { CoreModule } from 'ng2-alfresco-core';
import { MaterialModule } from '../material.module';
import { LoginComponent } from '../components/login.component'; import { LoginComponent } from '../components/login.component';
import { MaterialModule } from '../material.module';
import { LoginFooterDirective } from './login-footer.directive'; import { LoginFooterDirective } from './login-footer.directive';
describe('LoginFooterDirective', () => { describe('LoginFooterDirective', () => {
@@ -29,6 +30,7 @@ describe('LoginFooterDirective', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
RouterTestingModule,
CoreModule, CoreModule,
MaterialModule MaterialModule
], ],

View File

@@ -16,6 +16,7 @@
*/ */
import { async, TestBed } from '@angular/core/testing'; import { async, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { CoreModule } from 'ng2-alfresco-core'; import { CoreModule } from 'ng2-alfresco-core';
import { MaterialModule } from '../material.module'; import { MaterialModule } from '../material.module';
@@ -29,6 +30,7 @@ describe('LoginHeaderDirective', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
RouterTestingModule,
CoreModule, CoreModule,
MaterialModule MaterialModule
], ],