Browse Source

Various improvements

pull/6231/head
Thomas Kaul 3 days ago
parent
commit
d1f33b6aa1
  1. 13
      apps/api/src/app/user/user.controller.ts
  2. 2
      apps/api/src/app/user/user.module.ts
  3. 34
      apps/api/src/app/user/user.service.ts
  4. 8
      apps/api/src/services/tag/tag.service.ts

13
apps/api/src/app/user/user.controller.ts

@ -1,5 +1,6 @@
import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator'; import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator';
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
import { RedactValuesInResponseInterceptor } from '@ghostfolio/api/interceptors/redact-values-in-response/redact-values-in-response.interceptor';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service'; import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
@ -30,7 +31,8 @@ import {
Param, Param,
Post, Post,
Put, Put,
UseGuards UseGuards,
UseInterceptors
} from '@nestjs/common'; } from '@nestjs/common';
import { REQUEST } from '@nestjs/core'; import { REQUEST } from '@nestjs/core';
import { JwtService } from '@nestjs/jwt'; import { JwtService } from '@nestjs/jwt';
@ -110,6 +112,7 @@ export class UserController {
@Get() @Get()
@UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseGuards(AuthGuard('jwt'), HasPermissionGuard)
@UseInterceptors(RedactValuesInResponseInterceptor)
public async getUser( public async getUser(
@Headers('accept-language') acceptLanguage: string, @Headers('accept-language') acceptLanguage: string,
@Headers(HEADER_KEY_IMPERSONATION.toLowerCase()) impersonationId: string @Headers(HEADER_KEY_IMPERSONATION.toLowerCase()) impersonationId: string
@ -117,11 +120,11 @@ export class UserController {
const impersonationUserId = const impersonationUserId =
await this.impersonationService.validateImpersonationId(impersonationId); await this.impersonationService.validateImpersonationId(impersonationId);
return this.userService.getUser( return this.userService.getUser({
this.request.user,
impersonationUserId, impersonationUserId,
acceptLanguage?.split(',')?.[0] locale: acceptLanguage?.split(',')?.[0],
); user: this.request.user
});
} }
@Post() @Post()

2
apps/api/src/app/user/user.module.ts

@ -1,5 +1,6 @@
import { OrderModule } from '@ghostfolio/api/app/order/order.module'; import { OrderModule } from '@ghostfolio/api/app/order/order.module';
import { SubscriptionModule } from '@ghostfolio/api/app/subscription/subscription.module'; import { SubscriptionModule } from '@ghostfolio/api/app/subscription/subscription.module';
import { RedactValuesInResponseModule } from '@ghostfolio/api/interceptors/redact-values-in-response/redact-values-in-response.module';
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module'; import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
import { I18nModule } from '@ghostfolio/api/services/i18n/i18n.module'; import { I18nModule } from '@ghostfolio/api/services/i18n/i18n.module';
import { ImpersonationModule } from '@ghostfolio/api/services/impersonation/impersonation.module'; import { ImpersonationModule } from '@ghostfolio/api/services/impersonation/impersonation.module';
@ -27,6 +28,7 @@ import { UserService } from './user.service';
OrderModule, OrderModule,
PrismaModule, PrismaModule,
PropertyModule, PropertyModule,
RedactValuesInResponseModule,
SubscriptionModule, SubscriptionModule,
TagModule TagModule
], ],

34
apps/api/src/app/user/user.service.ts

@ -30,7 +30,7 @@ import {
PROPERTY_IS_READ_ONLY_MODE, PROPERTY_IS_READ_ONLY_MODE,
PROPERTY_SYSTEM_MESSAGE, PROPERTY_SYSTEM_MESSAGE,
TAG_ID_EXCLUDE_FROM_ANALYSIS, TAG_ID_EXCLUDE_FROM_ANALYSIS,
locale locale as defaultLocale
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { import {
User as IUser, User as IUser,
@ -96,11 +96,17 @@ export class UserService {
return { accessToken, hashedAccessToken }; return { accessToken, hashedAccessToken };
} }
public async getUser( public async getUser({
{ accounts, id, permissions, settings, subscription }: UserWithSettings, impersonationUserId,
impersonationUserId: string, locale = defaultLocale,
aLocale = locale user
): Promise<IUser> { }: {
impersonationUserId: string;
locale?: string;
user: UserWithSettings;
}): Promise<IUser> {
const { id, permissions, settings, subscription } = user;
const userData = await Promise.all([ const userData = await Promise.all([
this.prismaService.access.findMany({ this.prismaService.access.findMany({
include: { include: {
@ -114,23 +120,23 @@ export class UserService {
name: 'asc' name: 'asc'
}, },
where: { where: {
userId: impersonationUserId userId: impersonationUserId || user.id
} }
}), }),
this.prismaService.order.count({ this.prismaService.order.count({
where: { userId: id } where: { userId: impersonationUserId || user.id }
}), }),
this.prismaService.order.findFirst({ this.prismaService.order.findFirst({
orderBy: { orderBy: {
date: 'asc' date: 'asc'
}, },
where: { userId: id } where: { userId: impersonationUserId || user.id }
}), }),
this.tagService.getTagsForUser(id) this.tagService.getTagsForUser(impersonationUserId || user.id)
]); ]);
const access = userData[0]; const access = userData[0];
const impersonationAccounts = userData[1]; const accounts = userData[1];
const activitiesCount = userData[2]; const activitiesCount = userData[2];
const firstActivity = userData[3]; const firstActivity = userData[3];
let tags = userData[4].filter((tag) => { let tags = userData[4].filter((tag) => {
@ -169,11 +175,13 @@ export class UserService {
permissions: accessItem.permissions permissions: accessItem.permissions
}; };
}), }),
accounts: impersonationUserId ? impersonationAccounts : accounts, accounts: sortBy(accounts, ({ name }) => {
return name.toLowerCase();
}),
dateOfFirstActivity: firstActivity?.date ?? new Date(), dateOfFirstActivity: firstActivity?.date ?? new Date(),
settings: { settings: {
...(settings.settings as UserSettings), ...(settings.settings as UserSettings),
locale: (settings.settings as UserSettings)?.locale ?? aLocale locale: (settings.settings as UserSettings)?.locale ?? locale
} }
}; };
} }

8
apps/api/src/services/tag/tag.service.ts

@ -75,12 +75,16 @@ export class TagService {
} }
}); });
return tags.map(({ _count, id, name, userId }) => ({ return tags
.map(({ _count, id, name, userId }) => ({
id, id,
name, name,
userId, userId,
isUsed: _count.activities > 0 isUsed: _count.activities > 0
})); }))
.sort((a, b) => {
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
});
} }
public async getTagsWithActivityCount() { public async getTagsWithActivityCount() {

Loading…
Cancel
Save