Angular SDK (idenplane-angular)
Full Angular integration with dependency injection, route guards, HTTP interceptor, and RxJS-based reactive state.
Key Features
Requirements
- Angular 16+
- TypeScript 5+
- Node.js 18+
Installation
npm install idenplane-angular Configuration
Register the SDK in your root module using IdenplaneModule.forRoot(). This provides AuthService, AuthGuard, and AuthInterceptor for the whole app.
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { IdenplaneModule } from 'idenplane-angular';
@NgModule({
imports: [
BrowserModule,
HttpClientModule,
IdenplaneModule.forRoot({
url: 'https://auth.example.com',
realm: 'my-realm',
clientId: 'my-angular-app',
redirectUri: window.location.origin + '/callback',
}),
],
bootstrap: [AppComponent],
})
export class AppModule {} AuthService — Login & Logout
Inject AuthService to manage authentication state. State is exposed as RxJS observables (isAuthenticated$, user$, isLoading$) for use with the async pipe.
import { Component } from '@angular/core';
import { AuthService } from 'idenplane-angular';
@Component({
selector: 'app-header',
template: `
@if (auth.isAuthenticated$ | async) {
<span>Welcome, {{ (auth.user$ | async)?.name }}</span>
<button (click)="auth.logout()">Logout</button>
} @else {
<button (click)="auth.login()">Sign In</button>
}
`,
})
export class HeaderComponent {
constructor(public auth: AuthService) {}
} Route Guards
Protect routes with the built-in AuthGuard class, applied via canActivate. Role requirements go in the route's data.roles array.
import { Routes } from '@angular/router';
import { AuthGuard } from 'idenplane-angular';
export const routes: Routes = [
{ path: '', component: HomeComponent },
{
path: 'dashboard',
component: DashboardComponent,
canActivate: [AuthGuard],
},
{
path: 'admin',
component: AdminComponent,
canActivate: [AuthGuard],
data: { roles: ['admin'] }, // Role-based guard
},
]; HTTP Interceptor
IdenplaneModule.forRoot() already registers the class-based interceptor. If you use standalone components with provideHttpClient() instead of HttpClientModule, wire the functional authInterceptor directly.
// app.config.ts (standalone bootstrap)
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { authInterceptor } from 'idenplane-angular';
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(
withInterceptors([authInterceptor])
),
],
};
// API calls automatically include an Authorization: Bearer header,
// and a single token refresh + retry is attempted on a 401 response.
@Injectable()
export class ApiService {
constructor(private http: HttpClient) {}
getProfile() {
return this.http.get('/api/profile');
}
} User Info & Roles
AuthService also exposes synchronous getters and role/permission helpers for use outside templates.
import { Component } from '@angular/core';
import { AuthService } from 'idenplane-angular';
@Component({ /* ... */ })
export class ProfileComponent {
constructor(private auth: AuthService) {}
get user() { return this.auth.user; }
get isAdmin() { return this.auth.hasRole('admin'); }
get token() { return this.auth.getToken(); }
} Callback Component
Handle the OAuth callback redirect.
// callback.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { AuthService } from 'idenplane-angular';
@Component({
selector: 'app-callback',
template: '<p>Signing in...</p>',
})
export class CallbackComponent implements OnInit {
constructor(private auth: AuthService, private router: Router) {}
async ngOnInit() {
await this.auth.handleCallback();
this.router.navigate(['/dashboard']);
}
}