@asito/onego-header
v1.0.0
Published
OneGo global header, Keycloak (OIDC) authentication and current-user services for OneGo Angular applications
Readme
@asito/onego-header
The OneGo global header for Angular applications. Besides the <onego-header> component it ships the
Keycloak (OIDC) authentication setup, an HttpInterceptorFn that attaches the bearer token, and services
for the current user and their permissions.
Published to npm from this repository (asito-web, libs/onego-header).
Installation
The package is published publicly on npm under the @asito scope. No registry configuration or
authentication is needed to install it.
Install the package and its peer dependencies:
yarn add @asito/onego-header
yarn add @jsverse/transloco angular-oauth2-oidc @fortawesome/angular-fontawesome @fortawesome/free-solid-svg-iconsPeer dependency ranges:
| Package | Range |
| ------------------------------------------------------- | ---------- |
| @angular/common, core, platform-browser, router | ^21.0.0 |
| @jsverse/transloco | ^8.0.0 |
| angular-oauth2-oidc | >=19.0.0 |
| @fortawesome/angular-fontawesome | ^1.0.0 |
| @fortawesome/free-solid-svg-icons | ^6.7.2 |
| rxjs | ^7.8.0 |
Setup
Register the header once in the application config with provideOneGoHeader. It provides the OAuth
client, HttpClient (with the auth interceptor), Transloco, animations, and an app initializer that loads
assets/appsettings.json and maps it to a HeaderConfig.
import { ApplicationConfig } from '@angular/core';
import { HeaderConfig, getRedirectUrl, provideOneGoHeader } from '@asito/onego-header';
function mapHeaderSettings(appSettings: unknown): HeaderConfig {
const { keycloak, url } = appSettings as AppSettings;
return {
keycloakUrl: keycloak.url,
keycloakRealm: keycloak.realm,
keycloakClientId: keycloak.clientId,
keycloakScope: keycloak.scope,
redirectUri: getRedirectUrl(),
jwtDomainWhitelist: url.jwtDomainWhitelist,
userApi: url.api.users,
tenantsApi: url.api.tenants,
};
}
export const appConfig: ApplicationConfig = {
providers: [
provideOneGoHeader(mapHeaderSettings, {
availableLangs: ['en', 'nl'],
defaultLang: 'en',
fallbackLang: 'en',
}),
],
};The second argument configures the languages Transloco knows about. The header registers its own en
and nl translations and merges them into the app's translation set.
Use the component in the root template:
<onego-header
title="My App"
[menu]="menu"
[languageSwitcherLanguages]="['en', 'nl']"
[(language)]="language"
(loggedOut)="onLoggedOut()"
/>| Input / output | Type | Description |
| --------------------------- | ----------------- | ------------------------------------------------------------ |
| title | string | Application title next to the OneGo logo. |
| menu | Array<MenuItem> | Root menu items; each may have subItems, icon, action. |
| languageSwitcherLanguages | Array<string> | Language codes offered in the language menu. |
| language | string (model) | Active language; two-way bound with Transloco's active lang. |
| loggedOut | void (output) | Emitted right before the header logs the user out. |
HeaderConfig
| Field | Description |
| -------------------- | --------------------------------------------------------------------------------- |
| keycloakUrl | Base URL of the Keycloak server, without the realm. |
| keycloakRealm | Realm name; together with keycloakUrl it forms the OIDC issuer. |
| keycloakClientId | Public client id registered in Keycloak for this SPA. |
| keycloakScope | Space separated scopes, e.g. openid profile email offline_access. |
| redirectUri | Where Keycloak redirects after login; getRedirectUrl() uses the current origin. |
| jwtDomainWhitelist | Request URLs containing one of these strings receive the Authorization header. |
| userApi | Base URL of the user API; GET {userApi}/v2/users/me loads the current user. |
| tenantsApi | Base URL of the tenant API. |
Composing your own HttpClient
provideOneGoHeader already provides HttpClient with the auth interceptor and DI-based interceptors.
When the app needs its own functional interceptors, provide HttpClient again after the header and include
authInterceptorFn:
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { authInterceptorFn } from '@asito/onego-header';
providers: [
provideOneGoHeader(mapHeaderSettings, languageConfig),
provideHttpClient(withInterceptors([tenantInterceptor, authInterceptorFn])),
];Token storage
Tokens and the Keycloak identity-provider hint are stored through OAuthStorage, which defaults to
HeaderStorageService (plain localStorage). Override it after provideOneGoHeader to use a different
storage:
{
provide: OAuthStorage, useClass: MyStorageService;
}Services
| Export | Purpose |
| ------------------------ | ---------------------------------------------------------------------------------- |
| HeaderService | Login state (loggedIn, onInitialized), login(), logout(), getToken(). |
| OneGoUserService | getMe() streams the current OneGoUser once authenticated. |
| OneGoPermissionService | Wildcard-aware permission and feature checks on a OneGoUser. |
| authInterceptorFn | Adds Authorization: Bearer to whitelisted requests and refreshes expired tokens. |
| TENANT_KEY | Storage key under which consuming apps keep the active tenant id. |
Usage inside asito-web
The apps in this repository keep importing the library through the onego-header tsconfig path alias and
build it from source. They do not install the published package: that keeps a single source of truth and
avoids a publish round-trip for every header change. The published package is intended for external
consumers such as asito-vloerenpaspoort.
Because the library no longer depends on the shared lib, apps in this repository that use the shared
repositories provide REPOSITORY_BASE_URL_TOKEN themselves with provideShared(), and override
OAuthStorage with SecureLocalStorageService to keep existing sessions valid.
Releasing
Publishing happens from CI only. The Publish onego-header workflow
(.github/workflows/publish-onego-header.yml) runs on tags named onego-header@<version>, builds the
library, verifies the tag matches the package version, and publishes dist/libs/onego-header to npm.
The workflow authenticates with npm Trusted Publishing: npm
trusts the GitHub Actions OIDC token of this repository and workflow, so no npm token is stored as a
secret. Trusted Publishing requires a GitHub-hosted runner, which is why this workflow runs on
ubuntu-latest instead of the self-hosted runner used by the other workflows. Provenance attestations
are disabled because npm does not generate them for private repositories.
The trusted publisher is configured on npmjs.com under the package settings of @asito/onego-header:
| Field | Value |
| ----------------- | -------------------------- |
| Provider | GitHub Actions |
| Organization | Baseflow |
| Repository | asito-web |
| Workflow filename | publish-onego-header.yml |
| Environment | (empty) |
A trusted publisher configuration cannot be edited afterwards; delete and recreate it when the workflow file is renamed.
Bump
versioninlibs/onego-header/package.jsonand move theUnreleasednotes inlibs/onego-header/CHANGELOG.mdunder the new version with today's date.Merge that change into
developthrough a pull request.Tag the merge commit and push the tag:
git tag [email protected] git push origin [email protected]Check the workflow run; the version appears on the package's npm page.
Versioning policy
The package follows Semantic Versioning:
- Major: breaking changes to the public API (
index.tsexports),HeaderConfig, the provider signature, or a new Angular major as peer dependency. - Minor: new exports, inputs, outputs, or config fields that stay backwards compatible.
- Patch: bug fixes, styling, and translation updates without API changes.
Angular peer ranges track the Angular major used by the consuming apps; bumping them is a major release.
Development
nx build onego-header
nx lint onego-header
nx test onego-header