-
Notifications
You must be signed in to change notification settings - Fork 4
[NAE-2118] Implement OpenID Connector Auth for Admin node #286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release/7.0.0-rev3
Are you sure you want to change the base?
Changes from all commits
5540c11
b842c45
3ac92bb
df7dd13
ff174ba
8e3c165
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -5,6 +5,8 @@ import {UserService} from '../../user/services/user.service'; | |||||||||||||||
import {User} from '../../user/models/user'; | ||||||||||||||||
import {LoadingEmitter} from '../../utility/loading-emitter'; | ||||||||||||||||
import {take} from 'rxjs/operators'; | ||||||||||||||||
import {ConfigurationService} from "../../configuration/configuration.service"; | ||||||||||||||||
import {Sso} from "../../../commons/schema"; | ||||||||||||||||
|
||||||||||||||||
@Component({ | ||||||||||||||||
selector: 'ncc-abstract-login-field', | ||||||||||||||||
|
@@ -15,6 +17,7 @@ export abstract class AbstractLoginFormComponent implements HasForm, OnDestroy { | |||||||||||||||
public rootFormGroup: FormGroup; | ||||||||||||||||
public hidePassword = true; | ||||||||||||||||
public loading: LoadingEmitter; | ||||||||||||||||
protected showSsoButton: boolean; | ||||||||||||||||
|
||||||||||||||||
@Input() public showSignUpButton: boolean; | ||||||||||||||||
@Input() public showForgottenPasswordButton: boolean; | ||||||||||||||||
|
@@ -23,7 +26,7 @@ export abstract class AbstractLoginFormComponent implements HasForm, OnDestroy { | |||||||||||||||
@Output() public signUp: EventEmitter<void>; | ||||||||||||||||
@Output() public formSubmit: EventEmitter<FormSubmitEvent>; | ||||||||||||||||
|
||||||||||||||||
protected constructor(formBuilder: FormBuilder, protected _userService: UserService) { | ||||||||||||||||
protected constructor(formBuilder: FormBuilder, protected _userService: UserService, protected _config: ConfigurationService) { | ||||||||||||||||
this.rootFormGroup = formBuilder.group({ | ||||||||||||||||
login: [''], | ||||||||||||||||
password: [''] | ||||||||||||||||
|
@@ -33,6 +36,8 @@ export abstract class AbstractLoginFormComponent implements HasForm, OnDestroy { | |||||||||||||||
this.signUp = new EventEmitter<void>(); | ||||||||||||||||
this.formSubmit = new EventEmitter<FormSubmitEvent>(); | ||||||||||||||||
this.loading = new LoadingEmitter(); | ||||||||||||||||
let ssoConfig: Sso = this._config.getConfigurationSubtree(['providers', 'auth', 'sso']) | ||||||||||||||||
this.showSsoButton = ssoConfig?.enable | ||||||||||||||||
} | ||||||||||||||||
Comment on lines
+39
to
41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Defensive defaults &
- let ssoConfig: Sso = this._config.getConfigurationSubtree(['providers', 'auth', 'sso'])
- this.showSsoButton = ssoConfig?.enable
+ const ssoConfig: Sso | undefined =
+ this._config.getConfigurationSubtree(['providers', 'auth', 'sso']);
+ this.showSsoButton = !!ssoConfig?.enable; 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||
|
||||||||||||||||
ngOnDestroy(): void { | ||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
// todo 2118 |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,108 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {Component, OnDestroy} from "@angular/core"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {ActivatedRoute, Params, Router} from "@angular/router"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {Observable, throwError} from "rxjs"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {catchError} from "rxjs/operators"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {HttpClient} from "@angular/common/http"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {ConfigurationService} from "../../../configuration/configuration.service"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {LoggerService} from '../../../logger/services/logger.service'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {LoadingEmitter} from '../../../utility/loading-emitter'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {SnackBarService} from "../../../snack-bar/services/snack-bar.service"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {Sso} from "../../../../commons/schema"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import {TranslateService} from "@ngx-translate/core"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@Component({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
selector: 'ncc-abstract-login-field', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
template: '' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export abstract class AbstractLoginSsoComponent implements OnDestroy { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private _ssoConfig: Sso; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
protected loading: LoadingEmitter; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
protected constructor( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
protected _config: ConfigurationService, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
protected _http: HttpClient, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
protected _snackbar: SnackBarService, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
protected _log: LoggerService, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
protected _router: Router, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
protected _activeRouter: ActivatedRoute, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
protected _translate: TranslateService | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ssoConfig = this._config.getConfigurationSubtree(['providers', 'auth', 'sso']); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.loading = new LoadingEmitter(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+20
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Guard against missing SSO configuration - this._ssoConfig = this._config.getConfigurationSubtree(['providers', 'auth', 'sso']);
+ const subtree = this._config.getConfigurationSubtree(['providers', 'auth', 'sso']);
+ if (!subtree) {
+ this._log.error('SSO configuration subtree is missing – SSO button will not work');
+ return;
+ }
+ this._ssoConfig = subtree;
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._activeRouter.queryParams.subscribe((params) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!!params.code) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.loginFromCode(params); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+34
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Subscription is never disposed – memory-leak risk +import {Subscription} from 'rxjs';
…
- this._activeRouter.queryParams.subscribe((params) => {
+ this._paramsSub = this._activeRouter.queryParams.subscribe(params => {
if (params.code) {
this.loginFromCode(params);
}
}); and in the class body / - ngOnDestroy(): void {
- this.loading.complete();
- }
+ private _paramsSub?: Subscription;
+
+ ngOnDestroy(): void {
+ this._paramsSub?.unsubscribe();
+ this.loading.complete();
+ } 📝 Committable suggestion
Suggested change
🧰 Tools🪛 Biome (1.9.4)[error] 35-35: Avoid redundant double-negation. It is not necessary to use double-negation when a value will already be coerced to a boolean. (lint/complexity/noExtraBooleanCast) 🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ngOnDestroy(): void { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.loading.complete(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public redirectToSso(): void { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let redirectUrl: string = this.getRedirectUrl(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._log.info("Redirecting to " + redirectUrl) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
window.location.href = redirectUrl; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
public loginFromCode(params: Params) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!params.code) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.loading.on(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._log.debug('Handling access token: ' + params.code) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const token$ = this.getToken({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+57
to
+58
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Authorization code is sensitive – do not log it - this._log.debug('Handling access token: ' + params.code)
+ this._log.debug('Handling authorization-code callback') 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
grantType: 'authorization_code', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
code: params.code, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
realmId: '', // todo send realm id | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
redirectUri: location.origin + '/' + this._config.getConfigurationSubtree(['services', 'auth', 'toLoginRedirect']), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
token$.subscribe( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
token => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.loading.off(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!!token) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.redirectToHome(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private getRedirectUrl(): string { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const myQuery = this._ssoConfig.redirectUrl + '?'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const options: { [index: string]: string } = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
client_id: this._ssoConfig.clientId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
redirect_uri: location.origin + '/' + this._config.getConfigurationSubtree(['services', 'auth', 'toLoginRedirect']), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
response_type: 'code', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
scope: this._ssoConfig.scopes.join(' '), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return myQuery + Object.keys(options).map( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
key => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return encodeURIComponent(key) + '=' + encodeURIComponent(options[key]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
).join('&'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private getToken(body: any): Observable<any> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const url = this._ssoConfig.refreshUrl; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!url) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return throwError(() => new Error('Refresh URL is not defined in the config [nae.providers.auth.sso.refreshUrl]')); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._http.post(url, body, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{headers: {'Content-Type': 'application/json'}}).pipe( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
catchError(error => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.loading.off(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._snackbar.openErrorSnackBar(this._translate.instant('forms.login.wrongCredentials')); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return throwError(() => error); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private redirectToHome() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._router.navigate(['/' + this._config.getConfigurationSubtree(['services', 'auth', 'onLoginRedirect'])]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.then((value) => { this._log.debug('Routed to ' + value); }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,14 @@ | ||
import {Component} from '@angular/core'; | ||
import {FormBuilder} from '@angular/forms'; | ||
import {AbstractLoginFormComponent, UserService} from '@netgrif/components-core'; | ||
import {AbstractLoginFormComponent, ConfigurationService, UserService} from '@netgrif/components-core'; | ||
|
||
@Component({ | ||
selector: 'nc-login-form', | ||
templateUrl: './login-form.component.html', | ||
styleUrls: ['./login-form.component.scss'] | ||
}) | ||
export class LoginFormComponent extends AbstractLoginFormComponent { | ||
constructor(formBuilder: FormBuilder, protected _userService: UserService) { | ||
super(formBuilder, _userService); | ||
constructor(formBuilder: FormBuilder, protected _userService: UserService, protected _config: ConfigurationService) { | ||
super(formBuilder, _userService, _config); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<button color="primary" (click)="redirectToSso()" [disabled]="(loading | async)" mat-raised-button fxLayout="row" | ||
fxLayoutAlign="center center"> | ||
<mat-spinner *ngIf="loading | async" | ||
mode="indeterminate" | ||
diameter="36" | ||
color="accent" | ||
fxFlex></mat-spinner> | ||
<span *ngIf="(loading | async) === false" fxFlex>{{ 'forms.login.ssoButton' | translate }}</span> | ||
</button> |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,27 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { LoginSsoComponent } from './login-sso.component'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// todo 2118 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
xdescribe('LoginSsoComponent', () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let component: LoginSsoComponent; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let fixture: ComponentFixture<LoginSsoComponent>; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
beforeEach(async () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await TestBed.configureTestingModule({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
declarations: [ LoginSsoComponent ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.compileComponents(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
beforeEach(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fixture = TestBed.createComponent(LoginSsoComponent); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
component = fixture.componentInstance; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fixture.detectChanges(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
it('should create', () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
expect(component).toBeTruthy(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+5
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Disabled test suite hides compilation/runtime issues The whole spec is wrapped in
Unless there is a strong, short-term reason to skip, turn it into an active suite (or delete it until ready). -xdescribe('LoginSsoComponent', () => {
+describe('LoginSsoComponent', () => { If the component depends on external modules (Material, TranslateLib, etc.) add them to the testing module to prevent runtime failures. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import {HttpClient} from '@angular/common/http'; | ||
import {Component} from '@angular/core'; | ||
import {ActivatedRoute, Router} from '@angular/router'; | ||
import {AbstractLoginSsoComponent, ConfigurationService, LoggerService, SnackBarService} from '@netgrif/components-core'; | ||
import {TranslateService} from "@ngx-translate/core"; | ||
|
||
@Component({ | ||
selector: 'nc-login-sso', | ||
templateUrl: './login-sso.component.html', | ||
styleUrls: ['./login-sso.component.scss'], | ||
}) | ||
export class LoginSsoComponent extends AbstractLoginSsoComponent { | ||
constructor( | ||
protected _config: ConfigurationService, | ||
protected _http: HttpClient, | ||
protected _snackbar: SnackBarService, | ||
protected _log: LoggerService, | ||
protected _router: Router, | ||
protected _activeRouter: ActivatedRoute, | ||
protected _translate: TranslateService | ||
) { | ||
super(_config, _http, _snackbar, _log, _router, _activeRouter, _translate); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
❓ Verification inconclusive
Mixed-content risk:
refreshUrl
uses HTTP while the app is likely served over HTTPSBrowsers will block XMLHttpRequests from an HTTPS origin to an HTTP endpoint, breaking the token refresh flow in production.
Please verify that the service is reachable via HTTPS or proxy the call through the same origin.
Mixed-content risk:
refreshUrl
uses HTTP while the app is likely served over HTTPSBrowsers will block XMLHttpRequests from an HTTPS origin to an HTTP endpoint, breaking the token refresh flow in production.
Please verify that the service is reachable via HTTPS or proxy the call through the same origin.
🤖 Prompt for AI Agents