feat: add BYPASS_APP_AUTH token to AuthBearerInterceptor and use it in TimeSyncService

This commit is contained in:
copilot-swe-agent[bot]
2026-07-02 08:23:13 +00:00
committed by GitHub
parent 22956e4671
commit adcf1e64a1
4 changed files with 33 additions and 4 deletions
@@ -15,10 +15,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { HttpClient, HttpHandler, HttpRequest } from '@angular/common/http'; import { HttpClient, HttpContext, HttpHandler, HttpRequest } from '@angular/common/http';
import { TestBed } from '@angular/core/testing'; import { TestBed } from '@angular/core/testing';
import { EMPTY, Observable, of } from 'rxjs'; import { EMPTY, Observable, of } from 'rxjs';
import { AuthBearerInterceptor } from './auth-bearer.interceptor'; import { AuthBearerInterceptor, BYPASS_APP_AUTH } from './auth-bearer.interceptor';
import { AuthenticationService } from '../services/authentication.service'; import { AuthenticationService } from '../services/authentication.service';
import { RedirectAuthService } from '../oidc/redirect-auth.service'; import { RedirectAuthService } from '../oidc/redirect-auth.service';
@@ -105,4 +105,13 @@ describe('AuthBearerInterceptor', () => {
expect(addTokenToHeaderSpy).toHaveBeenCalledTimes(mockUrls.length); expect(addTokenToHeaderSpy).toHaveBeenCalledTimes(mockUrls.length);
}); });
it('should not add auth token when BYPASS_APP_AUTH context token is set to true, even for a non-excluded URL', () => {
const context = new HttpContext().set(BYPASS_APP_AUTH, true);
const req = new HttpRequest('GET', 'https://example.com/someotherpath', null, { context });
interceptor.intercept(req, mockNext);
expect(addTokenToHeaderSpy).not.toHaveBeenCalled();
});
}); });
@@ -18,6 +18,7 @@
import { throwError as observableThrowError, Observable } from 'rxjs'; import { throwError as observableThrowError, Observable } from 'rxjs';
import { Injectable, inject } from '@angular/core'; import { Injectable, inject } from '@angular/core';
import { import {
HttpContextToken,
HttpHandler, HttpHandler,
HttpInterceptor, HttpInterceptor,
HttpRequest, HttpRequest,
@@ -31,6 +32,8 @@ import {
import { catchError, mergeMap } from 'rxjs/operators'; import { catchError, mergeMap } from 'rxjs/operators';
import { AuthenticationService } from '../services/authentication.service'; import { AuthenticationService } from '../services/authentication.service';
export const BYPASS_APP_AUTH = new HttpContextToken<boolean>(() => false);
@Injectable() @Injectable()
export class AuthBearerInterceptor implements HttpInterceptor { export class AuthBearerInterceptor implements HttpInterceptor {
private readonly authenticationService = inject(AuthenticationService); private readonly authenticationService = inject(AuthenticationService);
@@ -48,6 +51,10 @@ export class AuthBearerInterceptor implements HttpInterceptor {
req: HttpRequest<any>, req: HttpRequest<any>,
next: HttpHandler next: HttpHandler
): Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> { ): Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {
if (req.context.get(BYPASS_APP_AUTH)) {
return next.handle(req).pipe(catchError((error) => observableThrowError(error)));
}
if (!this.excludedUrlsRegex) { if (!this.excludedUrlsRegex) {
this.loadExcludedUrlsRegex(); this.loadExcludedUrlsRegex();
} }
@@ -21,6 +21,7 @@ import { TestBed } from '@angular/core/testing';
import { AppConfigService } from '../../app-config/app-config.service'; import { AppConfigService } from '../../app-config/app-config.service';
import { TimeSyncService } from './time-sync.service'; import { TimeSyncService } from './time-sync.service';
import { firstValueFrom } from 'rxjs'; import { firstValueFrom } from 'rxjs';
import { BYPASS_APP_AUTH } from '../authentication-interceptor/auth-bearer.interceptor';
describe('TimeSyncService', () => { describe('TimeSyncService', () => {
let service: TimeSyncService; let service: TimeSyncService;
@@ -127,6 +128,17 @@ describe('TimeSyncService', () => {
expect(req.request.method).toBe('GET'); expect(req.request.method).toBe('GET');
req.error(new ProgressEvent('')); req.error(new ProgressEvent(''));
}); });
it('should set BYPASS_APP_AUTH context token and not send Authorization header on the server time request', () => {
appConfigSpy.get.and.returnValue('http://fake-server-time-url');
service.checkTimeSync(60).subscribe();
const req = httpMock.expectOne('http://fake-server-time-url');
expect(req.request.context.get(BYPASS_APP_AUTH)).toBeTrue();
expect(req.request.headers.has('Authorization')).toBeFalse();
req.flush(Date.now());
});
}); });
describe('isLocalTimeOutOfSync', () => { describe('isLocalTimeOutOfSync', () => {
@@ -15,11 +15,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { HttpClient } from '@angular/common/http'; import { HttpClient, HttpContext } from '@angular/common/http';
import { Injectable, Injector, inject } from '@angular/core'; import { Injectable, Injector, inject } from '@angular/core';
import { AppConfigService } from '../../app-config/app-config.service'; import { AppConfigService } from '../../app-config/app-config.service';
import { from, Observable, throwError } from 'rxjs'; import { from, Observable, throwError } from 'rxjs';
import { catchError, map, timeout } from 'rxjs/operators'; import { catchError, map, timeout } from 'rxjs/operators';
import { BYPASS_APP_AUTH } from '../authentication-interceptor/auth-bearer.interceptor';
export interface TimeSync { export interface TimeSync {
outOfSync: boolean; outOfSync: boolean;
@@ -85,7 +86,7 @@ export class TimeSyncService {
} }
private getServerTime(): Observable<number> { private getServerTime(): Observable<number> {
return from(this._http.get<number>(this.getServerTimeUrl())).pipe( return from(this._http.get<number>(this.getServerTimeUrl(), { context: new HttpContext().set(BYPASS_APP_AUTH, true) })).pipe(
timeout(5000), timeout(5000),
catchError(() => throwError(() => new Error('Failed to get server time'))) catchError(() => throwError(() => new Error('Failed to get server time')))
); );