Hi, we upgraded from Angular 19 to 21.So that means we have upgraded ng.theme.shared from 8.0.4 to 10.4.0.
Some places where font awesome is being used has changed due to the upgrade in packages (Bolder etc).
Also, our abp-navbar, we use it out of the box, previously the order of the items in the bar was:
abp-languages | abp-current-user | abp-full-screen
But now its ordered as:
abp-current-user | abp-full-screen | abp-languages
Is there anyway to change this order of nav-items without having to make a replacement component to overide it? Or any reason this reorder might have happened because of something we done?
Is there anyway to use older versions of themes too (Using Fontawesome 5 instead of 6 etc)?
Environment:
Issues encountered:
After the auth server redirects back with the authorization code, ABP's AuthGuard on the root route (/) fires immediately. At that point, the code exchange has not completed yet, so hasValidAccessToken() returns false. The guard redirects to login, the auth server auto-authenticates (session still active), redirects back - infinite loop. We had to create a dedicated /oauth/code callback route without an auth guard, and update the redirect_uri in both the Angular config and the OpenIddict application registration. Is there a recommended callback route for the code flow, or should ABP's auth guard wait for an in-progress code exchange before redirecting?
After the authorization code redirect, ABP's OAuth module calls tryLogin() without passing disableNonceCheck. The angular-oauth2-oidc library validates the nonce from the state parameter, fails, and rejects the promise - but ABP catches it with .catch(noop). The authorization code is consumed and discarded with no error surfaced to the developer. Is there a recommended way to disable nonce validation, or should ABP's OAuth module be passing disableNonceCheck: true for OpenIddict?
The library stores the PKCE verifier in sessionStorage by default. After the redirect back from the auth server, the verifier is gone and the token exchange fails with "code_verifier missing". We resolved this with saveNoncesInLocalStorage: true. Should this be the default for ABP's OpenIddict configuration?
After a successful code exchange, the token is stored in memory. ABP then calls /api/abp/application-configuration. If there is any timing issue or the API does not recognize the token immediately, ABP's checkAccessToken function clears all token storage. Is there a recommended approach to prevent this race condition, or is the no-op override for CHECK_AUTHENTICATION_STATE_FN_KEY intentional for OpenIddict setups?
During logout, ABP calls oAuthService.revokeTokenAndLogout() without setting ignoreCorsIssues = true. If the revocation endpoint returns a CORS error (status 0), the logOut() method (which redirects to the end_session endpoint) is never called - the user appears stuck. Should ABP's code flow strategy be passing ignoreCorsIssues = true, or is there a CORS configuration we are missing?
Workarounds applied:
Question: Are these known issues with the Angular + OpenIddict code flow? Is there planned documentation or a fix in ABP's @abp/ng.oauth module to handle these scenarios, or are we expected to apply these workarounds manually? We would also appreciate guidance on which workarounds are safe for production vs temporary.
Hi, I have sent an email, thanks for your assistance!
Exception message and full stack trace:
X [ERROR] No matching export in "node_modules/@volo/abp.ng.account/node_modules/@angular/core/fesm2022/core.mjs" for import "provideAppInitializer"
node_modules/@volo/abp.ng.account/fesm2022/volo-abp.ng.account-admin-config.mjs:3:9: 3 │ import { provideAppInitializer, inject, makeEnvironmentProviders, NgModule } from '@angular/core'; ╵ ~~~~~~~~~~~~~~~~~~~~~
X [ERROR] No matching export in "node_modules/@volo/abp.ng.account/node_modules/@angular/core/fesm2022/core.mjs" for import "provideAppInitializer"
node_modules/@volo/abp.ng.account/fesm2022/volo-abp.ng.account-public-config.mjs:2:21:
2 │ import { Injectable, provideAppInitializer, inject, makeEnvironmentProviders, Injector, NgModule } from '@angular/core';
╵ ~~~~~~~~~~~~~~~~~~~~~
angular\node_modules\esbuild\lib\main.js:1477 let error = new Error(text); ^
Error: Build failed with 2 errors: node_modules/@volo/abp.ng.account/fesm2022/volo-abp.ng.account-admin-config.mjs:3:9: ERROR: No matching export in "node_modules/@volo/abp.ng.account/node_modules/@angular/core/fesm2022/core.mjs" for import "provideAppInitializer" node_modules/@volo/abp.ng.account/fesm2022/volo-abp.ng.account-public-config.mjs:2:21: ERROR: No matching export in "node_modules/@volo/abp.ng.account/node_modules/@angular/core/fesm2022/core.mjs" for import "provideAppInitializer" at failureErrorWithLog (angular\node_modules\esbuild\lib\main.js:1477:15) at angular\node_modules\esbuild\lib\main.js:946:25 at angular\node_modules\esbuild\lib\main.js:1355:9 at process.processTicksAndRejections (node:internal/process/task_queues:105:5) { errors: [Getter/Setter], warnings: [Getter/Setter] }
app.module:
import { CoreModule } from '@abp/ng.core';
import { provideAbpOAuth } from "@abp/ng.oauth";
import { provideSettingManagementConfig } from '@abp/ng.setting-management/config';
import { SUPPRESS_UNSAVED_CHANGES_WARNING, ThemeSharedModule } from '@abp/ng.theme.shared';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { CommercialUiModule } from '@volo/abp.commercial.ng.ui';
import { provideCommercialUiConfig } from '@volo/abp.commercial.ng.ui/config';
import { provideAccountAdminConfig } from '@volo/abp.ng.account/admin/config';
import { provideAccountPublicConfig } from '@volo/abp.ng.account/public/config';
import { provideAuditLoggingConfig } from '@volo/abp.ng.audit-logging/config';
import { provideIdentityServerConfig } from '@volo/abp.ng.identity-server/config';
import { provideIdentityConfig } from '@volo/abp.ng.identity/config';
import { provideLanguageManagementConfig } from '@volo/abp.ng.language-management/config';
import { registerLocale } from '@volo/abp.ng.language-management/locale';
import { SaasConfigModule } from '@volo/abp.ng.saas/config';
import { HttpErrorComponent, provideThemeLepton } from '@volo/abp.ng.theme.lepton';
import { NgMultiSelectDropDownModule } from 'ng-multiselect-dropdown';
import { environment } from '../environments/environment';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { APP_ROUTE_PROVIDER } from './route.provider';
import { SettingsComponent } from './settings/settings.component';
@NgModule({
declarations: [AppComponent, SettingsComponent],
imports: [
BrowserModule,
BrowserAnimationsModule,
AppRoutingModule,
CommercialUiModule,
AppRoutingModule,
CoreModule.forRoot({
environment,
registerLocaleFn: registerLocale(),
}),
ThemeSharedModule.forRoot({
httpErrorConfig: {
errorScreen: {
component: HttpErrorComponent,
forWhichErrors: [401, 403, 404, 500],
hideCloseIcon: true,
},
},
}),
SaasConfigModule.forRoot(),
NgbModule,
NgMultiSelectDropDownModule,
],
providers: [
APP_ROUTE_PROVIDER,
{ provide: SUPPRESS_UNSAVED_CHANGES_WARNING, useValue: true },
provideAbpOAuth(),
provideAccountPublicConfig(),
provideLanguageManagementConfig(),
provideIdentityServerConfig(),
provideSettingManagementConfig(),
provideAuditLoggingConfig(),
provideThemeLepton(),
provideAccountAdminConfig(),
provideIdentityConfig(),
provideCommercialUiConfig()
],
bootstrap: [AppComponent]
})
export class AppModule {}
Package.json:
"dependencies": {
"@abp/ng.account.core": "^9.1.1",
"@abp/ng.components": "^9.1.1",
"@abp/ng.core": "^9.1.1",
"@abp/ng.oauth": "^9.1.1",
"@abp/ng.setting-management": "^9.1.1",
"@abp/ng.theme.shared": "^9.1.1",
"@angular/animations": "^19.2.8",
"@angular/common": "^19.2.8",
"@angular/compiler": "^19.2.8",
"@angular/core": "^19.2.8",
"@angular/forms": "^19.2.8",
"@angular/localize": "^19.2.8",
"@angular/platform-browser": "^19.2.8",
"@angular/platform-browser-dynamic": "^19.2.8",
"@angular/router": "^19.2.8",
"@ng-bootstrap/ng-bootstrap": "^18.0.0",
"@ngx-validate/core": "^0.2.0",
"@popperjs/core": "^2.11.8",
"@volo/abp.commercial.ng.ui": "^9.1.1",
"@volo/abp.ng.account": "^9.1.1",
"@volo/abp.ng.audit-logging": "^9.1.1",
"@volo/abp.ng.identity": "^9.1.1",
"@volo/abp.ng.identity-server": "^9.1.1",
"@volo/abp.ng.language-management": "^9.1.1",
"@volo/abp.ng.saas": "^9.1.1",
"@volo/abp.ng.text-template-management": "^9.1.1",
"@volo/abp.ng.theme.lepton": "^9.1.1",
"angular-typeahead": "^1.0.2",
"angularx-qrcode": "^19.0.0",
"bootstrap-icons": "^1.10.5",
"dotenv": "~16.0.0",
"file-saver": "^2.0.5",
"flag-icon-css": "^4.1.7",
"lodash": "^4.17.21",
"moment": "^2.29.3",
"ng-multiselect-dropdown": "^1.0.0",
"ng-zorro-antd": "^19.2.1",
"node": "^22.15.0",
"npm": "^9.8.0",
"powerbi-client": "^2.21.1",
"powerbi-client-angular": "^3.0.5",
"rxjs": "^7.4.0",
"ts-node": "^10.9.2",
"tslib": "^2.3.0",
"zone.js": "~0.15.0"
},
"devDependencies": {
"@abp/ng.schematics": "^9.1.1",
"@angular-devkit/build-angular": "^19.0.0",
"@angular-devkit/core": "^19.0.0",
"@angular-devkit/schematics": "^19.0.0",
"@angular-eslint/builder": "~17.0.0",
"@angular-eslint/eslint-plugin": "~17.0.0",
"@angular-eslint/eslint-plugin-template": "~17.0.0",
"@angular-eslint/schematics": "~19.0.0",
"@angular-eslint/template-parser": "~17.0.0",
"@angular/cli": "^19.0.0",
"@angular/compiler-cli": "^19.2.8",
"@angular/language-service": "^19.2.8",
"@types/jasmine": "~3.6.0",
"@types/node": "^22.15.3",
"@typescript-eslint/eslint-plugin": "^6.10.0",
"@typescript-eslint/parser": "^6.10.0",
"dotenv": "~16.0.0",
"eslint": "^8.53.0",
"jasmine-core": "~4.0.0",
"karma": "~6.4.4",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.1.0",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.7.0",
"ng-packagr": "^19.2.1",
"typescript": "~5.8.0"
},
"engines": {
"node": "22.15.0"
}
App routing module also as a related issue:
{
path: 'account',
loadChildren: () => import('@volo/abp.ng.account/public').then(m => m.AccountPublicModule.forLazy()),
canActivate: [authGuard, permissionGuard]
},
Type 'Promise<Routes | Type$1<any> | NgModuleFactory$1<any> | DefaultExport<Type$1<any>> | DefaultExport<Routes> | NgModuleFactory<...>>' is not assignable to type 'Routes | Type$1<any> | NgModuleFactory$1<any> | Observable<Routes | Type$1<any> | DefaultExport<Type$1<any>> | DefaultExport<...>> | Promise<...>'.
Type 'Promise<Routes | Type$1<any> | NgModuleFactory$1<any> | DefaultExport<Type$1<any>> | DefaultExport<Routes> | NgModuleFactory<...>>' is not assignable to type 'Promise<Routes | Type$1<any> | NgModuleFactory$1<any> | DefaultExport<Type$1<any>> | DefaultExport<Routes>>'.
Type 'Routes | Type$1<any> | NgModuleFactory$1<any> | DefaultExport<Type$1<any>> | DefaultExport<Routes> | NgModuleFactory<...>' is not assignable to type 'Routes | Type$1<any> | NgModuleFactory$1<any> | DefaultExport<Type$1<any>> | DefaultExport<Routes>'.
Type 'NgModuleFactory<AccountPublicModule>' is not assignable to type 'Routes | Type$1<any> | NgModuleFactory$1<any> | DefaultExport<Type$1<any>> | DefaultExport<Routes>'.
Type 'NgModuleFactory<AccountPublicModule>' is not assignable to type 'NgModuleFactory$1<any>'.
The types of 'create(...).componentFactoryResolver.resolveComponentFactory(...).inputs' are incompatible between these types.
Type '{ propName: string; templateName: string; transform?: (value: any) => any; }[]' is not assignable to type '{ propName: string; templateName: string; transform?: (value: any) => any; isSignal: boolean; }[]'.
Property 'isSignal' is missing in type '{ propName: string; templateName: string; transform?: (value: any) => any; }' but required in type '{ propName: string; templateName: string; transform?: (value: any) => any; isSignal: boolean; }'.ts(2322)
index.d.ts(9034, 9): 'isSignal' is declared here.
router_module.d-BivBj8FC.d.ts(524, 29): The expected type comes from the return type of this signature.
I have deleted package.lock and node modules multiple times and rebuilt using 'npm install':
npm i
removed 2 packages, and audited 1572 packages in 39s
230 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
main.ts:
/// <reference types="@angular/localize" />
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
I have also tried copying the versions used in this example but I get the same issue: https://github.com/abpframework/abp/blob/dev/templates/app/angular/package.json