FDC Authentication Library (fdc-auth)
This library is intended to decrease the development time required to start a new application based on angular. It provides authentication under the hood and helpers to specify which operations are available for the logged user.
Implementation
Install from npm running npm i @desarrollofdc/ng-auth
In app.module.ts
add:
@NgModule({
imports: [
NgAuthModule.forRoot({
apiGateway: API_GATEWAY,
applicationId: APPLICATION_ID,
authUri: AUTHENTICATION_URL,
environment: ENVIRONMENT,
redirectUrl: REDIRECT_URL,
})
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
}
Note:
API_GATEWAY
is the api gateway's url normally https://gateway.fdcteam.comAPPLICATION_ID
is the id registered in the databaseAUTHENTICATION_URL
is the url where theAuthentication Service
is runningENVIRONMENT
is the environment used for the authentication (test, production, demo)REDIRECT_URL
is the url where the user will be redirected once has logged (normally where the SPA is running)
In app.component.html
add:
<fdc-auth-wrapper>
<--!YOUR CODE, NORMALLY -->
<router-outlet></router-outlet>
</fdc-auth-wrapper>
Note: It will make sure to load the application once the user is logged, otherwise the user will be redirected to the
authentication service
to request a token
Features
This library provides the following features:
Auth Wrapper
To start protecting the frontend just add the fdc-auth-wrapper component and wrap what you expect to protect, for instance:
<fdc-auth-wrapper>
<h1>Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<router-outlet></router-outlet>
</fdc-auth-wrapper>
Route Guards
This library provides AuthGuard
to protect routes, this way, you can ensure that certain route will only be accessible if the user has access to the module related to that route.
const routes: Routes = [
{
path: '', canActivateChild: [AuthGuard],
children: [
{path: 'crisis-center', component: CrisisListComponent},
{
path: 'heroes',
component: HeroListComponent,
data: {title: 'Heroes List', moduleId: MODULE_ID, componentId: COMPONENT_ID, operationId: OPERATION_ID}
},
{
path: '',
redirectTo: '/heroes',
pathMatch: 'full'
},
]
},
{path: '**', component: PageNotFoundComponent}
];
Note: Provide moduleId, componentId or operationId in data, this way the library will automatically fetch the user accesses and will only render if the user has access to that module, component and/or operation
Token Injection
An interceptor is automatically configured to inject a Bearer
token to every request, this includes GraphQL
requests.
Render conditional components
This library provides fdc-auth-condition-component
which renders a child only if a user has access to a respective operation, component, or module. It is used as follows:
<fdc-auth-conditional-component [operationId]="YOUR_OPERATION_ID" [componentId]="YOUR_COMPONENT_ID" [condition]="YOUR_CONDITION" >
<your-depentent-components></your-depentent-components>
</fdc-auth-conditional-component>
Note:
your-dependent-components
will render if the user has access to the operation and/or component specified through props.operationId, componentId and condition are optional,
conditional-component
only takes in count the props provided.
Base layout
The library a FcdBaseLayout component, which includes a base styling for the whole app, this component accepts the following parameters:
- name the app name.
-
hideStaticSidebarByDefault show/hide the sidebar menu. It's a
boolean
type.false
by default. -
showLanguage show a component for select language, it's a
boolean
type.false
by default. -
routes which is of type
MenuItem[] | MenuItem
.
<fdc-auth-base-layout [hideStaticSidebarByDefault]="true" [showLanguage]="showLanguage" [routes]="routes" applicationName="Test">
<h1>Angular Router</h1>
<nav>
<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>
<a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<router-outlet></router-outlet>
</fdc-auth-base-layout>
This base layout already includes a logout option, and display the apps the logged user can access to. You have two options to change the styles used by your application
- add specific styles in
angular.json
, this way those styles will be added to your application styles
{
"projects": {
"your_project": {
"architect": {
"build": {
"options": {
"styles": [
"node_modules/@desarrollofdc/ng-auth/assets/theme/theme-orange-v4-css",
"node_modules/@desarrollofdc/ng-auth/assets/layout/css/layout-orange-v4.css"
]
}
}
}
}
}
}
- Specify assets to copy to the final build and configure your project to use them
{
"projects": {
"your_project": {
"architect": {
"build": {
"options": {
"assets": [
{
"glob": "layout-joomla-v4.css",
"input": "./node_modules/@desarrollofdc/ng-auth/assets/layout/css",
"output": "./assets/layout/css"
},
{
"glob": "layout-orange-v4.css",
"input": "./node_modules/@desarrollofdc/ng-auth/assets/layout/css",
"output": "./assets/layout/css"
}
]
}
}
}
}
}
}
In main.ts
add those styles to your html;
const {layout, theme, version} = environment.style;
const layoutElement = document.createElement('link');
layoutElement.href = `assets/layout/css/layout-${layout}-${version}.css`;
layoutElement.rel = 'stylesheet';
layoutElement.type = 'text/css';
const themeElement = document.createElement('link');
themeElement.href = `assets/theme/theme-${theme}-${version}.css`;
themeElement.rel = 'stylesheet';
themeElement.type = 'text/css';
document.head.append(layoutElement, themeElement);
Further help
To get more help contact Jeremy Perez
Pending Features
- Request new token when token expires
Development
run the app
To run the app you have to the following commands in sequence:
-
ng build ng-auth --watch
this will watch changes and rebuild the library. Run the following commands in a new terminal. -
npm run build-assets
orgulp build-assets
ng serve
Structure
This namespace has two projects auth-showcase
and ng-auth
. ng-auth
has the following structure:
ng-auth
├─ src
├─ assets
├─ lib
├─ api
├─ guard
├─ interceptors
├─ rest
├─ service
├─ store
├─ AuthLibConfig.ts
├─ components
├─ auth-wrapper
├─ base-layout
├─ conditional-component
├─ unauthorized
├─ types
├─ ng-auth.module.ts
├─ public-api.ts
-
assets
contains all the assets used by the apps, it contains layouts, custom-ui, and themes. -
guard
only containauth-guard
which is a guard to protect routes -
interceptos
contains two interceptorsresponse.interceptor
andtoken.interceptor
but onlytoken.interceptor
is being used and configured under the hood. -
rest
contains services used to fetch data fromauthentication-service
-
service
contains services with auth related logic -
components
contains the components provided by the library -
auth-wrapper
checks if the user is logged, otherwise it will request a new token. check authorization flow -
base-layout
is the layout structure used in order to keep the same styles across the apps developed by fdc-team -
conditional-component
renders a component conditionally if and only if the user has access to the componentId or operationId specified by props -
unauthorized
contains components rendered byauth-guard
when the user does not have access to a module, operation or component. -
types
contains interfaces defining types used across the library -
ng-auth.module.ts
is the module used to configure the library
Deployment
Deployments are made manually to npmjs.org where libraries are hosted, first is necessary to build the library and its assets
and then upload the library's new version, the whole process can be made by running npm run build:publish
Make sure to specify the new library's version in
projects/ng-auth/package.json
Make sure to add the token to your .npmrc config file
Components
FdcSplitButton
FdcSplitButton groups a set of commands in an overlay with a default command. Use the same PrimeNg styles, events and properties. This include a new property.
Name | Type | Default | Description |
---|---|---|---|
showDefaultBtn | Boolean | false | Show the first button |
<fdc-splitButton [showDefaultBtn]="false" [model]="actions" styleClass="ui-button-secondary"></fdc-splitButton>