Browse Source

Task/move auth and subscription controllers to endpoints (#8290)

Move auth and subscription controllers to endpoints
pull/8216/head
Thomas Kaul 4 days ago
committed by GitHub
parent
commit
3bc504ead9
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      apps/api/src/app/app.module.ts
  2. 0
      apps/api/src/app/endpoints/auth/api-key.strategy.ts
  3. 15
      apps/api/src/app/endpoints/auth/auth.controller.ts
  4. 4
      apps/api/src/app/endpoints/auth/auth.module.ts
  5. 0
      apps/api/src/app/endpoints/auth/auth.service.ts
  6. 0
      apps/api/src/app/endpoints/auth/generate-authentication-options.dto.ts
  7. 0
      apps/api/src/app/endpoints/auth/google.strategy.ts
  8. 0
      apps/api/src/app/endpoints/auth/interfaces/interfaces.ts
  9. 0
      apps/api/src/app/endpoints/auth/jwt.strategy.ts
  10. 0
      apps/api/src/app/endpoints/auth/oidc-state.store.ts
  11. 0
      apps/api/src/app/endpoints/auth/oidc.helper.spec.ts
  12. 0
      apps/api/src/app/endpoints/auth/oidc.helper.ts
  13. 0
      apps/api/src/app/endpoints/auth/oidc.strategy.ts
  14. 0
      apps/api/src/app/endpoints/auth/web-auth.service.ts
  15. 2
      apps/api/src/app/endpoints/info/info.module.ts
  16. 2
      apps/api/src/app/endpoints/info/info.service.ts
  17. 10
      apps/api/src/app/endpoints/subscription/subscription.controller.ts
  18. 13
      apps/api/src/app/endpoints/subscription/subscription.module.ts
  19. 2
      apps/api/src/app/user/user.module.ts
  20. 2
      apps/api/src/app/user/user.service.ts
  21. 2
      apps/api/src/services/impersonation/impersonation.module.ts
  22. 2
      apps/api/src/services/impersonation/impersonation.service.spec.ts
  23. 2
      apps/api/src/services/impersonation/impersonation.service.ts
  24. 2
      apps/api/src/services/subscription/subscription.module.ts
  25. 0
      apps/api/src/services/subscription/subscription.service.ts
  26. 2
      libs/common/src/lib/interfaces/index.ts
  27. 4
      libs/common/src/lib/interfaces/responses/redeem-coupon-response.interface.ts
  28. 10
      libs/ui/src/lib/services/data.service.ts

4
apps/api/src/app/app.module.ts

@ -40,12 +40,12 @@ import { AccountModule } from './account/account.module';
import { ActivitiesModule } from './activities/activities.module'; import { ActivitiesModule } from './activities/activities.module';
import { AdminModule } from './admin/admin.module'; import { AdminModule } from './admin/admin.module';
import { AppController } from './app.controller'; import { AppController } from './app.controller';
import { AuthModule } from './auth/auth.module';
import { AiModule } from './endpoints/ai/ai.module'; import { AiModule } from './endpoints/ai/ai.module';
import { ApiKeysModule } from './endpoints/api-keys/api-keys.module'; import { ApiKeysModule } from './endpoints/api-keys/api-keys.module';
import { AssetProfilesModule } from './endpoints/asset-profiles/asset-profiles.module'; import { AssetProfilesModule } from './endpoints/asset-profiles/asset-profiles.module';
import { AssetsModule } from './endpoints/assets/assets.module'; import { AssetsModule } from './endpoints/assets/assets.module';
import { AuthDevicesModule } from './endpoints/auth-devices/auth-devices.module'; import { AuthDevicesModule } from './endpoints/auth-devices/auth-devices.module';
import { AuthModule } from './endpoints/auth/auth.module';
import { BenchmarksModule } from './endpoints/benchmarks/benchmarks.module'; import { BenchmarksModule } from './endpoints/benchmarks/benchmarks.module';
import { CacheModule } from './endpoints/cache/cache.module'; import { CacheModule } from './endpoints/cache/cache.module';
import { GhostfolioModule } from './endpoints/data-providers/ghostfolio/ghostfolio.module'; import { GhostfolioModule } from './endpoints/data-providers/ghostfolio/ghostfolio.module';
@ -60,10 +60,10 @@ import { McpModule } from './endpoints/mcp/mcp.module';
import { PlatformsModule } from './endpoints/platforms/platforms.module'; import { PlatformsModule } from './endpoints/platforms/platforms.module';
import { PublicModule } from './endpoints/public/public.module'; import { PublicModule } from './endpoints/public/public.module';
import { SitemapModule } from './endpoints/sitemap/sitemap.module'; import { SitemapModule } from './endpoints/sitemap/sitemap.module';
import { SubscriptionModule } from './endpoints/subscription/subscription.module';
import { TagsModule } from './endpoints/tags/tags.module'; import { TagsModule } from './endpoints/tags/tags.module';
import { WatchlistModule } from './endpoints/watchlist/watchlist.module'; import { WatchlistModule } from './endpoints/watchlist/watchlist.module';
import { PortfolioModule } from './portfolio/portfolio.module'; import { PortfolioModule } from './portfolio/portfolio.module';
import { SubscriptionModule } from './subscription/subscription.module';
import { SymbolModule } from './symbol/symbol.module'; import { SymbolModule } from './symbol/symbol.module';
import { UserModule } from './user/user.module'; import { UserModule } from './user/user.module';

0
apps/api/src/app/auth/api-key.strategy.ts → apps/api/src/app/endpoints/auth/api-key.strategy.ts

15
apps/api/src/app/auth/auth.controller.ts → apps/api/src/app/endpoints/auth/auth.controller.ts

@ -1,10 +1,10 @@
import { WebAuthService } from '@ghostfolio/api/app/auth/web-auth.service';
import { AllowDuringImpersonation } from '@ghostfolio/api/decorators/allow-during-impersonation.decorator'; import { AllowDuringImpersonation } from '@ghostfolio/api/decorators/allow-during-impersonation.decorator';
import { CustomThrottlerGuard } from '@ghostfolio/api/guards/custom-throttler.guard'; import { CustomThrottlerGuard } from '@ghostfolio/api/guards/custom-throttler.guard';
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
import { OAuthCallbackGuard } from '@ghostfolio/api/guards/oauth-callback.guard'; import { OAuthCallbackGuard } from '@ghostfolio/api/guards/oauth-callback.guard';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DEFAULT_LANGUAGE_CODE } from '@ghostfolio/common/config'; import { DEFAULT_LANGUAGE_CODE } from '@ghostfolio/common/config';
import { AuthDeviceDto } from '@ghostfolio/common/dtos';
import { import {
AssertionCredentialJSON, AssertionCredentialJSON,
AttestationCredentialJSON, AttestationCredentialJSON,
@ -24,11 +24,16 @@ import {
VERSION_NEUTRAL VERSION_NEUTRAL
} from '@nestjs/common'; } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport'; import { AuthGuard } from '@nestjs/passport';
import type {
PublicKeyCredentialCreationOptionsJSON,
PublicKeyCredentialRequestOptionsJSON
} from '@simplewebauthn/server';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { getReasonPhrase, StatusCodes } from 'http-status-codes'; import { getReasonPhrase, StatusCodes } from 'http-status-codes';
import { AuthService } from './auth.service'; import { AuthService } from './auth.service';
import { GenerateAuthenticationOptionsDto } from './generate-authentication-options.dto'; import { GenerateAuthenticationOptionsDto } from './generate-authentication-options.dto';
import { WebAuthService } from './web-auth.service';
@AllowDuringImpersonation() @AllowDuringImpersonation()
@Controller('auth') @Controller('auth')
@ -124,13 +129,13 @@ export class AuthController {
@UseGuards(CustomThrottlerGuard) @UseGuards(CustomThrottlerGuard)
public async generateAuthenticationOptions( public async generateAuthenticationOptions(
@Body() body: GenerateAuthenticationOptionsDto @Body() body: GenerateAuthenticationOptionsDto
) { ): Promise<PublicKeyCredentialRequestOptionsJSON> {
return this.webAuthService.generateAuthenticationOptions(body.deviceId); return this.webAuthService.generateAuthenticationOptions(body.deviceId);
} }
@Get('webauthn/generate-registration-options') @Get('webauthn/generate-registration-options')
@UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseGuards(AuthGuard('jwt'), HasPermissionGuard)
public async generateRegistrationOptions() { public async generateRegistrationOptions(): Promise<PublicKeyCredentialCreationOptionsJSON> {
return this.webAuthService.generateRegistrationOptions(); return this.webAuthService.generateRegistrationOptions();
} }
@ -138,7 +143,7 @@ export class AuthController {
@UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseGuards(AuthGuard('jwt'), HasPermissionGuard)
public async verifyAttestation( public async verifyAttestation(
@Body() body: { deviceName: string; credential: AttestationCredentialJSON } @Body() body: { deviceName: string; credential: AttestationCredentialJSON }
) { ): Promise<AuthDeviceDto> {
return this.webAuthService.verifyAttestation(body.credential); return this.webAuthService.verifyAttestation(body.credential);
} }
@ -146,7 +151,7 @@ export class AuthController {
@UseGuards(CustomThrottlerGuard) @UseGuards(CustomThrottlerGuard)
public async verifyAuthentication( public async verifyAuthentication(
@Body() body: { deviceId: string; credential: AssertionCredentialJSON } @Body() body: { deviceId: string; credential: AssertionCredentialJSON }
) { ): Promise<OAuthResponse> {
try { try {
const authToken = await this.webAuthService.verifyAuthentication( const authToken = await this.webAuthService.verifyAuthentication(
body.deviceId, body.deviceId,

4
apps/api/src/app/auth/auth.module.ts → apps/api/src/app/endpoints/auth/auth.module.ts

@ -1,5 +1,3 @@
import { WebAuthService } from '@ghostfolio/api/app/auth/web-auth.service';
import { SubscriptionModule } from '@ghostfolio/api/app/subscription/subscription.module';
import { UserModule } from '@ghostfolio/api/app/user/user.module'; import { UserModule } from '@ghostfolio/api/app/user/user.module';
import { ApiKeyService } from '@ghostfolio/api/services/api-key/api-key.service'; import { ApiKeyService } from '@ghostfolio/api/services/api-key/api-key.service';
import { ApiModule } from '@ghostfolio/api/services/api/api.module'; import { ApiModule } from '@ghostfolio/api/services/api/api.module';
@ -24,6 +22,7 @@ import { GoogleStrategy } from './google.strategy';
import { JwtStrategy } from './jwt.strategy'; import { JwtStrategy } from './jwt.strategy';
import { getOidcDiscoveryUrl } from './oidc.helper'; import { getOidcDiscoveryUrl } from './oidc.helper';
import { OidcStrategy } from './oidc.strategy'; import { OidcStrategy } from './oidc.strategy';
import { WebAuthService } from './web-auth.service';
@Module({ @Module({
controllers: [AuthController], controllers: [AuthController],
@ -40,7 +39,6 @@ import { OidcStrategy } from './oidc.strategy';
PrismaModule, PrismaModule,
PropertyModule, PropertyModule,
RedisCacheModule, RedisCacheModule,
SubscriptionModule,
UserModule UserModule
], ],
providers: [ providers: [

0
apps/api/src/app/auth/auth.service.ts → apps/api/src/app/endpoints/auth/auth.service.ts

0
apps/api/src/app/auth/generate-authentication-options.dto.ts → apps/api/src/app/endpoints/auth/generate-authentication-options.dto.ts

0
apps/api/src/app/auth/google.strategy.ts → apps/api/src/app/endpoints/auth/google.strategy.ts

0
apps/api/src/app/auth/interfaces/interfaces.ts → apps/api/src/app/endpoints/auth/interfaces/interfaces.ts

0
apps/api/src/app/auth/jwt.strategy.ts → apps/api/src/app/endpoints/auth/jwt.strategy.ts

0
apps/api/src/app/auth/oidc-state.store.ts → apps/api/src/app/endpoints/auth/oidc-state.store.ts

0
apps/api/src/app/auth/oidc.helper.spec.ts → apps/api/src/app/endpoints/auth/oidc.helper.spec.ts

0
apps/api/src/app/auth/oidc.helper.ts → apps/api/src/app/endpoints/auth/oidc.helper.ts

0
apps/api/src/app/auth/oidc.strategy.ts → apps/api/src/app/endpoints/auth/oidc.strategy.ts

0
apps/api/src/app/auth/web-auth.service.ts → apps/api/src/app/endpoints/auth/web-auth.service.ts

2
apps/api/src/app/endpoints/info/info.module.ts

@ -1,4 +1,3 @@
import { SubscriptionModule } from '@ghostfolio/api/app/subscription/subscription.module';
import { UserModule } from '@ghostfolio/api/app/user/user.module'; import { UserModule } from '@ghostfolio/api/app/user/user.module';
import { TransformDataSourceInResponseModule } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.module'; import { TransformDataSourceInResponseModule } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.module';
import { BenchmarkModule } from '@ghostfolio/api/services/benchmark/benchmark.module'; import { BenchmarkModule } from '@ghostfolio/api/services/benchmark/benchmark.module';
@ -10,6 +9,7 @@ import { PlatformModule } from '@ghostfolio/api/services/platform/platform.modul
import { PropertyModule } from '@ghostfolio/api/services/property/property.module'; import { PropertyModule } from '@ghostfolio/api/services/property/property.module';
import { DataGatheringQueueModule } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.module'; import { DataGatheringQueueModule } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.module';
import { RedisCacheModule } from '@ghostfolio/api/services/redis-cache/redis-cache.module'; import { RedisCacheModule } from '@ghostfolio/api/services/redis-cache/redis-cache.module';
import { SubscriptionModule } from '@ghostfolio/api/services/subscription/subscription.module';
import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile/symbol-profile.module'; import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile/symbol-profile.module';
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';

2
apps/api/src/app/endpoints/info/info.service.ts

@ -1,4 +1,3 @@
import { SubscriptionService } from '@ghostfolio/api/app/subscription/subscription.service';
import { UserService } from '@ghostfolio/api/app/user/user.service'; import { UserService } from '@ghostfolio/api/app/user/user.service';
import { BenchmarkService } from '@ghostfolio/api/services/benchmark/benchmark.service'; import { BenchmarkService } from '@ghostfolio/api/services/benchmark/benchmark.service';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
@ -7,6 +6,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-
import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service'; import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import { RedisCacheService } from '@ghostfolio/api/services/redis-cache/redis-cache.service'; import { RedisCacheService } from '@ghostfolio/api/services/redis-cache/redis-cache.service';
import { SubscriptionService } from '@ghostfolio/api/services/subscription/subscription.service';
import { import {
DEFAULT_CURRENCY, DEFAULT_CURRENCY,
ghostfolioFearAndGreedIndexSymbolStocks, ghostfolioFearAndGreedIndexSymbolStocks,

10
apps/api/src/app/subscription/subscription.controller.ts → apps/api/src/app/endpoints/subscription/subscription.controller.ts

@ -3,13 +3,15 @@ import { CustomThrottlerGuard } from '@ghostfolio/api/guards/custom-throttler.gu
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service'; import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import { SubscriptionService } from '@ghostfolio/api/services/subscription/subscription.service';
import { import {
DEFAULT_LANGUAGE_CODE, DEFAULT_LANGUAGE_CODE,
PROPERTY_COUPONS PROPERTY_COUPONS
} from '@ghostfolio/common/config'; } from '@ghostfolio/common/config';
import { import {
Coupon, Coupon,
CreateStripeCheckoutSessionResponse CreateStripeCheckoutSessionResponse,
RedeemCouponResponse
} from '@ghostfolio/common/interfaces'; } from '@ghostfolio/common/interfaces';
import type { RequestWithUser } from '@ghostfolio/common/types'; import type { RequestWithUser } from '@ghostfolio/common/types';
@ -31,8 +33,6 @@ import { AuthGuard } from '@nestjs/passport';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import { StatusCodes, getReasonPhrase } from 'http-status-codes'; import { StatusCodes, getReasonPhrase } from 'http-status-codes';
import { SubscriptionService } from './subscription.service';
@AllowDuringImpersonation() @AllowDuringImpersonation()
@Controller('subscription') @Controller('subscription')
export class SubscriptionController { export class SubscriptionController {
@ -48,7 +48,9 @@ export class SubscriptionController {
@Post('redeem-coupon') @Post('redeem-coupon')
@HttpCode(StatusCodes.OK) @HttpCode(StatusCodes.OK)
@UseGuards(AuthGuard('jwt'), CustomThrottlerGuard, HasPermissionGuard) @UseGuards(AuthGuard('jwt'), CustomThrottlerGuard, HasPermissionGuard)
public async redeemCoupon(@Body() { couponCode }: { couponCode: string }) { public async redeemCoupon(
@Body() { couponCode }: { couponCode: string }
): Promise<RedeemCouponResponse> {
if (!this.request.user) { if (!this.request.user) {
throw new HttpException( throw new HttpException(
getReasonPhrase(StatusCodes.FORBIDDEN), getReasonPhrase(StatusCodes.FORBIDDEN),

13
apps/api/src/app/endpoints/subscription/subscription.module.ts

@ -0,0 +1,13 @@
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
import { PropertyModule } from '@ghostfolio/api/services/property/property.module';
import { SubscriptionModule as SubscriptionServiceModule } from '@ghostfolio/api/services/subscription/subscription.module';
import { Module } from '@nestjs/common';
import { SubscriptionController } from './subscription.controller';
@Module({
controllers: [SubscriptionController],
imports: [ConfigurationModule, PropertyModule, SubscriptionServiceModule]
})
export class SubscriptionModule {}

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

@ -1,5 +1,4 @@
import { ActivitiesModule } from '@ghostfolio/api/app/activities/activities.module'; import { ActivitiesModule } from '@ghostfolio/api/app/activities/activities.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 { RedactValuesInResponseModule } from '@ghostfolio/api/interceptors/redact-values-in-response/redact-values-in-response.module';
import { TransformDataSourceInResponseModule } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.module'; import { TransformDataSourceInResponseModule } from '@ghostfolio/api/interceptors/transform-data-source-in-response/transform-data-source-in-response.module';
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module'; import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
@ -7,6 +6,7 @@ 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';
import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module'; import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module';
import { PropertyModule } from '@ghostfolio/api/services/property/property.module'; import { PropertyModule } from '@ghostfolio/api/services/property/property.module';
import { SubscriptionModule } from '@ghostfolio/api/services/subscription/subscription.module';
import { TagModule } from '@ghostfolio/api/services/tag/tag.module'; import { TagModule } from '@ghostfolio/api/services/tag/tag.module';
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';

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

@ -1,5 +1,4 @@
import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service'; import { ActivitiesService } from '@ghostfolio/api/app/activities/activities.service';
import { SubscriptionService } from '@ghostfolio/api/app/subscription/subscription.service';
import { environment } from '@ghostfolio/api/environments/environment'; import { environment } from '@ghostfolio/api/environments/environment';
import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event'; import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event';
import { getSupportedLanguageCode } from '@ghostfolio/api/helper/language.helper'; import { getSupportedLanguageCode } from '@ghostfolio/api/helper/language.helper';
@ -9,6 +8,7 @@ import { ConfigurationService } from '@ghostfolio/api/services/configuration/con
import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service'; import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import { SubscriptionService } from '@ghostfolio/api/services/subscription/subscription.service';
import { TagService } from '@ghostfolio/api/services/tag/tag.service'; import { TagService } from '@ghostfolio/api/services/tag/tag.service';
import { import {
DEFAULT_CURRENCY, DEFAULT_CURRENCY,

2
apps/api/src/services/impersonation/impersonation.module.ts

@ -1,8 +1,8 @@
import { AccessModule } from '@ghostfolio/api/app/access/access.module'; import { AccessModule } from '@ghostfolio/api/app/access/access.module';
import { SubscriptionModule } from '@ghostfolio/api/app/subscription/subscription.module';
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module'; import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service'; import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service';
import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module'; import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module';
import { SubscriptionModule } from '@ghostfolio/api/services/subscription/subscription.module';
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';

2
apps/api/src/services/impersonation/impersonation.service.spec.ts

@ -1,7 +1,7 @@
import { AccessService } from '@ghostfolio/api/app/access/access.service'; import { AccessService } from '@ghostfolio/api/app/access/access.service';
import { SubscriptionService } from '@ghostfolio/api/app/subscription/subscription.service';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { SubscriptionService } from '@ghostfolio/api/services/subscription/subscription.service';
import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; import { DEFAULT_CURRENCY } from '@ghostfolio/common/config';
import { SubscriptionType } from '@ghostfolio/common/enums'; import { SubscriptionType } from '@ghostfolio/common/enums';
import { permissions } from '@ghostfolio/common/permissions'; import { permissions } from '@ghostfolio/common/permissions';

2
apps/api/src/services/impersonation/impersonation.service.ts

@ -1,7 +1,7 @@
import { AccessService } from '@ghostfolio/api/app/access/access.service'; import { AccessService } from '@ghostfolio/api/app/access/access.service';
import { SubscriptionService } from '@ghostfolio/api/app/subscription/subscription.service';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service';
import { SubscriptionService } from '@ghostfolio/api/services/subscription/subscription.service';
import { DEFAULT_CURRENCY } from '@ghostfolio/common/config'; import { DEFAULT_CURRENCY } from '@ghostfolio/common/config';
import { UserSettings } from '@ghostfolio/common/interfaces'; import { UserSettings } from '@ghostfolio/common/interfaces';
import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { hasPermission, permissions } from '@ghostfolio/common/permissions';

2
apps/api/src/app/subscription/subscription.module.ts → apps/api/src/services/subscription/subscription.module.ts

@ -4,11 +4,9 @@ import { PropertyModule } from '@ghostfolio/api/services/property/property.modul
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { SubscriptionController } from './subscription.controller';
import { SubscriptionService } from './subscription.service'; import { SubscriptionService } from './subscription.service';
@Module({ @Module({
controllers: [SubscriptionController],
exports: [SubscriptionService], exports: [SubscriptionService],
imports: [ConfigurationModule, PrismaModule, PropertyModule], imports: [ConfigurationModule, PrismaModule, PropertyModule],
providers: [SubscriptionService] providers: [SubscriptionService]

0
apps/api/src/app/subscription/subscription.service.ts → apps/api/src/services/subscription/subscription.service.ts

2
libs/common/src/lib/interfaces/index.ts

@ -86,6 +86,7 @@ import type { PortfolioPerformanceResponse } from './responses/portfolio-perform
import type { PortfolioReportResponse } from './responses/portfolio-report.interface'; import type { PortfolioReportResponse } from './responses/portfolio-report.interface';
import type { PublicPortfolioResponse } from './responses/public-portfolio-response.interface'; import type { PublicPortfolioResponse } from './responses/public-portfolio-response.interface';
import type { QuotesResponse } from './responses/quotes-response.interface'; import type { QuotesResponse } from './responses/quotes-response.interface';
import type { RedeemCouponResponse } from './responses/redeem-coupon-response.interface';
import type { WatchlistResponse } from './responses/watchlist-response.interface'; import type { WatchlistResponse } from './responses/watchlist-response.interface';
import type { RuleSettings } from './rule-settings.interface'; import type { RuleSettings } from './rule-settings.interface';
import type { ScraperConfiguration } from './scraper-configuration.interface'; import type { ScraperConfiguration } from './scraper-configuration.interface';
@ -192,6 +193,7 @@ export {
PublicKeyCredentialRequestOptionsJSON, PublicKeyCredentialRequestOptionsJSON,
PublicPortfolioResponse, PublicPortfolioResponse,
QuotesResponse, QuotesResponse,
RedeemCouponResponse,
ReferralPartner, ReferralPartner,
ResponseError, ResponseError,
RuleSettings, RuleSettings,

4
libs/common/src/lib/interfaces/responses/redeem-coupon-response.interface.ts

@ -0,0 +1,4 @@
export interface RedeemCouponResponse {
message: string;
statusCode: number;
}

10
libs/ui/src/lib/services/data.service.ts

@ -57,6 +57,7 @@ import {
PortfolioPerformanceResponse, PortfolioPerformanceResponse,
PortfolioReportResponse, PortfolioReportResponse,
PublicPortfolioResponse, PublicPortfolioResponse,
RedeemCouponResponse,
SymbolItem, SymbolItem,
User, User,
UserItem, UserItem,
@ -967,9 +968,12 @@ export class DataService {
} }
public redeemCoupon(couponCode: string) { public redeemCoupon(couponCode: string) {
return this.http.post('/api/v1/subscription/redeem-coupon', { return this.http.post<RedeemCouponResponse>(
couponCode '/api/v1/subscription/redeem-coupon',
}); {
couponCode
}
);
} }
public transferAccountBalance({ public transferAccountBalance({

Loading…
Cancel
Save