diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 234996edd..2edffc8d3 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -652,8 +652,6 @@ export class PortfolioController { const report = await this.portfolioService.getReport({ userId }); if ( - // The evaluations of the rules interpolate absolute values, hence they - // are withheld from a restricted view hasReadRestrictedAccessPermission({ accesses: this.request.user?.accessesGet, impersonationId: accessId diff --git a/apps/api/src/app/user/user.controller.ts b/apps/api/src/app/user/user.controller.ts index 8e0324943..50471c8bc 100644 --- a/apps/api/src/app/user/user.controller.ts +++ b/apps/api/src/app/user/user.controller.ts @@ -181,8 +181,9 @@ export class UserController { return !isUserSettingOfAuthenticatedUser(key); }) ) { - // While impersonating, the presented settings of the impersonated user - // must not be written back to the authenticated user + // While impersonating, only the settings which stay with the + // authenticated user can be changed, as the update is always written + // back to the authenticated user throw new HttpException( getReasonPhrase(StatusCodes.FORBIDDEN), StatusCodes.FORBIDDEN diff --git a/apps/api/src/decorators/allow-during-impersonation.decorator.ts b/apps/api/src/decorators/allow-during-impersonation.decorator.ts index 0a3a3cc96..4795bcf90 100644 --- a/apps/api/src/decorators/allow-during-impersonation.decorator.ts +++ b/apps/api/src/decorators/allow-during-impersonation.decorator.ts @@ -2,9 +2,11 @@ import { SetMetadata } from '@nestjs/common'; export const ALLOW_DURING_IMPERSONATION_KEY = 'allow_during_impersonation'; -// Marks a controller or a route which modifies data of the authenticated user -// instead of data of the impersonated user, hence it stays available while an -// impersonation is active +/** + * Marks a controller or a route which modifies data of the authenticated user + * instead of data of the impersonated user, hence it stays available while an + * impersonation is active + */ export function AllowDuringImpersonation() { return SetMetadata(ALLOW_DURING_IMPERSONATION_KEY, true); } diff --git a/apps/api/src/decorators/impersonation.decorator.ts b/apps/api/src/decorators/impersonation.decorator.ts index e831309db..190542459 100644 --- a/apps/api/src/decorators/impersonation.decorator.ts +++ b/apps/api/src/decorators/impersonation.decorator.ts @@ -5,8 +5,10 @@ import type { import { createParamDecorator, ExecutionContext } from '@nestjs/common'; -// Provides the impersonation context of the request, which requires the -// ImpersonationGuard to be applied to the route +/** + * Provides the impersonation context of the request, which requires the + * ImpersonationGuard to be applied to the route + */ export const Impersonation = createParamDecorator( (_data: unknown, context: ExecutionContext): ImpersonationContext => { const { impersonation, user } = context diff --git a/apps/api/src/guards/impersonation-write.guard.ts b/apps/api/src/guards/impersonation-write.guard.ts index 8119fa048..ec94c8e10 100644 --- a/apps/api/src/guards/impersonation-write.guard.ts +++ b/apps/api/src/guards/impersonation-write.guard.ts @@ -10,10 +10,12 @@ import { import { Reflector } from '@nestjs/core'; import { StatusCodes, getReasonPhrase } from 'http-status-codes'; -// Denies modifying requests while an impersonation is active, so that data of -// the authenticated user cannot be changed from a view presenting data of the -// impersonated user. The header is evaluated instead of the resolved context to -// fail closed, also for an identifier which cannot be resolved. +/** + * Blocks write requests while an impersonation is active, so that data of the + * authenticated user cannot be changed from a view presenting data of the + * impersonated user. The header is evaluated instead of the resolved context to + * fail closed, also for an identifier which cannot be resolved. + */ @Injectable() export class ImpersonationWriteGuard implements CanActivate { public constructor(private readonly reflector: Reflector) {} diff --git a/apps/api/src/services/impersonation/impersonation.service.ts b/apps/api/src/services/impersonation/impersonation.service.ts index df1e85983..f3083e96c 100644 --- a/apps/api/src/services/impersonation/impersonation.service.ts +++ b/apps/api/src/services/impersonation/impersonation.service.ts @@ -38,8 +38,8 @@ export class ImpersonationService { }); return { - isActive: true, accessId: impersonationId, + isActive: true, userId: impersonatedUserId, userSettings: { ...((settings?.settings ?? {}) as UserSettings), diff --git a/libs/common/src/lib/types/impersonation-context.type.ts b/libs/common/src/lib/types/impersonation-context.type.ts index 8d13efcd0..f5afb6bc7 100644 --- a/libs/common/src/lib/types/impersonation-context.type.ts +++ b/libs/common/src/lib/types/impersonation-context.type.ts @@ -1,8 +1,10 @@ import { UserSettings } from '@ghostfolio/common/interfaces'; -// Describes whose data a request presents. The user id and the settings belong -// to the impersonated user while an impersonation is active and to the -// authenticated user otherwise, so a handler can use them unconditionally. +/** + * Describes whose data a request presents. The user id and the settings belong + * to the impersonated user while an impersonation is active and to the + * authenticated user otherwise, so a handler can use them unconditionally. + */ export interface ImpersonationContext { accessId?: string; isActive: boolean;