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. 8
      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 { AdminModule } from './admin/admin.module';
import { AppController } from './app.controller';
import { AuthModule } from './auth/auth.module';
import { AiModule } from './endpoints/ai/ai.module';
import { ApiKeysModule } from './endpoints/api-keys/api-keys.module';
import { AssetProfilesModule } from './endpoints/asset-profiles/asset-profiles.module';
import { AssetsModule } from './endpoints/assets/assets.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 { CacheModule } from './endpoints/cache/cache.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 { PublicModule } from './endpoints/public/public.module';
import { SitemapModule } from './endpoints/sitemap/sitemap.module';
import { SubscriptionModule } from './endpoints/subscription/subscription.module';
import { TagsModule } from './endpoints/tags/tags.module';
import { WatchlistModule } from './endpoints/watchlist/watchlist.module';
import { PortfolioModule } from './portfolio/portfolio.module';
import { SubscriptionModule } from './subscription/subscription.module';
import { SymbolModule } from './symbol/symbol.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 { CustomThrottlerGuard } from '@ghostfolio/api/guards/custom-throttler.guard';
import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard';
import { OAuthCallbackGuard } from '@ghostfolio/api/guards/oauth-callback.guard';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { DEFAULT_LANGUAGE_CODE } from '@ghostfolio/common/config';
import { AuthDeviceDto } from '@ghostfolio/common/dtos';
import {
AssertionCredentialJSON,
AttestationCredentialJSON,
@ -24,11 +24,16 @@ import {
VERSION_NEUTRAL
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import type {
PublicKeyCredentialCreationOptionsJSON,
PublicKeyCredentialRequestOptionsJSON
} from '@simplewebauthn/server';
import { Request, Response } from 'express';
import { getReasonPhrase, StatusCodes } from 'http-status-codes';
import { AuthService } from './auth.service';
import { GenerateAuthenticationOptionsDto } from './generate-authentication-options.dto';
import { WebAuthService } from './web-auth.service';
@AllowDuringImpersonation()
@Controller('auth')
@ -124,13 +129,13 @@ export class AuthController {
@UseGuards(CustomThrottlerGuard)
public async generateAuthenticationOptions(
@Body() body: GenerateAuthenticationOptionsDto
) {
): Promise<PublicKeyCredentialRequestOptionsJSON> {
return this.webAuthService.generateAuthenticationOptions(body.deviceId);
}
@Get('webauthn/generate-registration-options')
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
public async generateRegistrationOptions() {
public async generateRegistrationOptions(): Promise<PublicKeyCredentialCreationOptionsJSON> {
return this.webAuthService.generateRegistrationOptions();
}
@ -138,7 +143,7 @@ export class AuthController {
@UseGuards(AuthGuard('jwt'), HasPermissionGuard)
public async verifyAttestation(
@Body() body: { deviceName: string; credential: AttestationCredentialJSON }
) {
): Promise<AuthDeviceDto> {
return this.webAuthService.verifyAttestation(body.credential);
}
@ -146,7 +151,7 @@ export class AuthController {
@UseGuards(CustomThrottlerGuard)
public async verifyAuthentication(
@Body() body: { deviceId: string; credential: AssertionCredentialJSON }
) {
): Promise<OAuthResponse> {
try {
const authToken = await this.webAuthService.verifyAuthentication(
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 { ApiKeyService } from '@ghostfolio/api/services/api-key/api-key.service';
import { ApiModule } from '@ghostfolio/api/services/api/api.module';
@ -24,6 +22,7 @@ import { GoogleStrategy } from './google.strategy';
import { JwtStrategy } from './jwt.strategy';
import { getOidcDiscoveryUrl } from './oidc.helper';
import { OidcStrategy } from './oidc.strategy';
import { WebAuthService } from './web-auth.service';
@Module({
controllers: [AuthController],
@ -40,7 +39,6 @@ import { OidcStrategy } from './oidc.strategy';
PrismaModule,
PropertyModule,
RedisCacheModule,
SubscriptionModule,
UserModule
],
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 { 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';
@ -10,6 +9,7 @@ import { PlatformModule } from '@ghostfolio/api/services/platform/platform.modul
import { PropertyModule } from '@ghostfolio/api/services/property/property.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 { SubscriptionModule } from '@ghostfolio/api/services/subscription/subscription.module';
import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile/symbol-profile.module';
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 { BenchmarkService } from '@ghostfolio/api/services/benchmark/benchmark.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 { PropertyService } from '@ghostfolio/api/services/property/property.service';
import { RedisCacheService } from '@ghostfolio/api/services/redis-cache/redis-cache.service';
import { SubscriptionService } from '@ghostfolio/api/services/subscription/subscription.service';
import {
DEFAULT_CURRENCY,
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 { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service';
import { PropertyService } from '@ghostfolio/api/services/property/property.service';
import { SubscriptionService } from '@ghostfolio/api/services/subscription/subscription.service';
import {
DEFAULT_LANGUAGE_CODE,
PROPERTY_COUPONS
} from '@ghostfolio/common/config';
import {
Coupon,
CreateStripeCheckoutSessionResponse
CreateStripeCheckoutSessionResponse,
RedeemCouponResponse
} from '@ghostfolio/common/interfaces';
import type { RequestWithUser } from '@ghostfolio/common/types';
@ -31,8 +33,6 @@ import { AuthGuard } from '@nestjs/passport';
import { Request, Response } from 'express';
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
import { SubscriptionService } from './subscription.service';
@AllowDuringImpersonation()
@Controller('subscription')
export class SubscriptionController {
@ -48,7 +48,9 @@ export class SubscriptionController {
@Post('redeem-coupon')
@HttpCode(StatusCodes.OK)
@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) {
throw new HttpException(
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 { SubscriptionModule } from '@ghostfolio/api/app/subscription/subscription.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 { 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 { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.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 { 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 { SubscriptionService } from '@ghostfolio/api/app/subscription/subscription.service';
import { environment } from '@ghostfolio/api/environments/environment';
import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event';
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 { PrismaService } from '@ghostfolio/api/services/prisma/prisma.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 {
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 { SubscriptionModule } from '@ghostfolio/api/app/subscription/subscription.module';
import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module';
import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service';
import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module';
import { SubscriptionModule } from '@ghostfolio/api/services/subscription/subscription.module';
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 { SubscriptionService } from '@ghostfolio/api/app/subscription/subscription.service';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.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 { SubscriptionType } from '@ghostfolio/common/enums';
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 { SubscriptionService } from '@ghostfolio/api/app/subscription/subscription.service';
import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.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 { UserSettings } from '@ghostfolio/common/interfaces';
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 { SubscriptionController } from './subscription.controller';
import { SubscriptionService } from './subscription.service';
@Module({
controllers: [SubscriptionController],
exports: [SubscriptionService],
imports: [ConfigurationModule, PrismaModule, PropertyModule],
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 { PublicPortfolioResponse } from './responses/public-portfolio-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 { RuleSettings } from './rule-settings.interface';
import type { ScraperConfiguration } from './scraper-configuration.interface';
@ -192,6 +193,7 @@ export {
PublicKeyCredentialRequestOptionsJSON,
PublicPortfolioResponse,
QuotesResponse,
RedeemCouponResponse,
ReferralPartner,
ResponseError,
RuleSettings,

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

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

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

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

Loading…
Cancel
Save