Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion nae.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"enable": false,
"clientId": "dev-cluster-worker",
"redirectUrl": "http://localhost:8081/realms/netgrif-cloud-testing/protocol/openid-connect/auth",
"refreshUrl": "http://localhost:8800/api/auth/login",
"refreshUrl": "http://localhost:8080/api/auth/login",
"scopes": ["openid","email","profile","roles"]
}
},
Expand Down
2 changes: 1 addition & 1 deletion projects/nae-example-app/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class AppComponent {
translate.setTranslation('en', en, true);
translate.setTranslation('sk', sk, true);

this.userService.user$.pipe(filter(u => !!u && u.id !== ''), take(1)).subscribe(() => {
this.userService.user$.pipe(filter(u => !!u && u.id !== '' && !u.isAnonymous()), take(1)).subscribe(() => {
const allNets = allowedNetsFactory.createWithAllNets();
allNets.allowedNetsIdentifiers$.pipe(take(1)).subscribe(nets => {
if (this.baseAllowedNets.allowedNets.length !== 0) {
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {ProxyAuthenticationService} from './proxyAuthentication.service';
import {AuthenticationMethodService} from './services/authentication-method.service';
import {OverlayModule} from '@angular/cdk/overlay';
import {MatProgressSpinnerModule} from '@angular/material/progress-spinner';
import {AnonymousAuthenticationInterceptor} from './services/anonymous-authentication-interceptor';
// import {AnonymousAuthenticationInterceptor} from './services/anonymous-authentication-interceptor';


@NgModule({
Expand All @@ -22,7 +22,7 @@ import {AnonymousAuthenticationInterceptor} from './services/anonymous-authentic
],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AuthenticationInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: AnonymousAuthenticationInterceptor, multi: true },
// { provide: HTTP_INTERCEPTORS, useClass: AnonymousAuthenticationInterceptor, multi: true },
{ provide: AuthenticationMethodService, useClass: ProxyAuthenticationService},
// AuthenticationEffects
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ export * from './sign-up/public-api';
/* MODULES */
export * from './authentication.module';

/* SERVICES */
export * from './anonymous/anonymous.service';
export * from './services/anonymous-authentication-interceptor'
// export * from './services/anonymous-authentication-interceptor'
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Remove the commented export from the public API surface.

Keeping commented exports in a public API file creates dead code and ambiguity. If this export is intentionally retired, delete it outright.

🧹 Suggested cleanup
-// export * from './services/anonymous-authentication-interceptor'
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// export * from './services/anonymous-authentication-interceptor'
🤖 Prompt for AI Agents
In `@projects/netgrif-components-core/src/lib/authentication/public-api.ts` at
line 13, Remove the commented dead export in public-api.ts: delete the line "//
export * from './services/anonymous-authentication-interceptor'". This cleans up
the public API surface by removing the stale commented export referencing the
anonymous-authentication-interceptor module.

export * from './services/authentication-interceptor'
export * from './proxyAuthentication.service'

Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import {Observable, throwError} from 'rxjs';
import {catchError, tap} from 'rxjs/operators';
import {SessionService} from '../session/services/session.service';
import {RedirectService} from '../../routing/redirect-service/redirect.service';
import {AnonymousService} from '../anonymous/anonymous.service';
// import {AnonymousService} from '../anonymous/anonymous.service';
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Remove commented-out import.

Delete the commented-out import rather than leaving dead code. If the AnonymousService dependency is permanently removed from this interceptor, clean up the remnants.

♻️ Proposed fix
-// import {AnonymousService} from '../anonymous/anonymous.service';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// import {AnonymousService} from '../anonymous/anonymous.service';
🤖 Prompt for AI Agents
In
`@projects/netgrif-components-core/src/lib/authentication/services/authentication-interceptor.ts`
at line 14, Remove the dead commented import for AnonymousService from
authentication-interceptor.ts and clean up any remaining references or leftover
comments related to AnonymousService in the AuthenticationInterceptor (e.g.,
constructor parameters, private fields, or TODO comments) so the file contains
only active imports and dependencies; ensure the import block and any unused
symbols in the AuthenticationInterceptor class are cleaned up to avoid linter
warnings.

import {SessionIdleTimerService} from "../session/services/session-idle-timer.service";

@Injectable()
export class AuthenticationInterceptor implements HttpInterceptor {

constructor(private _session: SessionService,
private _redirect: RedirectService,
private _anonymousService: AnonymousService,
// private _anonymousService: AnonymousService,
private idleTimerService: SessionIdleTimerService) {
}
Comment on lines 20 to 24
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Remove commented-out constructor parameter.

The commented-out _anonymousService parameter should be deleted for cleanliness.

♻️ Proposed fix
 constructor(private _session: SessionService,
             private _redirect: RedirectService,
-            // private _anonymousService: AnonymousService,
             private idleTimerService: SessionIdleTimerService) {
 }
🤖 Prompt for AI Agents
In
`@projects/netgrif-components-core/src/lib/authentication/services/authentication-interceptor.ts`
around lines 20 - 24, Remove the commented-out constructor parameter
_anonymousService from the AuthenticationInterceptor constructor: open the
constructor in authentication-interceptor.ts (the constructor method that
currently lists _session, _redirect, // private _anonymousService:
AnonymousService, and idleTimerService) and delete the commented line so the
constructor only declares the active dependencies (_session, _redirect,
idleTimerService).


Expand All @@ -37,7 +37,7 @@ export class AuthenticationInterceptor implements HttpInterceptor {
return next.handle(req).pipe(
tap(event => {
if (event instanceof HttpResponse) {
if (event.headers.has(this._session.sessionHeader) && !event.headers.has(this._anonymousService.jwtHeader)) {
if (event.headers.has(this._session.sessionHeader)) {
this._session.setVerifiedToken(event.headers.get(this._session.sessionHeader));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class AccessService {
if (view.access !== 'private') {
throw new Error(`Unknown access option '${view.access}'. Only 'public' or 'private' is allowed.`);
}
return !this._userService.user.isEmpty();
return !this._userService.user.isEmpty() && !this._userService.user.isAnonymous();
}

if (!url) {
Expand Down
10 changes: 10 additions & 0 deletions projects/netgrif-components-core/src/lib/filter/models/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ export abstract class Filter {
*/
public abstract bodyContainsQuery(): boolean;


/**
* Checks whether any of the filter bodies contains the `caseId` attribute.
*
* This method analyzes the body of the filter to determine if at least one of its parts includes a `caseId` field.
*
* @returns `true` if the `caseId` attribute exists in any of the filter bodies; otherwise, `false`.
*/
public abstract bodyContainsCaseId(): boolean;

/**
* Returns the necessary request params for the filter. Default implementation returns an empty object.
* The params are added on top of the request when sending it to the backend by the respective service methods.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ export class MergedFilter extends Filter {
return this._filters.some(f => f.query !== undefined && f.query !== null);
}

/**
* See [Filter.bodyContainsCaseId()]{@link Filter#bodyContainsCaseId}
*/
bodyContainsCaseId(): boolean {
return false;
}
Comment on lines +124 to +129
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Stub implementation may incorrectly return false for merged filters containing case IDs.

The existing bodyContainsQuery() method iterates through _filters using .some() to check all filter bodies. This stub always returns false, which would be incorrect if any underlying filter body contains a case property with an ID.

Consider implementing consistent logic:

🔧 Proposed fix to iterate filter bodies
     bodyContainsCaseId(): boolean {
-        return false;
+        return this._filters.some(f => 
+            !!f['case'] && 
+            ((!Array.isArray(f['case']) && !!f['case'].id && f['case'].id.length > 0) ||
+             (Array.isArray(f['case']) && f['case'].length > 0))
+        );
     }

Alternatively, if this stub is intentional (e.g., merged filters are never expected to contain case IDs in anonymous access scenarios), please add a comment explaining why returning false is correct.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* See [Filter.bodyContainsCaseId()]{@link Filter#bodyContainsCaseId}
*/
bodyContainsCaseId(): boolean {
return false;
}
/**
* See [Filter.bodyContainsCaseId()]{`@link` Filter#bodyContainsCaseId}
*/
bodyContainsCaseId(): boolean {
return this._filters.some(f =>
!!f['case'] &&
((!Array.isArray(f['case']) && !!f['case'].id && f['case'].id.length > 0) ||
(Array.isArray(f['case']) && f['case'].length > 0))
);
}
🤖 Prompt for AI Agents
In `@projects/netgrif-components-core/src/lib/filter/models/merged-filter.ts`
around lines 124 - 129, The bodyContainsCaseId() currently returns false but
should mirror the logic used in bodyContainsQuery() by scanning the merged
filters: update bodyContainsCaseId() to iterate this._filters and return true if
any contained filter indicates a case-id (either by calling
filter.bodyContainsCaseId() if available or by checking filter.body?.case?.id),
otherwise return false; if returning false was intentional, replace the stub
with a comment explaining why merged filters can never contain case IDs.


/**
* Returns the necessary request params for the filter.
* @returns params with `operation` set to either `AND` or `OR` based on this object's `_operator` property.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,20 @@ export class SimpleFilter extends Filter {
return this._filter.query !== undefined && this._filter.query !== null;
}

/**
* See [Filter.bodyContainsCaseId()]{@link Filter#bodyContainsCaseId}
*/
bodyContainsCaseId(): boolean {
return !!this._filter
&& !!this._filter['case']
&& ((!Array.isArray(this._filter['case'])
&& !!this._filter['case'].id
&& this._filter['case'].id.length > 0)
|| (Array.isArray(this._filter['case'])
&& this._filter['case'].length > 0));
}
Comment on lines +108 to +116
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Inconsistent validation between array and non-array case.

For a single case object (lines 111-113), you validate that id exists and is non-empty. For an array of cases (lines 114-115), you only check length > 0 without validating that any element has a valid id.

This inconsistency could cause bodyContainsCaseId() to return true for an array containing case objects with empty or missing IDs.

🔧 Proposed fix for consistent validation
     bodyContainsCaseId(): boolean {
         return !!this._filter
             && !!this._filter['case']
             && ((!Array.isArray(this._filter['case'])
                 && !!this._filter['case'].id
                 && this._filter['case'].id.length > 0)
             || (Array.isArray(this._filter['case'])
-                    && this._filter['case'].length > 0));
+                    && this._filter['case'].some(c => !!c.id && c.id.length > 0)));
     }

If the current behavior is intentional (any array presence is sufficient regardless of element validity), please add a clarifying comment.

🤖 Prompt for AI Agents
In `@projects/netgrif-components-core/src/lib/filter/models/simple-filter.ts`
around lines 108 - 116, The bodyContainsCaseId() method currently treats a
single case object and an array of cases inconsistently: for a single object it
checks this._filter['case'].id is present and non-empty, but for an array it
only checks length > 0. Update bodyContainsCaseId() so that when
this._filter['case'] is an array it returns true only if at least one element
has a non-empty id (e.g., iterate the array and validate item.id &&
item.id.length > 0), or if the array-presence behavior is intentional add a
clarifying comment above bodyContainsCaseId() explaining that any non-empty
array is considered valid regardless of element ids.



/**
* See [Filter.getRequestBody()]{@link Filter#getRequestBody}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,14 @@ export class NextGroupService implements OnDestroy {
protected _memberGroups$: BehaviorSubject<Array<Case>>;
protected _ownerGroups$: BehaviorSubject<Array<Case>>;

private _userSub: Subscription;

constructor(protected _userService: UserService, protected _caseResourceService: CaseResourceService) {
this._ownerGroups$ = new BehaviorSubject<Array<Case>>([]);
this._memberGroups$ = new BehaviorSubject<Array<Case>>([]);

this._userSub = this._userService.user$.pipe(
switchMap(user => {
if (!user || user.id === '') {
return of([]);
}

const params = new HttpParams().set(PaginationParams.PAGE_SIZE, `${(user as any).nextGroups.length}`);

return this._caseResourceService.searchCases(SimpleFilter.fromCaseQuery({id: (user as any).nextGroups}), params)
.pipe(
map(page => page.content ? page.content : []),
map(groups => groups.filter(group => group.author.fullName !== 'application engine'))
);
})
).subscribe(groups => {
const ownerGroups = groups.filter(g => g.author.email === this._userService.user.email);
this._ownerGroups$.next(ownerGroups);
this._memberGroups$.next(groups);
});
}

ngOnDestroy(): void {
this._userSub.unsubscribe();
this._memberGroups$.complete();
this._ownerGroups$.complete();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import {UserResourceService} from '../../resources/engine-endpoint/user-resource
import {UserTransformer} from '../../authentication/models/user.transformer';
import {SessionService} from '../../authentication/session/services/session.service';
import {User} from '../../user/models/user';
import {AnonymousService} from '../../authentication/anonymous/anonymous.service';
import {ActiveGroupService} from '../../groups/services/active-group.service';
import {TaskResourceService} from '../../resources/engine-endpoint/task-resource.service';
import {LanguageService} from '../../translate/language.service';
Expand Down Expand Up @@ -396,9 +395,9 @@ class TestUserService extends UserService {
userTransform: UserTransformer,
log: LoggerService,
session: SessionService,
anonymousService: AnonymousService,
// anonymousService: AnonymousService,
config: ConfigurationService) {
super(authService, userResource, userTransform, log, session, anonymousService, config);
super(authService, userResource, userTransform, log, session, config);
Comment on lines +398 to +400
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Remove commented-out code instead of leaving it in place.

The anonymousService parameter on line 398 should be deleted entirely rather than commented out. Leaving dead code as comments clutters the codebase and creates maintenance burden, especially since version control already preserves the history.

♻️ Suggested cleanup
 `@Injectable`()
 class TestUserService extends UserService {

     constructor(authService: AuthenticationService,
                 userResource: UserResourceService,
                 userTransform: UserTransformer,
                 log: LoggerService,
                 session: SessionService,
-                // anonymousService: AnonymousService,
                 config: ConfigurationService) {
         super(authService, userResource, userTransform, log, session, config);
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// anonymousService: AnonymousService,
config: ConfigurationService) {
super(authService, userResource, userTransform, log, session, anonymousService, config);
super(authService, userResource, userTransform, log, session, config);
config: ConfigurationService) {
super(authService, userResource, userTransform, log, session, config);
🤖 Prompt for AI Agents
In
`@projects/netgrif-components-core/src/lib/navigation/navigation-tree/abstract-navigation-tree.component.spec.ts`
around lines 398 - 400, Remove the commented-out parameter "anonymousService"
from the constructor signature and any related commented code; update the
constructor declaration that currently shows "// anonymousService:
AnonymousService," so it only lists the real parameters (e.g., authService,
config) and ensure the corresponding super(...) call in the test still matches
the actual parameters passed to the parent constructor (authService,
userResource, userTransform, log, session, config) in the spec for the class
under test.

}

public setUser(user: User) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const publicFactoryResolver = (userService: UserService, sessionService:
} else {
router.navigate([url], {queryParams: redirectService.queryParams});
}
} else if (authService.isAuthenticated && userService.user.id !== '' && userService.user.email !== 'anonymous@netgrif.com') {
} else if (authService.isAuthenticated && !!userService.user && !userService.user.isAnonymous()) {
return privateService;
} else {
return publicService;
Expand Down
Loading
Loading