Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
eba1717
Initial plan
Copilot Mar 19, 2026
9b17452
fix: migrate side-nav-auth igx-ts template to angular-auth-oidc-clien…
Copilot Mar 19, 2026
dcec8e5
fix(igx-ts): update the providers to fix build errors
Hristo313 Mar 19, 2026
740b8fe
refactor: remove NgModule files and convert side-nav-auth to fully st…
Copilot Mar 19, 2026
2658cf5
fix: remove standalone: true decorators and guard against "undefined"…
Copilot Mar 19, 2026
4582360
refactor: extract provideAuthentication() to keep auth config self-co…
Copilot Mar 19, 2026
455460d
merge master
Hristo313 Mar 20, 2026
fbdbef8
Merge branch 'master' into copilot/refactor-side-navigation-auth-temp…
Hristo313 Mar 20, 2026
62e36c6
refactor: migrate spec files from Jasmine to Vitest syntax (vi.fn, vi…
Copilot Mar 20, 2026
96e8c95
fix(igx-ts): fixing build tests errors
Hristo313 Mar 20, 2026
c4cb896
fix: sync formatUserData in providers, mock close/navigate spies in s…
Copilot Mar 20, 2026
2252821
revert: undo c4cb896 provider/spec changes and restore yarn.lock
Copilot Mar 20, 2026
2dd06a8
fix(igx-ts): fix failing tests
Hristo313 Mar 20, 2026
4eb4a78
Merge branch 'master' into copilot/refactor-side-navigation-auth-temp…
Hristo313 Mar 20, 2026
ac3f5e3
refactor: wire OIDC configs via OidcConfigLoader, fix route data shap…
Copilot Mar 23, 2026
b7697ea
fix(igx-ts): update spec files
Hristo313 Mar 23, 2026
97ac362
refactor: remove OidcConfigLoader, simplify ExternalAuth and provideA…
Copilot Mar 23, 2026
67bf7be
chore: add TODO comments for OIDC clientID usage in addGoogle/addMicr…
Copilot Mar 23, 2026
e75af5c
fix: remove unused clientID params from addGoogle/addMicrosoft, drop …
Copilot Mar 23, 2026
4f06d3f
fix(igx-ts): add home route
Hristo313 Mar 24, 2026
09f09f8
feat: restore social provider registration comments in App constructo…
Copilot Mar 24, 2026
30cf341
fix: use clearer CLIENT_ID placeholder for Facebook provider
Copilot Mar 24, 2026
7198fc6
fix(igx-ts): add clientId to microsoft and google login
Hristo313 Mar 24, 2026
8355531
fix(igx-ts): fix tests
Hristo313 Mar 24, 2026
ad5db64
fix(igx-ts): fix login
Hristo313 Mar 25, 2026
6d18c67
Merge branch 'master' into copilot/refactor-side-navigation-auth-temp…
Hristo313 Mar 25, 2026
1348032
fix(igx-ts): fix tests
Hristo313 Mar 25, 2026
3947cb4
fix(igx-ts): update the provide auth
Hristo313 Mar 26, 2026
e504f1f
Merge branch 'master' into copilot/refactor-side-navigation-auth-temp…
Hristo313 Mar 27, 2026
cf76d0d
Merge branch 'master' into copilot/refactor-side-navigation-auth-temp…
Hristo313 Mar 27, 2026
dcbf515
fix(igx-ts): fix configuration of multiple providers problem
Hristo313 Mar 27, 2026
24a7db3
Externalize OIDC configs to oidc-configs.ts; provideAuthentication() …
Copilot Mar 27, 2026
658a2bd
fix(igx-ts): add fixes
Hristo313 Mar 27, 2026
6ba1589
Move social provider registration from app.ts into provideAuthenticat…
Copilot Mar 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { ApplicationConfig, importProvidersFrom, provideBrowserGlobalErrorListeners, provideZoneChangeDetection } from '@angular/core';
import { BrowserModule, HammerModule } from '@angular/platform-browser';
import { provideAnimations } from '@angular/platform-browser/animations';
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
import { provideRouter } from '@angular/router';
import { AuthModule } from 'angular-auth-oidc-client';
import {
IgxLayoutModule,
IgxNavbarModule,
IgxNavigationDrawerModule,
IgxRippleModule,
} from '<%=igxPackage%>';

import { AuthenticationModule, ExternalAuthService } from './authentication';
import { BackendProvider } from './authentication/services/fake-backend.service';
import { JwtInterceptor } from './authentication/services/jwt.interceptor';
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
Expand All @@ -24,9 +28,12 @@ export const appConfig: ApplicationConfig = {
IgxNavbarModule,
IgxNavigationDrawerModule,
IgxRippleModule,
AuthenticationModule
AuthModule.forRoot({ config: [] })
),
provideAnimations(),
ExternalAuthService
provideHttpClient(withInterceptorsFromDi()),
{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
// TODO: DELETE THIS BEFORE PRODUCTION!
BackendProvider
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Don't move all of the previous config of AuthenticationModule into the main app config - it's job was to keep the authentication self-contained. Since we're not working with modules anymore, the modern approach for that would be to wrap the necessary config in something like provideAuthetication() that can be added to the config

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in commit 4582360. Created authentication/provide-authentication.ts with a provideAuthentication() function that encapsulates all auth-related providers (OIDC AuthModule, HTTP client with interceptors, JWT interceptor, fake backend). app.config.ts now simply spreads ...provideAuthentication(), keeping the auth setup self-contained.

]
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
import { Routes } from '@angular/router';
import { AuthGuard } from './authentication/auth.guard';
import { Profile } from './authentication/profile/profile';
import { Redirect } from './authentication/redirect/redirect';
import { ExternalAuthProvider } from './authentication/services/external-auth-configs';
import { ExternalAuthRedirectUrl } from './authentication/services/external-auth.service';

export const routes: Routes = [];
export const routes: Routes = [
{ path: 'profile', component: Profile, canActivate: [AuthGuard] },
{ path: ExternalAuthRedirectUrl.Google, component: Redirect, data: { provider: ExternalAuthProvider.Google } },
{ path: ExternalAuthRedirectUrl.Facebook, component: Redirect, data: { provider: ExternalAuthProvider.Facebook } },
{ path: ExternalAuthRedirectUrl.Microsoft, component: Redirect, data: { provider: ExternalAuthProvider.Microsoft } }
];
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { importProvidersFrom } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { provideHttpClient } from '@angular/common/http';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { RouterModule } from '@angular/router';
import { AuthModule } from 'angular-auth-oidc-client';
import { IgxLayoutModule, IgxNavbarModule, IgxNavigationDrawerModule, IgxRippleModule } from 'igniteui-angular';
import { App } from './app';
import { AuthenticationModule } from './authentication';

describe('App', () => {
beforeEach(async () => {
Expand All @@ -12,11 +14,14 @@ describe('App', () => {
NoopAnimationsModule,
RouterModule.forRoot([]),
IgxNavigationDrawerModule,
AuthenticationModule,
IgxNavbarModule,
IgxLayoutModule,
IgxRippleModule,
App
],
providers: [
importProvidersFrom(AuthModule.forRoot({ config: [] })),
provideHttpClient()
]
}).compileComponents();
});
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
export * from './auth.guard';
export * from './authentication-routing-module';
export * from './authentication-module';
export * from './models/login';
export * from './models/register-info';
export * from './models/user';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<button class="login-button" *ngIf="userService.currentUser" igxRipple="white" igxButton="flat" igxButtonBackground="c"
igxButtonColor="white" [igxToggleAction]="options">
<igx-avatar [initials]="userService.initials ?? ''" [src]="userService.currentUser.picture ?? ''"
[roundShape]="true" size="small" bgColor="white">
shape="circle" size="small" bgColor="white">
</igx-avatar>
<igx-icon>keyboard_arrow_down</igx-icon>
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { importProvidersFrom } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';
import { AuthModule } from 'angular-auth-oidc-client';
import {
IgxAvatarComponent,
Expand Down Expand Up @@ -54,7 +56,6 @@ describe('LoginBar', () => {
imports: [
RouterTestingModule,
NoopAnimationsModule,
AuthModule,
IgxAvatarModule,
IgxButtonModule,
IgxDialogModule,
Expand All @@ -66,6 +67,8 @@ describe('LoginBar', () => {
TestLoginDialog
],
providers: [
importProvidersFrom(AuthModule.forRoot({ config: [] })),
provideHttpClient(),
{ provide: UserService, useClass: TestUserServSpy },
{ provide: ExternalAuthService, useClass: TestAuthService }
]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { ExternalLogin } from '../models/login';

export interface AuthProvider {
config(): void;
login(): void;
getUserInfo(): Promise<ExternalLogin>;
logout(): void;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,71 +1,34 @@
import {
AuthWellKnownEndpoints,
OidcConfigService,
OidcSecurityService,
OpenIDImplicitFlowConfiguration
} from 'angular-auth-oidc-client';
import { take } from 'rxjs/operators';
import { OidcSecurityService } from 'angular-auth-oidc-client';
import { firstValueFrom } from 'rxjs';
import { ExternalLogin } from '../models/login';
import { ExternalAuthConfig } from '../services/external-auth-configs';
import { AuthProvider } from './auth-provider';

/** Base provider for OpenID Connect (OIDC) https://openid.net/connect/ */
export abstract class BaseOidcProvider implements AuthProvider {
constructor(
protected oidcConfigService: OidcConfigService,
protected oidcSecurityService: OidcSecurityService,
protected externalStsConfig: ExternalAuthConfig) { }

public config() {
const openIDImplicitFlowConfiguration = new OpenIDImplicitFlowConfiguration();
openIDImplicitFlowConfiguration.stsServer = this.externalStsConfig.stsServer;
openIDImplicitFlowConfiguration.redirect_url = this.externalStsConfig.redirect_url;
openIDImplicitFlowConfiguration.client_id = this.externalStsConfig.client_id;
openIDImplicitFlowConfiguration.response_type = this.externalStsConfig.response_type;
openIDImplicitFlowConfiguration.scope = this.externalStsConfig.scope;
openIDImplicitFlowConfiguration.post_logout_redirect_uri = this.externalStsConfig.redirect_url;
openIDImplicitFlowConfiguration.post_login_route = this.externalStsConfig.post_login_route;
openIDImplicitFlowConfiguration.auto_userinfo = this.externalStsConfig.auto_userinfo;
openIDImplicitFlowConfiguration.max_id_token_iat_offset_allowed_in_seconds =
this.externalStsConfig.max_id_token_iat_offset_allowed_in_seconds;

const authWellKnownEndpoints = new AuthWellKnownEndpoints();
authWellKnownEndpoints.setWellKnownEndpoints(this.oidcConfigService.wellKnownEndpoints);
this.oidcSecurityService.setupModule(openIDImplicitFlowConfiguration, authWellKnownEndpoints);
}

public login() {
this.oidcConfigService.onConfigurationLoaded.pipe(take(1)).subscribe(() => {
this.config();
this.oidcSecurityService.authorize();
});
this.oidcConfigService.load_using_stsServer(this.externalStsConfig.stsServer);
this.oidcSecurityService.authorize(this.externalStsConfig.configId);
}

public getUserInfo(): Promise<ExternalLogin> {
let resolve: (val: ExternalLogin) => void;
let reject: () => void;
const user = new Promise<ExternalLogin>((res, rej) => {
resolve = res;
reject = rej;
});
this.oidcConfigService.onConfigurationLoaded.pipe(take(1)).subscribe(() => {
this.config();
this.oidcSecurityService.onAuthorizationResult.subscribe(() => {
this.oidcSecurityService.getUserData().subscribe(userData => {
resolve(this.formatUserData(userData));
});
});
this.oidcSecurityService.authorizedImplicitFlowCallback();
});
this.oidcConfigService.load_using_stsServer(this.externalStsConfig.stsServer);
return user;
public async getUserInfo(): Promise<ExternalLogin> {
const result = await firstValueFrom(this.oidcSecurityService.userData$);
const configData = result.allUserData?.find(
d => d.configId === this.externalStsConfig.configId
);
if (configData?.userData) {
return this.formatUserData(configData.userData);
}
return Promise.reject(null);
}

public logout() {
this.oidcSecurityService.logoff();
this.oidcSecurityService.logoff(this.externalStsConfig.configId);
}

/** Format received user data per provider claims */
protected abstract formatUserData(userData: { [key: string]: any; }): ExternalLogin;
protected abstract formatUserData(userData: { [key: string]: any; }): Promise<ExternalLogin>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ export class FacebookProvider implements AuthProvider {
'/me?fields=id,email,name,first_name,last_name,picture',
(newResponse: { [key: string]: any; }) => {
this.user = {
id: newResponse.id,
name: newResponse.name,
given_name: newResponse.first_name,
family_name: newResponse.last_name,
email: newResponse.email,
picture: newResponse.picture,
externalToken: FB.getAuthResponse()[accessToken]
id: newResponse['id'],
name: newResponse['name'],
given_name: newResponse['first_name'],
family_name: newResponse['last_name'],
email: newResponse['email'],
picture: newResponse['picture'],
externalToken: FB.getAuthResponse()?.[accessToken] ?? ''
};
this.router.navigate([this.externalStsConfig.redirect_url]);
});
Expand Down
Loading