diff --git a/CHANGELOG.md b/CHANGELOG.md index c0bfc2081..a9931838a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,16 +9,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Upgraded `nx` from version `21.5.1` to `22.1.3` +- Upgraded `nx` from version `21.5.1` to `22.1.` -## 2.221.0 - 2025-12-01 +### Changed + +- Moved the notification module to `@ghostfolio/ui` +- Improved the language localization for German (`de`) -#### Added +## 2.222.0 - 2025-12-07 + +### Added - Introduced data source transformation support in the import functionality for self-hosted environments +- Added _OpenID Connect_ (`OIDC`) as a new login provider for self-hosted environments (experimental) - Added an optional 3D hover effect to the membership card component -#### Changed +### Changed - Increased the numerical precision for cryptocurrency quantities in the holding detail dialog - Upgraded `envalid` from version `8.1.0` to `8.1.1` diff --git a/README.md b/README.md index 1a5cc6e95..822825b57 100644 --- a/README.md +++ b/README.md @@ -85,24 +85,39 @@ We provide official container images hosted on [Docker Hub](https://hub.docker.c ### Supported Environment Variables -| Name | Type | Default Value | Description | -| ------------------------ | --------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `ACCESS_TOKEN_SALT` | `string` | | A random string used as salt for access tokens | -| `API_KEY_COINGECKO_DEMO` | `string` (optional) |   | The _CoinGecko_ Demo API key | -| `API_KEY_COINGECKO_PRO` | `string` (optional) | | The _CoinGecko_ Pro API key | -| `DATABASE_URL` | `string` | | The database connection URL, e.g. `postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}?sslmode=prefer` | -| `HOST` | `string` (optional) | `0.0.0.0` | The host where the Ghostfolio application will run on | -| `JWT_SECRET_KEY` | `string` | | A random string used for _JSON Web Tokens_ (JWT) | -| `LOG_LEVELS` | `string[]` (optional) | | The logging levels for the Ghostfolio application, e.g. `["debug","error","log","warn"]` | -| `PORT` | `number` (optional) | `3333` | The port where the Ghostfolio application will run on | -| `POSTGRES_DB` | `string` | | The name of the _PostgreSQL_ database | -| `POSTGRES_PASSWORD` | `string` | | The password of the _PostgreSQL_ database | -| `POSTGRES_USER` | `string` | | The user of the _PostgreSQL_ database | -| `REDIS_DB` | `number` (optional) | `0` | The database index of _Redis_ | -| `REDIS_HOST` | `string` | | The host where _Redis_ is running | -| `REDIS_PASSWORD` | `string` | | The password of _Redis_ | -| `REDIS_PORT` | `number` | | The port where _Redis_ is running | -| `REQUEST_TIMEOUT` | `number` (optional) | `2000` | The timeout of network requests to data providers in milliseconds | +| Name | Type | Default Value | Description | +| ------------------------ | --------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| `ACCESS_TOKEN_SALT` | `string` | | A random string used as salt for access tokens | +| `API_KEY_COINGECKO_DEMO` | `string` (optional) |   | The _CoinGecko_ Demo API key | +| `API_KEY_COINGECKO_PRO` | `string` (optional) | | The _CoinGecko_ Pro API key | +| `DATABASE_URL` | `string` | | The database connection URL, e.g. `postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}?sslmode=prefer` | +| `HOST` | `string` (optional) | `0.0.0.0` | The host where the Ghostfolio application will run on | +| `JWT_SECRET_KEY` | `string` | | A random string used for _JSON Web Tokens_ (JWT) | +| `LOG_LEVELS` | `string[]` (optional) | | The logging levels for the Ghostfolio application, e.g. `["debug","error","log","warn"]` | +| `PORT` | `number` (optional) | `3333` | The port where the Ghostfolio application will run on | +| `POSTGRES_DB` | `string` | | The name of the _PostgreSQL_ database | +| `POSTGRES_PASSWORD` | `string` | | The password of the _PostgreSQL_ database | +| `POSTGRES_USER` | `string` | | The user of the _PostgreSQL_ database | +| `REDIS_DB` | `number` (optional) | `0` | The database index of _Redis_ | +| `REDIS_HOST` | `string` | | The host where _Redis_ is running | +| `REDIS_PASSWORD` | `string` | | The password of _Redis_ | +| `REDIS_PORT` | `number` | | The port where _Redis_ is running | +| `REQUEST_TIMEOUT` | `number` (optional) | `2000` | The timeout of network requests to data providers in milliseconds | +| `ROOT_URL` | `string` (optional) | `http://0.0.0.0:3333` | The root URL of the Ghostfolio application, used for generating callback URLs and external links. | + +#### OpenID Connect OIDC (Experimental) + +| Name | Type | Default Value | Description | +| -------------------------- | --------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------- | +| `ENABLE_FEATURE_AUTH_OIDC` | `boolean` (optional) | `false` | Enables _OpenID Connect_ authentication | +| `OIDC_AUTHORIZATION_URL` | `string` (optional) | | Manual override for the OIDC authorization endpoint (falls back to the discovery from the issuer) | +| `OIDC_CALLBACK_URL` | `string` (optional) | `${ROOT_URL}/api/auth/oidc/callback` | The OIDC callback URL | +| `OIDC_CLIENT_ID` | `string` | | The OIDC client ID | +| `OIDC_CLIENT_SECRET` | `string` | | The OIDC client secret | +| `OIDC_ISSUER` | `string` | | The OIDC issuer URL, used to discover the OIDC configuration via `/.well-known/openid-configuration` | +| `OIDC_SCOPE` | `string[]` (optional) | `["openid"]` | The OIDC scope to request, e.g. `["email","openid","profile"]` | +| `OIDC_TOKEN_URL` | `string` (optional) | | Manual override for the OIDC token endpoint (falls back to the discovery from the issuer) | +| `OIDC_USER_INFO_URL` | `string` (optional) | | Manual override for the OIDC user info endpoint (falls back to the discovery from the issuer) | ### Run with Docker Compose diff --git a/apps/api/src/app/auth/auth.controller.ts b/apps/api/src/app/auth/auth.controller.ts index b45e7b97b..388f1dbd3 100644 --- a/apps/api/src/app/auth/auth.controller.ts +++ b/apps/api/src/app/auth/auth.controller.ts @@ -84,7 +84,6 @@ export class AuthController { @Req() request: Request, @Res() response: Response ) { - // Handles the Google OAuth2 callback const jwt: string = (request.user as any).jwt; if (jwt) { @@ -102,6 +101,46 @@ export class AuthController { } } + @Get('oidc') + @UseGuards(AuthGuard('oidc')) + @Version(VERSION_NEUTRAL) + public oidcLogin() { + if (!this.configurationService.get('ENABLE_FEATURE_AUTH_OIDC')) { + throw new HttpException( + getReasonPhrase(StatusCodes.FORBIDDEN), + StatusCodes.FORBIDDEN + ); + } + } + + @Get('oidc/callback') + @UseGuards(AuthGuard('oidc')) + @Version(VERSION_NEUTRAL) + public oidcLoginCallback(@Req() request: Request, @Res() response: Response) { + const jwt: string = (request.user as any).jwt; + + if (jwt) { + response.redirect( + `${this.configurationService.get( + 'ROOT_URL' + )}/${DEFAULT_LANGUAGE_CODE}/auth/${jwt}` + ); + } else { + response.redirect( + `${this.configurationService.get( + 'ROOT_URL' + )}/${DEFAULT_LANGUAGE_CODE}/auth` + ); + } + } + + @Post('webauthn/generate-authentication-options') + public async generateAuthenticationOptions( + @Body() body: { deviceId: string } + ) { + return this.webAuthService.generateAuthenticationOptions(body.deviceId); + } + @Get('webauthn/generate-registration-options') @UseGuards(AuthGuard('jwt'), HasPermissionGuard) public async generateRegistrationOptions() { @@ -116,13 +155,6 @@ export class AuthController { return this.webAuthService.verifyAttestation(body.credential); } - @Post('webauthn/generate-authentication-options') - public async generateAuthenticationOptions( - @Body() body: { deviceId: string } - ) { - return this.webAuthService.generateAuthenticationOptions(body.deviceId); - } - @Post('webauthn/verify-authentication') public async verifyAuthentication( @Body() body: { deviceId: string; credential: AssertionCredentialJSON } diff --git a/apps/api/src/app/auth/auth.module.ts b/apps/api/src/app/auth/auth.module.ts index 824c432b1..9fc5d0925 100644 --- a/apps/api/src/app/auth/auth.module.ts +++ b/apps/api/src/app/auth/auth.module.ts @@ -4,17 +4,20 @@ import { SubscriptionModule } from '@ghostfolio/api/app/subscription/subscriptio import { UserModule } from '@ghostfolio/api/app/user/user.module'; import { ApiKeyService } from '@ghostfolio/api/services/api-key/api-key.service'; import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module'; import { PropertyModule } from '@ghostfolio/api/services/property/property.module'; -import { Module } from '@nestjs/common'; +import { Logger, Module } from '@nestjs/common'; import { JwtModule } from '@nestjs/jwt'; +import type { StrategyOptions } from 'passport-openidconnect'; import { ApiKeyStrategy } from './api-key.strategy'; import { AuthController } from './auth.controller'; import { AuthService } from './auth.service'; import { GoogleStrategy } from './google.strategy'; import { JwtStrategy } from './jwt.strategy'; +import { OidcStrategy } from './oidc.strategy'; @Module({ controllers: [AuthController], @@ -36,6 +39,83 @@ import { JwtStrategy } from './jwt.strategy'; AuthService, GoogleStrategy, JwtStrategy, + { + inject: [AuthService, ConfigurationService], + provide: OidcStrategy, + useFactory: async ( + authService: AuthService, + configurationService: ConfigurationService + ) => { + const isOidcEnabled = configurationService.get( + 'ENABLE_FEATURE_AUTH_OIDC' + ); + + if (!isOidcEnabled) { + return null; + } + + const issuer = configurationService.get('OIDC_ISSUER'); + const scope = configurationService.get('OIDC_SCOPE'); + + const callbackUrl = + configurationService.get('OIDC_CALLBACK_URL') || + `${configurationService.get('ROOT_URL')}/api/auth/oidc/callback`; + + // Check for manual URL overrides + const manualAuthorizationUrl = configurationService.get( + 'OIDC_AUTHORIZATION_URL' + ); + const manualTokenUrl = configurationService.get('OIDC_TOKEN_URL'); + const manualUserInfoUrl = + configurationService.get('OIDC_USER_INFO_URL'); + + let authorizationURL: string; + let tokenURL: string; + let userInfoURL: string; + + if (manualAuthorizationUrl && manualTokenUrl && manualUserInfoUrl) { + // Use manual URLs + authorizationURL = manualAuthorizationUrl; + tokenURL = manualTokenUrl; + userInfoURL = manualUserInfoUrl; + } else { + // Fetch OIDC configuration from discovery endpoint + try { + const response = await fetch( + `${issuer}/.well-known/openid-configuration` + ); + + const config = (await response.json()) as { + authorization_endpoint: string; + token_endpoint: string; + userinfo_endpoint: string; + }; + + // Manual URLs take priority over discovered ones + authorizationURL = + manualAuthorizationUrl || config.authorization_endpoint; + tokenURL = manualTokenUrl || config.token_endpoint; + userInfoURL = manualUserInfoUrl || config.userinfo_endpoint; + } catch (error) { + Logger.error(error, 'OidcStrategy'); + throw new Error('Failed to fetch OIDC configuration from issuer'); + } + } + + const options: StrategyOptions = { + authorizationURL, + issuer, + scope, + tokenURL, + userInfoURL, + callbackURL: callbackUrl, + clientID: configurationService.get('OIDC_CLIENT_ID'), + clientSecret: configurationService.get('OIDC_CLIENT_SECRET') + }; + + return new OidcStrategy(authService, options); + } + }, WebAuthService ] }) diff --git a/apps/api/src/app/auth/auth.service.ts b/apps/api/src/app/auth/auth.service.ts index a6ee5d260..6fe50dce0 100644 --- a/apps/api/src/app/auth/auth.service.ts +++ b/apps/api/src/app/auth/auth.service.ts @@ -17,30 +17,22 @@ export class AuthService { ) {} public async validateAnonymousLogin(accessToken: string): Promise { - return new Promise(async (resolve, reject) => { - try { - const hashedAccessToken = this.userService.createAccessToken({ - password: accessToken, - salt: this.configurationService.get('ACCESS_TOKEN_SALT') - }); + const hashedAccessToken = this.userService.createAccessToken({ + password: accessToken, + salt: this.configurationService.get('ACCESS_TOKEN_SALT') + }); - const [user] = await this.userService.users({ - where: { accessToken: hashedAccessToken } - }); + const [user] = await this.userService.users({ + where: { accessToken: hashedAccessToken } + }); - if (user) { - const jwt = this.jwtService.sign({ - id: user.id - }); + if (user) { + return this.jwtService.sign({ + id: user.id + }); + } - resolve(jwt); - } else { - throw new Error(); - } - } catch { - reject(); - } - }); + throw new Error(); } public async validateOAuthLogin({ @@ -75,7 +67,7 @@ export class AuthService { } catch (error) { throw new InternalServerErrorException( 'validateOAuthLogin', - error.message + error instanceof Error ? error.message : 'Unknown error' ); } } diff --git a/apps/api/src/app/auth/interfaces/interfaces.ts b/apps/api/src/app/auth/interfaces/interfaces.ts index 4fdcc25b5..7ddfe41d2 100644 --- a/apps/api/src/app/auth/interfaces/interfaces.ts +++ b/apps/api/src/app/auth/interfaces/interfaces.ts @@ -6,6 +6,25 @@ export interface AuthDeviceDialogParams { authDevice: AuthDeviceDto; } +export interface OidcContext { + claims?: { + sub?: string; + }; +} + +export interface OidcIdToken { + sub?: string; +} + +export interface OidcParams { + sub?: string; +} + +export interface OidcProfile { + id?: string; + sub?: string; +} + export interface ValidateOAuthLoginParams { provider: Provider; thirdPartyId: string; diff --git a/apps/api/src/app/auth/oidc-state.store.ts b/apps/api/src/app/auth/oidc-state.store.ts new file mode 100644 index 000000000..653451166 --- /dev/null +++ b/apps/api/src/app/auth/oidc-state.store.ts @@ -0,0 +1,114 @@ +import ms from 'ms'; + +/** + * Custom state store for OIDC authentication that doesn't rely on express-session. + * This store manages OAuth2 state parameters in memory with automatic cleanup. + */ +export class OidcStateStore { + private readonly STATE_EXPIRY_MS = ms('10 minutes'); + + private stateMap = new Map< + string, + { + appState?: unknown; + ctx: { issued?: Date; maxAge?: number; nonce?: string }; + meta?: unknown; + timestamp: number; + } + >(); + + /** + * Store request state. + * Signature matches passport-openidconnect SessionStore + */ + public store( + _req: unknown, + _meta: unknown, + appState: unknown, + ctx: { maxAge?: number; nonce?: string; issued?: Date }, + callback: (err: Error | null, handle?: string) => void + ) { + try { + // Generate a unique handle for this state + const handle = this.generateHandle(); + + this.stateMap.set(handle, { + appState, + ctx, + meta: _meta, + timestamp: Date.now() + }); + + // Clean up expired states + this.cleanup(); + + callback(null, handle); + } catch (error) { + callback(error as Error); + } + } + + /** + * Verify request state. + * Signature matches passport-openidconnect SessionStore + */ + public verify( + _req: unknown, + handle: string, + callback: ( + err: Error | null, + appState?: unknown, + ctx?: { maxAge?: number; nonce?: string; issued?: Date } + ) => void + ) { + try { + const data = this.stateMap.get(handle); + + if (!data) { + return callback(null, undefined, undefined); + } + + if (Date.now() - data.timestamp > this.STATE_EXPIRY_MS) { + // State has expired + this.stateMap.delete(handle); + return callback(null, undefined, undefined); + } + + // Remove state after verification (one-time use) + this.stateMap.delete(handle); + + callback(null, data.ctx, data.appState); + } catch (error) { + callback(error as Error); + } + } + + /** + * Clean up expired states + */ + private cleanup() { + const now = Date.now(); + const expiredKeys: string[] = []; + + for (const [key, value] of this.stateMap.entries()) { + if (now - value.timestamp > this.STATE_EXPIRY_MS) { + expiredKeys.push(key); + } + } + + for (const key of expiredKeys) { + this.stateMap.delete(key); + } + } + + /** + * Generate a cryptographically secure random handle + */ + private generateHandle() { + return ( + Math.random().toString(36).substring(2, 15) + + Math.random().toString(36).substring(2, 15) + + Date.now().toString(36) + ); + } +} diff --git a/apps/api/src/app/auth/oidc.strategy.ts b/apps/api/src/app/auth/oidc.strategy.ts new file mode 100644 index 000000000..96b284121 --- /dev/null +++ b/apps/api/src/app/auth/oidc.strategy.ts @@ -0,0 +1,69 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { PassportStrategy } from '@nestjs/passport'; +import { Provider } from '@prisma/client'; +import { Request } from 'express'; +import { Strategy, type StrategyOptions } from 'passport-openidconnect'; + +import { AuthService } from './auth.service'; +import { + OidcContext, + OidcIdToken, + OidcParams, + OidcProfile +} from './interfaces/interfaces'; +import { OidcStateStore } from './oidc-state.store'; + +@Injectable() +export class OidcStrategy extends PassportStrategy(Strategy, 'oidc') { + private static readonly stateStore = new OidcStateStore(); + + public constructor( + private readonly authService: AuthService, + options: StrategyOptions + ) { + super({ + ...options, + passReqToCallback: true, + store: OidcStrategy.stateStore + }); + } + + public async validate( + _request: Request, + issuer: string, + profile: OidcProfile, + context: OidcContext, + idToken: OidcIdToken, + _accessToken: string, + _refreshToken: string, + params: OidcParams + ) { + try { + const thirdPartyId = + profile?.id ?? + profile?.sub ?? + idToken?.sub ?? + params?.sub ?? + context?.claims?.sub; + + const jwt = await this.authService.validateOAuthLogin({ + thirdPartyId, + provider: Provider.OIDC + }); + + if (!thirdPartyId) { + Logger.error( + `Missing subject identifier in OIDC response from ${issuer}`, + 'OidcStrategy' + ); + + throw new Error('Missing subject identifier in OIDC response'); + } + + return { jwt }; + } catch (error) { + Logger.error(error, 'OidcStrategy'); + throw error; + } + } +} diff --git a/apps/api/src/app/info/info.service.ts b/apps/api/src/app/info/info.service.ts index 634fc959c..3802e3ef4 100644 --- a/apps/api/src/app/info/info.service.ts +++ b/apps/api/src/app/info/info.service.ts @@ -55,6 +55,10 @@ export class InfoService { globalPermissions.push(permissions.enableAuthGoogle); } + if (this.configurationService.get('ENABLE_FEATURE_AUTH_OIDC')) { + globalPermissions.push(permissions.enableAuthOidc); + } + if (this.configurationService.get('ENABLE_FEATURE_AUTH_TOKEN')) { globalPermissions.push(permissions.enableAuthToken); } diff --git a/apps/api/src/services/configuration/configuration.service.ts b/apps/api/src/services/configuration/configuration.service.ts index f37189569..a91aa6e69 100644 --- a/apps/api/src/services/configuration/configuration.service.ts +++ b/apps/api/src/services/configuration/configuration.service.ts @@ -41,6 +41,7 @@ export class ConfigurationService { default: [] }), ENABLE_FEATURE_AUTH_GOOGLE: bool({ default: false }), + ENABLE_FEATURE_AUTH_OIDC: bool({ default: false }), ENABLE_FEATURE_AUTH_TOKEN: bool({ default: true }), ENABLE_FEATURE_FEAR_AND_GREED_INDEX: bool({ default: false }), ENABLE_FEATURE_GATHER_NEW_EXCHANGE_RATES: bool({ default: true }), @@ -54,9 +55,32 @@ export class ConfigurationService { GOOGLE_SHEETS_ID: str({ default: '' }), GOOGLE_SHEETS_PRIVATE_KEY: str({ default: '' }), HOST: host({ default: DEFAULT_HOST }), - JWT_SECRET_KEY: str({}), + JWT_SECRET_KEY: str(), MAX_ACTIVITIES_TO_IMPORT: num({ default: Number.MAX_SAFE_INTEGER }), MAX_CHART_ITEMS: num({ default: 365 }), + OIDC_AUTHORIZATION_URL: str({ default: '' }), + OIDC_CALLBACK_URL: str({ default: '' }), + OIDC_CLIENT_ID: str({ + default: undefined, + requiredWhen: (env) => { + return env.ENABLE_FEATURE_AUTH_OIDC === true; + } + }), + OIDC_CLIENT_SECRET: str({ + default: undefined, + requiredWhen: (env) => { + return env.ENABLE_FEATURE_AUTH_OIDC === true; + } + }), + OIDC_ISSUER: str({ + default: undefined, + requiredWhen: (env) => { + return env.ENABLE_FEATURE_AUTH_OIDC === true; + } + }), + OIDC_SCOPE: json({ default: ['openid'] }), + OIDC_TOKEN_URL: str({ default: '' }), + OIDC_USER_INFO_URL: str({ default: '' }), PORT: port({ default: DEFAULT_PORT }), PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY: num({ default: DEFAULT_PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY diff --git a/apps/api/src/services/interfaces/environment.interface.ts b/apps/api/src/services/interfaces/environment.interface.ts index 3a2ac687c..3c03744f1 100644 --- a/apps/api/src/services/interfaces/environment.interface.ts +++ b/apps/api/src/services/interfaces/environment.interface.ts @@ -17,6 +17,7 @@ export interface Environment extends CleanedEnvAccessors { DATA_SOURCES: string[]; DATA_SOURCES_GHOSTFOLIO_DATA_PROVIDER: string[]; ENABLE_FEATURE_AUTH_GOOGLE: boolean; + ENABLE_FEATURE_AUTH_OIDC: boolean; ENABLE_FEATURE_AUTH_TOKEN: boolean; ENABLE_FEATURE_FEAR_AND_GREED_INDEX: boolean; ENABLE_FEATURE_GATHER_NEW_EXCHANGE_RATES: boolean; @@ -32,6 +33,14 @@ export interface Environment extends CleanedEnvAccessors { JWT_SECRET_KEY: string; MAX_ACTIVITIES_TO_IMPORT: number; MAX_CHART_ITEMS: number; + OIDC_AUTHORIZATION_URL: string; + OIDC_CALLBACK_URL: string; + OIDC_CLIENT_ID: string; + OIDC_CLIENT_SECRET: string; + OIDC_ISSUER: string; + OIDC_SCOPE: string[]; + OIDC_TOKEN_URL: string; + OIDC_USER_INFO_URL: string; PORT: number; PROCESSOR_GATHER_ASSET_PROFILE_CONCURRENCY: number; PROCESSOR_GATHER_HISTORICAL_MARKET_DATA_CONCURRENCY: number; diff --git a/apps/client/src/app/app.component.ts b/apps/client/src/app/app.component.ts index de82c7d9c..12a7b0de9 100644 --- a/apps/client/src/app/app.component.ts +++ b/apps/client/src/app/app.component.ts @@ -3,6 +3,7 @@ import { InfoItem, User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { internalRoutes, publicRoutes } from '@ghostfolio/common/routes/routes'; import { ColorScheme } from '@ghostfolio/common/types'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { ChangeDetectionStrategy, @@ -35,7 +36,6 @@ import { GfFooterComponent } from './components/footer/footer.component'; import { GfHeaderComponent } from './components/header/header.component'; import { GfHoldingDetailDialogComponent } from './components/holding-detail-dialog/holding-detail-dialog.component'; import { HoldingDetailDialogParams } from './components/holding-detail-dialog/interfaces/interfaces'; -import { NotificationService } from './core/notification/notification.service'; import { DataService } from './services/data.service'; import { ImpersonationStorageService } from './services/impersonation-storage.service'; import { TokenStorageService } from './services/token-storage.service'; diff --git a/apps/client/src/app/components/access-table/access-table.component.ts b/apps/client/src/app/components/access-table/access-table.component.ts index 1127e5629..fe2c81199 100644 --- a/apps/client/src/app/components/access-table/access-table.component.ts +++ b/apps/client/src/app/components/access-table/access-table.component.ts @@ -1,7 +1,7 @@ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { ConfirmationDialogType } from '@ghostfolio/common/enums'; import { Access, User } from '@ghostfolio/common/interfaces'; import { publicRoutes } from '@ghostfolio/common/routes/routes'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { Clipboard, ClipboardModule } from '@angular/cdk/clipboard'; import { CommonModule } from '@angular/common'; diff --git a/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts b/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts index 8ed72445f..66bac76f5 100644 --- a/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts +++ b/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts @@ -1,4 +1,3 @@ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { AdminService } from '@ghostfolio/client/services/admin.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { @@ -9,6 +8,7 @@ import { } from '@ghostfolio/common/config'; import { getDateWithTimeFormatString } from '@ghostfolio/common/helper'; import { AdminJobs, User } from '@ghostfolio/common/interfaces'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { CommonModule } from '@angular/common'; import { diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.service.ts b/apps/client/src/app/components/admin-market-data/admin-market-data.service.ts index 3f60cb8c5..eaad32c0e 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.service.ts +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.service.ts @@ -1,4 +1,3 @@ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { AdminService } from '@ghostfolio/client/services/admin.service'; import { ghostfolioScraperApiSymbolPrefix } from '@ghostfolio/common/config'; import { ConfirmationDialogType } from '@ghostfolio/common/enums'; @@ -11,6 +10,7 @@ import { AssetProfileIdentifier, AdminMarketDataItem } from '@ghostfolio/common/interfaces'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { Injectable } from '@angular/core'; import { EMPTY, catchError, finalize, forkJoin } from 'rxjs'; diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts index b2ef4f17b..3fe944a25 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts @@ -1,5 +1,4 @@ import { AdminMarketDataService } from '@ghostfolio/client/components/admin-market-data/admin-market-data.service'; -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { AdminService } from '@ghostfolio/client/services/admin.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; @@ -24,6 +23,7 @@ import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo'; import { GfHistoricalMarketDataEditorComponent } from '@ghostfolio/ui/historical-market-data-editor'; import { translate } from '@ghostfolio/ui/i18n'; import { GfLineChartComponent } from '@ghostfolio/ui/line-chart'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { GfPortfolioProportionChartComponent } from '@ghostfolio/ui/portfolio-proportion-chart'; import { GfSymbolAutocompleteComponent } from '@ghostfolio/ui/symbol-autocomplete'; import { GfValueComponent } from '@ghostfolio/ui/value'; diff --git a/apps/client/src/app/components/admin-overview/admin-overview.component.ts b/apps/client/src/app/components/admin-overview/admin-overview.component.ts index 0b4b36d06..e4be7b062 100644 --- a/apps/client/src/app/components/admin-overview/admin-overview.component.ts +++ b/apps/client/src/app/components/admin-overview/admin-overview.component.ts @@ -1,4 +1,3 @@ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { AdminService } from '@ghostfolio/client/services/admin.service'; import { CacheService } from '@ghostfolio/client/services/cache.service'; import { DataService } from '@ghostfolio/client/services/data.service'; @@ -20,6 +19,7 @@ import { User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; diff --git a/apps/client/src/app/components/admin-platform/admin-platform.component.ts b/apps/client/src/app/components/admin-platform/admin-platform.component.ts index 64e7ff7cf..832a70503 100644 --- a/apps/client/src/app/components/admin-platform/admin-platform.component.ts +++ b/apps/client/src/app/components/admin-platform/admin-platform.component.ts @@ -1,10 +1,10 @@ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { AdminService } from '@ghostfolio/client/services/admin.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { CreatePlatformDto, UpdatePlatformDto } from '@ghostfolio/common/dtos'; import { ConfirmationDialogType } from '@ghostfolio/common/enums'; import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { ChangeDetectionStrategy, diff --git a/apps/client/src/app/components/admin-settings/admin-settings.component.ts b/apps/client/src/app/components/admin-settings/admin-settings.component.ts index ec44b6e65..cabf4e589 100644 --- a/apps/client/src/app/components/admin-settings/admin-settings.component.ts +++ b/apps/client/src/app/components/admin-settings/admin-settings.component.ts @@ -1,7 +1,6 @@ import { GfAdminPlatformComponent } from '@ghostfolio/client/components/admin-platform/admin-platform.component'; import { GfAdminTagComponent } from '@ghostfolio/client/components/admin-tag/admin-tag.component'; import { GfDataProviderStatusComponent } from '@ghostfolio/client/components/data-provider-status/data-provider-status.component'; -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { AdminService } from '@ghostfolio/client/services/admin.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; @@ -15,6 +14,7 @@ import { } from '@ghostfolio/common/interfaces'; import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { GfValueComponent } from '@ghostfolio/ui/value'; diff --git a/apps/client/src/app/components/admin-tag/admin-tag.component.ts b/apps/client/src/app/components/admin-tag/admin-tag.component.ts index a891baa45..305eb4628 100644 --- a/apps/client/src/app/components/admin-tag/admin-tag.component.ts +++ b/apps/client/src/app/components/admin-tag/admin-tag.component.ts @@ -1,8 +1,8 @@ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { CreateTagDto, UpdateTagDto } from '@ghostfolio/common/dtos'; import { ConfirmationDialogType } from '@ghostfolio/common/enums'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { ChangeDetectionStrategy, diff --git a/apps/client/src/app/components/admin-users/admin-users.component.ts b/apps/client/src/app/components/admin-users/admin-users.component.ts index 6c366a16c..99fbe7901 100644 --- a/apps/client/src/app/components/admin-users/admin-users.component.ts +++ b/apps/client/src/app/components/admin-users/admin-users.component.ts @@ -1,6 +1,5 @@ import { UserDetailDialogParams } from '@ghostfolio/client/components/user-detail-dialog/interfaces/interfaces'; import { GfUserDetailDialogComponent } from '@ghostfolio/client/components/user-detail-dialog/user-detail-dialog.component'; -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { AdminService } from '@ghostfolio/client/services/admin.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; @@ -19,6 +18,7 @@ import { User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { GfValueComponent } from '@ghostfolio/ui/value'; diff --git a/apps/client/src/app/components/header/header.component.ts b/apps/client/src/app/components/header/header.component.ts index 9fb9a8351..b7bf4cb98 100644 --- a/apps/client/src/app/components/header/header.component.ts +++ b/apps/client/src/app/components/header/header.component.ts @@ -1,7 +1,6 @@ import { LoginWithAccessTokenDialogParams } from '@ghostfolio/client/components/login-with-access-token-dialog/interfaces/interfaces'; import { GfLoginWithAccessTokenDialogComponent } from '@ghostfolio/client/components/login-with-access-token-dialog/login-with-access-token-dialog.component'; import { LayoutService } from '@ghostfolio/client/core/layout.service'; -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; import { @@ -17,6 +16,7 @@ import { internalRoutes, publicRoutes } from '@ghostfolio/common/routes/routes'; import { DateRange } from '@ghostfolio/common/types'; import { GfAssistantComponent } from '@ghostfolio/ui/assistant/assistant.component'; import { GfLogoComponent } from '@ghostfolio/ui/logo'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { CommonModule } from '@angular/common'; @@ -105,6 +105,7 @@ export class GfHeaderComponent implements OnChanges { public hasFilters: boolean; public hasImpersonationId: boolean; public hasPermissionForAuthGoogle: boolean; + public hasPermissionForAuthOidc: boolean; public hasPermissionForAuthToken: boolean; public hasPermissionForSubscription: boolean; public hasPermissionToAccessAdminControl: boolean; @@ -170,6 +171,11 @@ export class GfHeaderComponent implements OnChanges { permissions.enableAuthGoogle ); + this.hasPermissionForAuthOidc = hasPermission( + this.info?.globalPermissions, + permissions.enableAuthOidc + ); + this.hasPermissionForAuthToken = hasPermission( this.info?.globalPermissions, permissions.enableAuthToken @@ -286,6 +292,7 @@ export class GfHeaderComponent implements OnChanges { data: { accessToken: '', hasPermissionToUseAuthGoogle: this.hasPermissionForAuthGoogle, + hasPermissionToUseAuthOidc: this.hasPermissionForAuthOidc, hasPermissionToUseAuthToken: this.hasPermissionForAuthToken, title: $localize`Sign in` }, diff --git a/apps/client/src/app/components/login-with-access-token-dialog/interfaces/interfaces.ts b/apps/client/src/app/components/login-with-access-token-dialog/interfaces/interfaces.ts index c7c4ab3fd..e9222e142 100644 --- a/apps/client/src/app/components/login-with-access-token-dialog/interfaces/interfaces.ts +++ b/apps/client/src/app/components/login-with-access-token-dialog/interfaces/interfaces.ts @@ -1,6 +1,7 @@ export interface LoginWithAccessTokenDialogParams { accessToken: string; hasPermissionToUseAuthGoogle: boolean; + hasPermissionToUseAuthOidc: boolean; hasPermissionToUseAuthToken: boolean; title: string; } diff --git a/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html b/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html index bc232cfb7..78604456b 100644 --- a/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html +++ b/apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html @@ -45,6 +45,17 @@ > } + + @if (data.hasPermissionToUseAuthOidc) { +
+ Sign in with OpenID Connect +
+ } diff --git a/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts b/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts index c98a26831..04c0f507c 100644 --- a/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts +++ b/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts @@ -1,4 +1,3 @@ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { getLocale, getNumberFormatDecimal, @@ -8,6 +7,7 @@ import { PortfolioPerformance, ResponseError } from '@ghostfolio/common/interfaces'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; diff --git a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts index 7eab9172e..9e9bb13d3 100644 --- a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts +++ b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts @@ -1,8 +1,8 @@ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { NUMERICAL_PRECISION_THRESHOLD_6_FIGURES } from '@ghostfolio/common/config'; import { getDateFnsLocale, getLocale } from '@ghostfolio/common/helper'; import { PortfolioSummary, User } from '@ghostfolio/common/interfaces'; import { translate } from '@ghostfolio/ui/i18n'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; diff --git a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts index 9aa07feee..05c047dc6 100644 --- a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts +++ b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts @@ -1,7 +1,7 @@ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { CreateAccessDto, UpdateAccessDto } from '@ghostfolio/common/dtos'; import { validateObjectForForm } from '@ghostfolio/common/utils'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { ChangeDetectionStrategy, diff --git a/apps/client/src/app/components/user-account-access/user-account-access.component.ts b/apps/client/src/app/components/user-account-access/user-account-access.component.ts index da2e8f508..11960b8aa 100644 --- a/apps/client/src/app/components/user-account-access/user-account-access.component.ts +++ b/apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -1,5 +1,4 @@ import { GfAccessTableComponent } from '@ghostfolio/client/components/access-table/access-table.component'; -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; @@ -7,6 +6,7 @@ import { CreateAccessDto } from '@ghostfolio/common/dtos'; import { ConfirmationDialogType } from '@ghostfolio/common/enums'; import { Access, User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { diff --git a/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts b/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts index ae9183c13..069ea4b0e 100644 --- a/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts +++ b/apps/client/src/app/components/user-account-membership/user-account-membership.component.ts @@ -1,4 +1,3 @@ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { ConfirmationDialogType } from '@ghostfolio/common/enums'; @@ -7,6 +6,7 @@ import { User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { GfMembershipCardComponent } from '@ghostfolio/ui/membership-card'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { CommonModule } from '@angular/common'; diff --git a/apps/client/src/app/components/user-account-membership/user-account-membership.html b/apps/client/src/app/components/user-account-membership/user-account-membership.html index 351d5608a..31d239215 100644 --- a/apps/client/src/app/components/user-account-membership/user-account-membership.html +++ b/apps/client/src/app/components/user-account-membership/user-account-membership.html @@ -5,6 +5,7 @@ diff --git a/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts b/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts index 32e3d132e..e17425676 100644 --- a/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts +++ b/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts @@ -1,4 +1,3 @@ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { KEY_STAY_SIGNED_IN, @@ -12,6 +11,7 @@ import { ConfirmationDialogType } from '@ghostfolio/common/enums'; import { downloadAsFile } from '@ghostfolio/common/helper'; import { User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { ChangeDetectionStrategy, diff --git a/apps/client/src/app/core/layout.service.ts b/apps/client/src/app/core/layout.service.ts index a6fb65006..fd435acdb 100644 --- a/apps/client/src/app/core/layout.service.ts +++ b/apps/client/src/app/core/layout.service.ts @@ -1,9 +1,9 @@ +import { NotificationService } from '@ghostfolio/ui/notifications'; + import { Injectable } from '@angular/core'; import { DeviceDetectorService } from 'ngx-device-detector'; import { Observable, Subject } from 'rxjs'; -import { NotificationService } from './notification/notification.service'; - @Injectable({ providedIn: 'root' }) diff --git a/apps/client/src/app/pages/accounts/accounts-page.component.ts b/apps/client/src/app/pages/accounts/accounts-page.component.ts index 2bb6457a5..2b496e4fb 100644 --- a/apps/client/src/app/pages/accounts/accounts-page.component.ts +++ b/apps/client/src/app/pages/accounts/accounts-page.component.ts @@ -1,6 +1,5 @@ import { GfAccountDetailDialogComponent } from '@ghostfolio/client/components/account-detail-dialog/account-detail-dialog.component'; import { AccountDetailDialogParams } from '@ghostfolio/client/components/account-detail-dialog/interfaces/interfaces'; -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; @@ -12,6 +11,7 @@ import { import { User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { GfAccountsTableComponent } from '@ghostfolio/ui/accounts-table'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; diff --git a/apps/client/src/app/pages/demo/demo-page.component.ts b/apps/client/src/app/pages/demo/demo-page.component.ts index 720bb4974..9eba64788 100644 --- a/apps/client/src/app/pages/demo/demo-page.component.ts +++ b/apps/client/src/app/pages/demo/demo-page.component.ts @@ -1,7 +1,7 @@ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service'; import { InfoItem } from '@ghostfolio/common/interfaces'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { Component, OnDestroy } from '@angular/core'; import { Router } from '@angular/router'; diff --git a/apps/client/src/app/pages/pricing/pricing-page.component.ts b/apps/client/src/app/pages/pricing/pricing-page.component.ts index 88958ea0d..6ed8dfd31 100644 --- a/apps/client/src/app/pages/pricing/pricing-page.component.ts +++ b/apps/client/src/app/pages/pricing/pricing-page.component.ts @@ -1,10 +1,10 @@ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { publicRoutes } from '@ghostfolio/common/routes/routes'; import { translate } from '@ghostfolio/ui/i18n'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { CommonModule } from '@angular/common'; diff --git a/apps/client/src/assets/oss-friends.json b/apps/client/src/assets/oss-friends.json index 8a64650fe..2d5b994d3 100644 --- a/apps/client/src/assets/oss-friends.json +++ b/apps/client/src/assets/oss-friends.json @@ -1,5 +1,5 @@ { - "createdAt": "2025-11-21T00:00:00.000Z", + "createdAt": "2025-12-08T00:00:00.000Z", "data": [ { "name": "Activepieces", @@ -76,6 +76,11 @@ "description": "Mockoon is the easiest and quickest way to design and run mock REST APIs.", "href": "https://mockoon.com" }, + { + "name": "Onyx", + "description": "Onyx is the open-source AI chat connected to your docs, apps, and people.", + "href": "https://onyx.app" + }, { "name": "OpenBB", "description": "Democratizing investment research through an open source financial ecosystem. The OpenBB Terminal allows everyone to perform investment research, from everywhere.", diff --git a/apps/client/src/locales/messages.ca.xlf b/apps/client/src/locales/messages.ca.xlf index e2740945e..2944e43fb 100644 --- a/apps/client/src/locales/messages.ca.xlf +++ b/apps/client/src/locales/messages.ca.xlf @@ -38,11 +38,11 @@ apps/client/src/app/components/header/header.component.ts - 290 + 297 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 68 + 79 libs/common/src/lib/routes/routes.ts @@ -607,7 +607,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 453 + 457 @@ -643,7 +643,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 480 + 484 libs/ui/src/lib/benchmark/benchmark.component.html @@ -795,7 +795,7 @@ Veure Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 215 + 216 @@ -803,7 +803,7 @@ Executar Procés apps/client/src/app/components/admin-jobs/admin-jobs.html - 218 + 220 @@ -811,7 +811,7 @@ Suprimir Procés apps/client/src/app/components/admin-jobs/admin-jobs.html - 222 + 224 @@ -1503,7 +1503,7 @@ No auto-renewal on membership. apps/client/src/app/components/user-account-membership/user-account-membership.html - 73 + 74 @@ -1531,7 +1531,7 @@ Actuar com un altre Usuari apps/client/src/app/components/admin-users/admin-users.html - 232 + 234 @@ -1539,7 +1539,7 @@ Eliminar Usuari apps/client/src/app/components/admin-users/admin-users.html - 253 + 255 @@ -1623,7 +1623,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 20 + 21 apps/client/src/app/pages/pricing/pricing-page.html @@ -1639,7 +1639,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 18 + 19 apps/client/src/app/pages/pricing/pricing-page.html @@ -1671,7 +1671,7 @@ Oooh! El testimoni de seguretat és incorrecte. apps/client/src/app/components/header/header.component.ts - 305 + 312 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -2043,7 +2043,7 @@ Manteniu la sessió iniciada apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 55 + 66 @@ -2471,7 +2471,7 @@ per any apps/client/src/app/components/user-account-membership/user-account-membership.html - 32 + 33 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -2487,7 +2487,7 @@ Prova Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 52 + 53 @@ -2495,7 +2495,7 @@ Bescanviar el cupó apps/client/src/app/components/user-account-membership/user-account-membership.html - 66 + 67 @@ -4076,7 +4076,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 382 + 383 @@ -4092,7 +4092,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 394 + 397 @@ -5229,7 +5229,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 37 + 40 @@ -5301,7 +5301,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 407 + 411 @@ -5313,7 +5313,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 420 + 424 @@ -5337,7 +5337,7 @@ Clonar libs/ui/src/lib/activities-table/activities-table.component.html - 459 + 463 @@ -5345,7 +5345,7 @@ Exporta l’esborrany com a ICS libs/ui/src/lib/activities-table/activities-table.component.html - 469 + 473 @@ -5929,7 +5929,7 @@ View Details apps/client/src/app/components/admin-users/admin-users.html - 225 + 226 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -5944,6 +5944,14 @@ 33 + + Sign in with OpenID Connect + Sign in with OpenID Connect + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 55 + + Buy Comprar @@ -6061,7 +6069,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 32 + 35 @@ -6209,7 +6217,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 42 + 45 @@ -6461,7 +6469,7 @@ View Holding libs/ui/src/lib/activities-table/activities-table.component.html - 446 + 450 @@ -6729,7 +6737,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 36 + 14 @@ -7167,7 +7175,7 @@ API Key libs/ui/src/lib/membership-card/membership-card.component.html - 18 + 21 @@ -7175,7 +7183,7 @@ Generate Ghostfolio Premium Data Provider API key for self-hosted environments... libs/ui/src/lib/membership-card/membership-card.component.html - 26 + 29 @@ -7531,7 +7539,7 @@ Generate Security Token apps/client/src/app/components/admin-users/admin-users.html - 242 + 244 @@ -7907,7 +7915,7 @@ Limited Offer! apps/client/src/app/components/user-account-membership/user-account-membership.html - 40 + 41 apps/client/src/app/pages/pricing/pricing-page.html @@ -7919,7 +7927,7 @@ Get extra apps/client/src/app/components/user-account-membership/user-account-membership.html - 43 + 44 apps/client/src/app/pages/pricing/pricing-page.html @@ -8592,7 +8600,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 20 + 26 diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index 65e71fbd8..02ef33acd 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -254,7 +254,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 453 + 457 @@ -290,7 +290,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 480 + 484 libs/ui/src/lib/benchmark/benchmark.component.html @@ -418,7 +418,7 @@ Stacktrace anzeigen apps/client/src/app/components/admin-jobs/admin-jobs.html - 215 + 216 @@ -426,7 +426,7 @@ Job löschen apps/client/src/app/components/admin-jobs/admin-jobs.html - 222 + 224 @@ -674,7 +674,7 @@ Keine automatische Erneuerung der Mitgliedschaft. apps/client/src/app/components/user-account-membership/user-account-membership.html - 73 + 74 @@ -758,11 +758,11 @@ apps/client/src/app/components/header/header.component.ts - 290 + 297 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 68 + 79 libs/common/src/lib/routes/routes.ts @@ -778,7 +778,7 @@ Ups! Falsches Sicherheits-Token. apps/client/src/app/components/header/header.component.ts - 305 + 312 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -890,7 +890,7 @@ Eingeloggt bleiben apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 55 + 66 @@ -1226,7 +1226,7 @@ pro Jahr apps/client/src/app/components/user-account-membership/user-account-membership.html - 32 + 33 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -1242,7 +1242,7 @@ Premium ausprobieren apps/client/src/app/components/user-account-membership/user-account-membership.html - 52 + 53 @@ -1250,7 +1250,7 @@ Gutschein einlösen apps/client/src/app/components/user-account-membership/user-account-membership.html - 66 + 67 @@ -2254,7 +2254,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 382 + 383 @@ -2266,7 +2266,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 407 + 411 @@ -2278,7 +2278,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 420 + 424 @@ -2286,7 +2286,7 @@ Kopieren libs/ui/src/lib/activities-table/activities-table.component.html - 459 + 463 @@ -2294,7 +2294,7 @@ Geplante Aktivität als ICS exportieren libs/ui/src/lib/activities-table/activities-table.component.html - 469 + 473 @@ -2870,7 +2870,7 @@ Authentifizierung apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 32 + 35 @@ -3266,7 +3266,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 394 + 397 @@ -3278,7 +3278,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 42 + 45 @@ -3466,7 +3466,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 20 + 21 apps/client/src/app/pages/pricing/pricing-page.html @@ -3726,7 +3726,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 18 + 19 apps/client/src/app/pages/pricing/pricing-page.html @@ -3746,7 +3746,7 @@ Benutzer verwenden apps/client/src/app/components/admin-users/admin-users.html - 232 + 234 @@ -3754,7 +3754,7 @@ Benutzer löschen apps/client/src/app/components/admin-users/admin-users.html - 253 + 255 @@ -4006,7 +4006,7 @@ Details anzeigen apps/client/src/app/components/admin-users/admin-users.html - 225 + 226 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -4385,6 +4385,14 @@ 73 + + Sign in with OpenID Connect + Einloggen mit OpenID Connect + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 55 + + Buy Kauf @@ -5468,7 +5476,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 37 + 40 @@ -6093,7 +6101,7 @@ Job ausführen apps/client/src/app/components/admin-jobs/admin-jobs.html - 218 + 220 @@ -6485,7 +6493,7 @@ Position ansehen libs/ui/src/lib/activities-table/activities-table.component.html - 446 + 450 @@ -6753,7 +6761,7 @@ Rolle apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 36 + 14 @@ -7191,7 +7199,7 @@ API-Schlüssel libs/ui/src/lib/membership-card/membership-card.component.html - 18 + 21 @@ -7199,7 +7207,7 @@ Ghostfolio Premium Datenanbieter API-Schlüssel für selbst gehostete Umgebungen erstellen... libs/ui/src/lib/membership-card/membership-card.component.html - 26 + 29 @@ -7555,7 +7563,7 @@ Sicherheits-Token generieren apps/client/src/app/components/admin-users/admin-users.html - 242 + 244 @@ -7907,7 +7915,7 @@ Begrenztes Angebot! apps/client/src/app/components/user-account-membership/user-account-membership.html - 40 + 41 apps/client/src/app/pages/pricing/pricing-page.html @@ -7919,7 +7927,7 @@ Erhalte extra apps/client/src/app/components/user-account-membership/user-account-membership.html - 43 + 44 apps/client/src/app/pages/pricing/pricing-page.html @@ -8592,7 +8600,7 @@ Registrierungsdatum apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 20 + 26 diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index 2703aebb8..4314903be 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -255,7 +255,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 453 + 457 @@ -291,7 +291,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 480 + 484 libs/ui/src/lib/benchmark/benchmark.component.html @@ -419,7 +419,7 @@ Visualiza Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 215 + 216 @@ -427,7 +427,7 @@ Elimina el trabajo apps/client/src/app/components/admin-jobs/admin-jobs.html - 222 + 224 @@ -659,7 +659,7 @@ No auto-renewal on membership. apps/client/src/app/components/user-account-membership/user-account-membership.html - 73 + 74 @@ -743,11 +743,11 @@ apps/client/src/app/components/header/header.component.ts - 290 + 297 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 68 + 79 libs/common/src/lib/routes/routes.ts @@ -763,7 +763,7 @@ Vaya! Token de seguridad incorrecto. apps/client/src/app/components/header/header.component.ts - 305 + 312 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -875,7 +875,7 @@ Seguir conectado apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 55 + 66 @@ -1211,7 +1211,7 @@ por año apps/client/src/app/components/user-account-membership/user-account-membership.html - 32 + 33 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -1227,7 +1227,7 @@ Prueba Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 52 + 53 @@ -1235,7 +1235,7 @@ Canjea el cupón apps/client/src/app/components/user-account-membership/user-account-membership.html - 66 + 67 @@ -2239,7 +2239,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 382 + 383 @@ -2251,7 +2251,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 407 + 411 @@ -2263,7 +2263,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 420 + 424 @@ -2271,7 +2271,7 @@ Clonar libs/ui/src/lib/activities-table/activities-table.component.html - 459 + 463 @@ -2279,7 +2279,7 @@ Exportar borrador como ICS libs/ui/src/lib/activities-table/activities-table.component.html - 469 + 473 @@ -2855,7 +2855,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 32 + 35 @@ -3251,7 +3251,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 394 + 397 @@ -3263,7 +3263,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 42 + 45 @@ -3451,7 +3451,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 20 + 21 apps/client/src/app/pages/pricing/pricing-page.html @@ -3703,7 +3703,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 18 + 19 apps/client/src/app/pages/pricing/pricing-page.html @@ -3723,7 +3723,7 @@ Suplantar usuario apps/client/src/app/components/admin-users/admin-users.html - 232 + 234 @@ -3731,7 +3731,7 @@ Eliminar usuario apps/client/src/app/components/admin-users/admin-users.html - 253 + 255 @@ -3983,7 +3983,7 @@ View Details apps/client/src/app/components/admin-users/admin-users.html - 225 + 226 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -4362,6 +4362,14 @@ 73 + + Sign in with OpenID Connect + Sign in with OpenID Connect + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 55 + + Buy Comprar @@ -5445,7 +5453,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 37 + 40 @@ -6070,7 +6078,7 @@ Ejecutar Tarea apps/client/src/app/components/admin-jobs/admin-jobs.html - 218 + 220 @@ -6462,7 +6470,7 @@ View Holding libs/ui/src/lib/activities-table/activities-table.component.html - 446 + 450 @@ -6730,7 +6738,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 36 + 14 @@ -7168,7 +7176,7 @@ Clave API libs/ui/src/lib/membership-card/membership-card.component.html - 18 + 21 @@ -7176,7 +7184,7 @@ Genere la clave API del proveedor de datos premium de Ghostfolio para entornos autohospedados... libs/ui/src/lib/membership-card/membership-card.component.html - 26 + 29 @@ -7532,7 +7540,7 @@ Generar token de seguridad apps/client/src/app/components/admin-users/admin-users.html - 242 + 244 @@ -7908,7 +7916,7 @@ ¡Oferta limitada! apps/client/src/app/components/user-account-membership/user-account-membership.html - 40 + 41 apps/client/src/app/pages/pricing/pricing-page.html @@ -7920,7 +7928,7 @@ Obtén extra apps/client/src/app/components/user-account-membership/user-account-membership.html - 43 + 44 apps/client/src/app/pages/pricing/pricing-page.html @@ -8593,7 +8601,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 20 + 26 diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index 81da3848d..41dc3d391 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -310,7 +310,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 453 + 457 @@ -346,7 +346,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 480 + 484 libs/ui/src/lib/benchmark/benchmark.component.html @@ -474,7 +474,7 @@ Voir la Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 215 + 216 @@ -482,7 +482,7 @@ Supprimer Tâche apps/client/src/app/components/admin-jobs/admin-jobs.html - 222 + 224 @@ -870,7 +870,7 @@ No auto-renewal on membership. apps/client/src/app/components/user-account-membership/user-account-membership.html - 73 + 74 @@ -966,11 +966,11 @@ apps/client/src/app/components/header/header.component.ts - 290 + 297 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 68 + 79 libs/common/src/lib/routes/routes.ts @@ -986,7 +986,7 @@ Oups! Jeton de Sécurité Incorrect. apps/client/src/app/components/header/header.component.ts - 305 + 312 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -1146,7 +1146,7 @@ Rester connecté apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 55 + 66 @@ -1494,7 +1494,7 @@ par an apps/client/src/app/components/user-account-membership/user-account-membership.html - 32 + 33 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -1510,7 +1510,7 @@ Essayer Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 52 + 53 @@ -1518,7 +1518,7 @@ Utiliser un Code Promotionnel apps/client/src/app/components/user-account-membership/user-account-membership.html - 66 + 67 @@ -2710,7 +2710,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 382 + 383 @@ -2722,7 +2722,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 407 + 411 @@ -2734,7 +2734,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 420 + 424 @@ -2742,7 +2742,7 @@ Dupliquer libs/ui/src/lib/activities-table/activities-table.component.html - 459 + 463 @@ -2750,7 +2750,7 @@ Exporter Brouillon sous ICS libs/ui/src/lib/activities-table/activities-table.component.html - 469 + 473 @@ -3058,7 +3058,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 32 + 35 @@ -3250,7 +3250,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 394 + 397 @@ -3262,7 +3262,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 42 + 45 @@ -3450,7 +3450,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 20 + 21 apps/client/src/app/pages/pricing/pricing-page.html @@ -3702,7 +3702,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 18 + 19 apps/client/src/app/pages/pricing/pricing-page.html @@ -3722,7 +3722,7 @@ Voir en tant que ... apps/client/src/app/components/admin-users/admin-users.html - 232 + 234 @@ -3730,7 +3730,7 @@ Supprimer l’Utilisateur apps/client/src/app/components/admin-users/admin-users.html - 253 + 255 @@ -3982,7 +3982,7 @@ View Details apps/client/src/app/components/admin-users/admin-users.html - 225 + 226 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -4361,6 +4361,14 @@ 73 + + Sign in with OpenID Connect + Sign in with OpenID Connect + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 55 + + Buy Achat @@ -5444,7 +5452,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 37 + 40 @@ -6069,7 +6077,7 @@ Execute la tâche apps/client/src/app/components/admin-jobs/admin-jobs.html - 218 + 220 @@ -6461,7 +6469,7 @@ View Holding libs/ui/src/lib/activities-table/activities-table.component.html - 446 + 450 @@ -6729,7 +6737,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 36 + 14 @@ -7167,7 +7175,7 @@ Clé API libs/ui/src/lib/membership-card/membership-card.component.html - 18 + 21 @@ -7175,7 +7183,7 @@ Générer la clé API du fournisseur de données Ghostfolio Premium pour les environnements auto-hébergés... libs/ui/src/lib/membership-card/membership-card.component.html - 26 + 29 @@ -7531,7 +7539,7 @@ Générer un jeton de sécurité apps/client/src/app/components/admin-users/admin-users.html - 242 + 244 @@ -7907,7 +7915,7 @@ Offre Limitée ! apps/client/src/app/components/user-account-membership/user-account-membership.html - 40 + 41 apps/client/src/app/pages/pricing/pricing-page.html @@ -7919,7 +7927,7 @@ Obtenez supplémentaires apps/client/src/app/components/user-account-membership/user-account-membership.html - 43 + 44 apps/client/src/app/pages/pricing/pricing-page.html @@ -8592,7 +8600,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 20 + 26 diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 6618d2463..e5bc9ccc6 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -255,7 +255,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 453 + 457 @@ -291,7 +291,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 480 + 484 libs/ui/src/lib/benchmark/benchmark.component.html @@ -419,7 +419,7 @@ Visualizza Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 215 + 216 @@ -427,7 +427,7 @@ Elimina il lavoro apps/client/src/app/components/admin-jobs/admin-jobs.html - 222 + 224 @@ -659,7 +659,7 @@ No auto-renewal on membership. apps/client/src/app/components/user-account-membership/user-account-membership.html - 73 + 74 @@ -743,11 +743,11 @@ apps/client/src/app/components/header/header.component.ts - 290 + 297 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 68 + 79 libs/common/src/lib/routes/routes.ts @@ -763,7 +763,7 @@ Ops! Token di sicurezza errato. apps/client/src/app/components/header/header.component.ts - 305 + 312 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -875,7 +875,7 @@ Rimani connesso apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 55 + 66 @@ -1211,7 +1211,7 @@ per anno apps/client/src/app/components/user-account-membership/user-account-membership.html - 32 + 33 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -1227,7 +1227,7 @@ Prova Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 52 + 53 @@ -1235,7 +1235,7 @@ Riscatta il buono apps/client/src/app/components/user-account-membership/user-account-membership.html - 66 + 67 @@ -2239,7 +2239,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 382 + 383 @@ -2251,7 +2251,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 407 + 411 @@ -2263,7 +2263,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 420 + 424 @@ -2271,7 +2271,7 @@ Clona libs/ui/src/lib/activities-table/activities-table.component.html - 459 + 463 @@ -2279,7 +2279,7 @@ Esporta la bozza come ICS libs/ui/src/lib/activities-table/activities-table.component.html - 469 + 473 @@ -2855,7 +2855,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 32 + 35 @@ -3251,7 +3251,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 394 + 397 @@ -3263,7 +3263,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 42 + 45 @@ -3451,7 +3451,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 20 + 21 apps/client/src/app/pages/pricing/pricing-page.html @@ -3703,7 +3703,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 18 + 19 apps/client/src/app/pages/pricing/pricing-page.html @@ -3723,7 +3723,7 @@ Imita l’utente apps/client/src/app/components/admin-users/admin-users.html - 232 + 234 @@ -3731,7 +3731,7 @@ Elimina l’utente apps/client/src/app/components/admin-users/admin-users.html - 253 + 255 @@ -3983,7 +3983,7 @@ View Details apps/client/src/app/components/admin-users/admin-users.html - 225 + 226 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -4362,6 +4362,14 @@ 73 + + Sign in with OpenID Connect + Sign in with OpenID Connect + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 55 + + Buy Compra @@ -5445,7 +5453,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 37 + 40 @@ -6070,7 +6078,7 @@ Esegui il lavoro apps/client/src/app/components/admin-jobs/admin-jobs.html - 218 + 220 @@ -6462,7 +6470,7 @@ View Holding libs/ui/src/lib/activities-table/activities-table.component.html - 446 + 450 @@ -6730,7 +6738,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 36 + 14 @@ -7168,7 +7176,7 @@ API Key libs/ui/src/lib/membership-card/membership-card.component.html - 18 + 21 @@ -7176,7 +7184,7 @@ Genera API key per Ghostfolio Premium Data Provider per ambienti self-hosted... libs/ui/src/lib/membership-card/membership-card.component.html - 26 + 29 @@ -7532,7 +7540,7 @@ Genera Token di Sicurezza apps/client/src/app/components/admin-users/admin-users.html - 242 + 244 @@ -7908,7 +7916,7 @@ Offerta limitata! apps/client/src/app/components/user-account-membership/user-account-membership.html - 40 + 41 apps/client/src/app/pages/pricing/pricing-page.html @@ -7920,7 +7928,7 @@ Get extra apps/client/src/app/components/user-account-membership/user-account-membership.html - 43 + 44 apps/client/src/app/pages/pricing/pricing-page.html @@ -8593,7 +8601,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 20 + 26 diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index 43f22714b..5d1bec1b5 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -254,7 +254,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 453 + 457 @@ -290,7 +290,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 480 + 484 libs/ui/src/lib/benchmark/benchmark.component.html @@ -418,7 +418,7 @@ Bekijk Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 215 + 216 @@ -426,7 +426,7 @@ Taak verwijderen apps/client/src/app/components/admin-jobs/admin-jobs.html - 222 + 224 @@ -658,7 +658,7 @@ No auto-renewal on membership. apps/client/src/app/components/user-account-membership/user-account-membership.html - 73 + 74 @@ -742,11 +742,11 @@ apps/client/src/app/components/header/header.component.ts - 290 + 297 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 68 + 79 libs/common/src/lib/routes/routes.ts @@ -762,7 +762,7 @@ Oeps! Onjuiste beveiligingstoken. apps/client/src/app/components/header/header.component.ts - 305 + 312 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -874,7 +874,7 @@ Aangemeld blijven apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 55 + 66 @@ -1210,7 +1210,7 @@ per jaar apps/client/src/app/components/user-account-membership/user-account-membership.html - 32 + 33 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -1226,7 +1226,7 @@ Probeer Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 52 + 53 @@ -1234,7 +1234,7 @@ Coupon inwisselen apps/client/src/app/components/user-account-membership/user-account-membership.html - 66 + 67 @@ -2238,7 +2238,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 382 + 383 @@ -2250,7 +2250,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 407 + 411 @@ -2262,7 +2262,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 420 + 424 @@ -2270,7 +2270,7 @@ Kloon libs/ui/src/lib/activities-table/activities-table.component.html - 459 + 463 @@ -2278,7 +2278,7 @@ Concept exporteren als ICS libs/ui/src/lib/activities-table/activities-table.component.html - 469 + 473 @@ -2854,7 +2854,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 32 + 35 @@ -3250,7 +3250,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 394 + 397 @@ -3262,7 +3262,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 42 + 45 @@ -3450,7 +3450,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 20 + 21 apps/client/src/app/pages/pricing/pricing-page.html @@ -3702,7 +3702,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 18 + 19 apps/client/src/app/pages/pricing/pricing-page.html @@ -3722,7 +3722,7 @@ Gebruiker immiteren apps/client/src/app/components/admin-users/admin-users.html - 232 + 234 @@ -3730,7 +3730,7 @@ Gebruiker verwijderen apps/client/src/app/components/admin-users/admin-users.html - 253 + 255 @@ -3982,7 +3982,7 @@ View Details apps/client/src/app/components/admin-users/admin-users.html - 225 + 226 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -4361,6 +4361,14 @@ 73 + + Sign in with OpenID Connect + Sign in with OpenID Connect + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 55 + + Buy Koop @@ -5444,7 +5452,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 37 + 40 @@ -6069,7 +6077,7 @@ Opdracht Uitvoeren apps/client/src/app/components/admin-jobs/admin-jobs.html - 218 + 220 @@ -6461,7 +6469,7 @@ View Holding libs/ui/src/lib/activities-table/activities-table.component.html - 446 + 450 @@ -6729,7 +6737,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 36 + 14 @@ -7167,7 +7175,7 @@ API-sleutel libs/ui/src/lib/membership-card/membership-card.component.html - 18 + 21 @@ -7175,7 +7183,7 @@ Genereer een Ghostfolio Premium Gegevensleverancier API-sleutel voor zelfgehoste omgevingen... libs/ui/src/lib/membership-card/membership-card.component.html - 26 + 29 @@ -7531,7 +7539,7 @@ Beveiligingstoken Aanmaken apps/client/src/app/components/admin-users/admin-users.html - 242 + 244 @@ -7907,7 +7915,7 @@ Beperkt aanbod! apps/client/src/app/components/user-account-membership/user-account-membership.html - 40 + 41 apps/client/src/app/pages/pricing/pricing-page.html @@ -7919,7 +7927,7 @@ Krijg extra apps/client/src/app/components/user-account-membership/user-account-membership.html - 43 + 44 apps/client/src/app/pages/pricing/pricing-page.html @@ -8592,7 +8600,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 20 + 26 diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index 1ae972c8e..6e167a355 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -531,7 +531,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 453 + 457 @@ -567,7 +567,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 480 + 484 libs/ui/src/lib/benchmark/benchmark.component.html @@ -691,7 +691,7 @@ Wyświetl Stos Wywołań apps/client/src/app/components/admin-jobs/admin-jobs.html - 215 + 216 @@ -699,7 +699,7 @@ Usuń Zadanie apps/client/src/app/components/admin-jobs/admin-jobs.html - 222 + 224 @@ -1331,7 +1331,7 @@ No auto-renewal on membership. apps/client/src/app/components/user-account-membership/user-account-membership.html - 73 + 74 @@ -1359,7 +1359,7 @@ Wciel się w Użytkownika apps/client/src/app/components/admin-users/admin-users.html - 232 + 234 @@ -1367,7 +1367,7 @@ Usuń Użytkownika apps/client/src/app/components/admin-users/admin-users.html - 253 + 255 @@ -1459,11 +1459,11 @@ apps/client/src/app/components/header/header.component.ts - 290 + 297 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 68 + 79 libs/common/src/lib/routes/routes.ts @@ -1479,7 +1479,7 @@ Ups! Nieprawidłowy token bezpieczeństwa. apps/client/src/app/components/header/header.component.ts - 305 + 312 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -1739,7 +1739,7 @@ Pozostań zalogowany apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 55 + 66 @@ -2059,7 +2059,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 20 + 21 apps/client/src/app/pages/pricing/pricing-page.html @@ -2187,7 +2187,7 @@ rocznie apps/client/src/app/components/user-account-membership/user-account-membership.html - 32 + 33 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -2203,7 +2203,7 @@ Wypróbuj Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 52 + 53 @@ -2211,7 +2211,7 @@ Wykorzystaj kupon apps/client/src/app/components/user-account-membership/user-account-membership.html - 66 + 67 @@ -3703,7 +3703,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 382 + 383 @@ -3719,7 +3719,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 394 + 397 @@ -4339,7 +4339,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 18 + 19 apps/client/src/app/pages/pricing/pricing-page.html @@ -4756,7 +4756,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 37 + 40 @@ -4820,7 +4820,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 407 + 411 @@ -4832,7 +4832,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 420 + 424 @@ -4848,7 +4848,7 @@ Sklonuj libs/ui/src/lib/activities-table/activities-table.component.html - 459 + 463 @@ -4856,7 +4856,7 @@ Eksportuj Wersję Roboczą jako ICS libs/ui/src/lib/activities-table/activities-table.component.html - 469 + 473 @@ -5296,7 +5296,7 @@ View Details apps/client/src/app/components/admin-users/admin-users.html - 225 + 226 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -5311,6 +5311,14 @@ 33 + + Sign in with OpenID Connect + Sign in with OpenID Connect + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 55 + + Buy Zakup @@ -5420,7 +5428,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 32 + 35 @@ -5568,7 +5576,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 42 + 45 @@ -6069,7 +6077,7 @@ Wykonaj Zadanie apps/client/src/app/components/admin-jobs/admin-jobs.html - 218 + 220 @@ -6461,7 +6469,7 @@ View Holding libs/ui/src/lib/activities-table/activities-table.component.html - 446 + 450 @@ -6729,7 +6737,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 36 + 14 @@ -7167,7 +7175,7 @@ Klucz API libs/ui/src/lib/membership-card/membership-card.component.html - 18 + 21 @@ -7175,7 +7183,7 @@ Generowanie klucza API Ghostfolio Premium Data Provider dla środowisk hostowanych samodzielnie... libs/ui/src/lib/membership-card/membership-card.component.html - 26 + 29 @@ -7531,7 +7539,7 @@ Generowanie Tokena Zabezpieczającego apps/client/src/app/components/admin-users/admin-users.html - 242 + 244 @@ -7907,7 +7915,7 @@ Oferta ograniczona czasowo! apps/client/src/app/components/user-account-membership/user-account-membership.html - 40 + 41 apps/client/src/app/pages/pricing/pricing-page.html @@ -7919,7 +7927,7 @@ Uzyskaj dodatkowo apps/client/src/app/components/user-account-membership/user-account-membership.html - 43 + 44 apps/client/src/app/pages/pricing/pricing-page.html @@ -8592,7 +8600,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 20 + 26 diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index 9c928731a..8b63acdf6 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -310,7 +310,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 453 + 457 @@ -346,7 +346,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 480 + 484 libs/ui/src/lib/benchmark/benchmark.component.html @@ -474,7 +474,7 @@ Ver Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 215 + 216 @@ -482,7 +482,7 @@ Apagar Tarefa apps/client/src/app/components/admin-jobs/admin-jobs.html - 222 + 224 @@ -738,7 +738,7 @@ No auto-renewal on membership. apps/client/src/app/components/user-account-membership/user-account-membership.html - 73 + 74 @@ -834,11 +834,11 @@ apps/client/src/app/components/header/header.component.ts - 290 + 297 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 68 + 79 libs/common/src/lib/routes/routes.ts @@ -854,7 +854,7 @@ Oops! Token de Segurança Incorreto. apps/client/src/app/components/header/header.component.ts - 305 + 312 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -1022,7 +1022,7 @@ Manter sessão iniciada apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 55 + 66 @@ -1482,7 +1482,7 @@ por ano apps/client/src/app/components/user-account-membership/user-account-membership.html - 32 + 33 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -1498,7 +1498,7 @@ Experimentar Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 52 + 53 @@ -1506,7 +1506,7 @@ Resgatar Cupão apps/client/src/app/components/user-account-membership/user-account-membership.html - 66 + 67 @@ -2610,7 +2610,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 382 + 383 @@ -2622,7 +2622,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 407 + 411 @@ -2634,7 +2634,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 420 + 424 @@ -2642,7 +2642,7 @@ Clonar libs/ui/src/lib/activities-table/activities-table.component.html - 459 + 463 @@ -2650,7 +2650,7 @@ Exportar Rascunho como ICS libs/ui/src/lib/activities-table/activities-table.component.html - 469 + 473 @@ -2902,7 +2902,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 32 + 35 @@ -3250,7 +3250,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 394 + 397 @@ -3262,7 +3262,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 42 + 45 @@ -3450,7 +3450,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 20 + 21 apps/client/src/app/pages/pricing/pricing-page.html @@ -3702,7 +3702,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 18 + 19 apps/client/src/app/pages/pricing/pricing-page.html @@ -3722,7 +3722,7 @@ Personificar Utilizador apps/client/src/app/components/admin-users/admin-users.html - 232 + 234 @@ -3730,7 +3730,7 @@ Apagar Utilizador apps/client/src/app/components/admin-users/admin-users.html - 253 + 255 @@ -3982,7 +3982,7 @@ View Details apps/client/src/app/components/admin-users/admin-users.html - 225 + 226 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -4361,6 +4361,14 @@ 73 + + Sign in with OpenID Connect + Sign in with OpenID Connect + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 55 + + Buy Comprar @@ -5444,7 +5452,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 37 + 40 @@ -6069,7 +6077,7 @@ Executar trabalho apps/client/src/app/components/admin-jobs/admin-jobs.html - 218 + 220 @@ -6461,7 +6469,7 @@ View Holding libs/ui/src/lib/activities-table/activities-table.component.html - 446 + 450 @@ -6729,7 +6737,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 36 + 14 @@ -7167,7 +7175,7 @@ Chave de API libs/ui/src/lib/membership-card/membership-card.component.html - 18 + 21 @@ -7175,7 +7183,7 @@ Gerar chave de API do Provedor de Dados do Ghostfolio Premium para ambientes auto-hospedados... libs/ui/src/lib/membership-card/membership-card.component.html - 26 + 29 @@ -7531,7 +7539,7 @@ Generate Security Token apps/client/src/app/components/admin-users/admin-users.html - 242 + 244 @@ -7907,7 +7915,7 @@ Limited Offer! apps/client/src/app/components/user-account-membership/user-account-membership.html - 40 + 41 apps/client/src/app/pages/pricing/pricing-page.html @@ -7919,7 +7927,7 @@ Get extra apps/client/src/app/components/user-account-membership/user-account-membership.html - 43 + 44 apps/client/src/app/pages/pricing/pricing-page.html @@ -8592,7 +8600,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 20 + 26 diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index 810f91cfa..bc687b3d4 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -491,7 +491,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 453 + 457 @@ -527,7 +527,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 480 + 484 libs/ui/src/lib/benchmark/benchmark.component.html @@ -655,7 +655,7 @@ Hata İzini Görüntüle apps/client/src/app/components/admin-jobs/admin-jobs.html - 215 + 216 @@ -663,7 +663,7 @@ İşleri Sil apps/client/src/app/components/admin-jobs/admin-jobs.html - 222 + 224 @@ -1199,7 +1199,7 @@ No auto-renewal on membership. apps/client/src/app/components/user-account-membership/user-account-membership.html - 73 + 74 @@ -1227,7 +1227,7 @@ Kullanıcıyı Taklit Et apps/client/src/app/components/admin-users/admin-users.html - 232 + 234 @@ -1235,7 +1235,7 @@ Kullanıcıyı Sil apps/client/src/app/components/admin-users/admin-users.html - 253 + 255 @@ -1319,11 +1319,11 @@ apps/client/src/app/components/header/header.component.ts - 290 + 297 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 68 + 79 libs/common/src/lib/routes/routes.ts @@ -1339,7 +1339,7 @@ Hay Allah! Güvenlik anahtarı yanlış. apps/client/src/app/components/header/header.component.ts - 305 + 312 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -1599,7 +1599,7 @@ Oturumu açık tut apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 55 + 66 @@ -1919,7 +1919,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 20 + 21 apps/client/src/app/pages/pricing/pricing-page.html @@ -3183,7 +3183,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 382 + 383 @@ -3199,7 +3199,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 394 + 397 @@ -3827,7 +3827,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 18 + 19 apps/client/src/app/pages/pricing/pricing-page.html @@ -4324,7 +4324,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 42 + 45 @@ -4332,7 +4332,7 @@ yıllık apps/client/src/app/components/user-account-membership/user-account-membership.html - 32 + 33 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -4348,7 +4348,7 @@ Premium’u Deneyin apps/client/src/app/components/user-account-membership/user-account-membership.html - 52 + 53 @@ -4356,7 +4356,7 @@ Kupon Kullan apps/client/src/app/components/user-account-membership/user-account-membership.html - 66 + 67 @@ -4540,7 +4540,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 407 + 411 @@ -4552,7 +4552,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 420 + 424 @@ -4568,7 +4568,7 @@ Klonla libs/ui/src/lib/activities-table/activities-table.component.html - 459 + 463 @@ -4576,7 +4576,7 @@ Taslakları ICS Olarak Dışa Aktar libs/ui/src/lib/activities-table/activities-table.component.html - 469 + 473 @@ -4988,7 +4988,7 @@ View Details apps/client/src/app/components/admin-users/admin-users.html - 225 + 226 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -5003,6 +5003,14 @@ 33 + + Sign in with OpenID Connect + Sign in with OpenID Connect + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 55 + + Buy Al @@ -5096,7 +5104,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 32 + 35 @@ -5444,7 +5452,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 37 + 40 @@ -6069,7 +6077,7 @@ İşlemi Yürüt apps/client/src/app/components/admin-jobs/admin-jobs.html - 218 + 220 @@ -6461,7 +6469,7 @@ View Holding libs/ui/src/lib/activities-table/activities-table.component.html - 446 + 450 @@ -6729,7 +6737,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 36 + 14 @@ -7167,7 +7175,7 @@ API Anahtarı libs/ui/src/lib/membership-card/membership-card.component.html - 18 + 21 @@ -7175,7 +7183,7 @@ Kendi barındırılan ortamlar için Ghostfolio Premium Veri Sağlayıcı API anahtarı oluştur... libs/ui/src/lib/membership-card/membership-card.component.html - 26 + 29 @@ -7531,7 +7539,7 @@ Güvenlik belirteci oluştur apps/client/src/app/components/admin-users/admin-users.html - 242 + 244 @@ -7907,7 +7915,7 @@ Sınırlı Teklif! apps/client/src/app/components/user-account-membership/user-account-membership.html - 40 + 41 apps/client/src/app/pages/pricing/pricing-page.html @@ -7919,7 +7927,7 @@ Get extra apps/client/src/app/components/user-account-membership/user-account-membership.html - 43 + 44 apps/client/src/app/pages/pricing/pricing-page.html @@ -8592,7 +8600,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 20 + 26 diff --git a/apps/client/src/locales/messages.uk.xlf b/apps/client/src/locales/messages.uk.xlf index 24bc12dd1..166b79a13 100644 --- a/apps/client/src/locales/messages.uk.xlf +++ b/apps/client/src/locales/messages.uk.xlf @@ -38,11 +38,11 @@ apps/client/src/app/components/header/header.component.ts - 290 + 297 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 68 + 79 libs/common/src/lib/routes/routes.ts @@ -623,7 +623,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 453 + 457 @@ -659,7 +659,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 480 + 484 libs/ui/src/lib/benchmark/benchmark.component.html @@ -819,7 +819,7 @@ Переглянути трасування apps/client/src/app/components/admin-jobs/admin-jobs.html - 215 + 216 @@ -827,7 +827,7 @@ Виконати завдання apps/client/src/app/components/admin-jobs/admin-jobs.html - 218 + 220 @@ -835,7 +835,7 @@ Видалити завдання apps/client/src/app/components/admin-jobs/admin-jobs.html - 222 + 224 @@ -1427,7 +1427,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 42 + 45 @@ -1567,7 +1567,7 @@ No auto-renewal on membership. apps/client/src/app/components/user-account-membership/user-account-membership.html - 73 + 74 @@ -1647,7 +1647,7 @@ Видавати себе за користувача apps/client/src/app/components/admin-users/admin-users.html - 232 + 234 @@ -1655,7 +1655,7 @@ Видалити користувача apps/client/src/app/components/admin-users/admin-users.html - 253 + 255 @@ -1739,7 +1739,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 20 + 21 apps/client/src/app/pages/pricing/pricing-page.html @@ -1755,7 +1755,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 18 + 19 apps/client/src/app/pages/pricing/pricing-page.html @@ -1779,7 +1779,7 @@ Упс! Неправильний Секретний Токен. apps/client/src/app/components/header/header.component.ts - 305 + 312 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -2135,7 +2135,7 @@ Залишатися в системі apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 55 + 66 @@ -2759,7 +2759,7 @@ на рік apps/client/src/app/components/user-account-membership/user-account-membership.html - 32 + 33 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -2775,7 +2775,7 @@ Спробуйте Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 52 + 53 @@ -2783,7 +2783,7 @@ Обміняти купон apps/client/src/app/components/user-account-membership/user-account-membership.html - 66 + 67 @@ -4376,7 +4376,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 382 + 383 @@ -4392,7 +4392,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 394 + 397 @@ -5947,7 +5947,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 37 + 40 @@ -6019,7 +6019,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 407 + 411 @@ -6031,7 +6031,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 420 + 424 @@ -6055,7 +6055,7 @@ Клонувати libs/ui/src/lib/activities-table/activities-table.component.html - 459 + 463 @@ -6063,7 +6063,7 @@ Експортувати чернетку як ICS libs/ui/src/lib/activities-table/activities-table.component.html - 469 + 473 @@ -6763,7 +6763,7 @@ View Details apps/client/src/app/components/admin-users/admin-users.html - 225 + 226 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -6783,7 +6783,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 36 + 14 @@ -6794,6 +6794,14 @@ 34 + + Sign in with OpenID Connect + Sign in with OpenID Connect + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 55 + + Buy Купити @@ -6911,7 +6919,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 32 + 35 @@ -7063,7 +7071,7 @@ View Holding libs/ui/src/lib/activities-table/activities-table.component.html - 446 + 450 @@ -7223,7 +7231,7 @@ Ключ API libs/ui/src/lib/membership-card/membership-card.component.html - 18 + 21 @@ -7231,7 +7239,7 @@ Згенерувати ключ API для постачальника даних Ghostfolio Premium для self-hosted середовищ... libs/ui/src/lib/membership-card/membership-card.component.html - 26 + 29 @@ -7531,7 +7539,7 @@ Generate Security Token apps/client/src/app/components/admin-users/admin-users.html - 242 + 244 @@ -7907,7 +7915,7 @@ Limited Offer! apps/client/src/app/components/user-account-membership/user-account-membership.html - 40 + 41 apps/client/src/app/pages/pricing/pricing-page.html @@ -7919,7 +7927,7 @@ Get extra apps/client/src/app/components/user-account-membership/user-account-membership.html - 43 + 44 apps/client/src/app/pages/pricing/pricing-page.html @@ -8592,7 +8600,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 20 + 26 diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index 800f238ef..92d1c9639 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -509,7 +509,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 453 + 457 @@ -544,7 +544,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 480 + 484 libs/ui/src/lib/benchmark/benchmark.component.html @@ -656,14 +656,14 @@ View Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 215 + 216 Delete Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 222 + 224 @@ -1254,7 +1254,7 @@ No auto-renewal on membership. apps/client/src/app/components/user-account-membership/user-account-membership.html - 73 + 74 @@ -1279,14 +1279,14 @@ Impersonate User apps/client/src/app/components/admin-users/admin-users.html - 232 + 234 Delete User apps/client/src/app/components/admin-users/admin-users.html - 253 + 255 @@ -1370,11 +1370,11 @@ apps/client/src/app/components/header/header.component.ts - 290 + 297 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 68 + 79 libs/common/src/lib/routes/routes.ts @@ -1389,7 +1389,7 @@ Oops! Incorrect Security Token. apps/client/src/app/components/header/header.component.ts - 305 + 312 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -1627,7 +1627,7 @@ Stay signed in apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 55 + 66 @@ -1919,7 +1919,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 20 + 21 apps/client/src/app/pages/pricing/pricing-page.html @@ -2034,7 +2034,7 @@ per year apps/client/src/app/components/user-account-membership/user-account-membership.html - 32 + 33 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -2049,14 +2049,14 @@ Try Premium apps/client/src/app/components/user-account-membership/user-account-membership.html - 52 + 53 Redeem Coupon apps/client/src/app/components/user-account-membership/user-account-membership.html - 66 + 67 @@ -3417,7 +3417,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 382 + 383 @@ -3432,7 +3432,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 394 + 397 @@ -3989,7 +3989,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 18 + 19 apps/client/src/app/pages/pricing/pricing-page.html @@ -4378,7 +4378,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 37 + 40 @@ -4442,7 +4442,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 407 + 411 @@ -4453,7 +4453,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 420 + 424 @@ -4467,14 +4467,14 @@ Clone libs/ui/src/lib/activities-table/activities-table.component.html - 459 + 463 Export Draft as ICS libs/ui/src/lib/activities-table/activities-table.component.html - 469 + 473 @@ -4888,7 +4888,7 @@ View Details apps/client/src/app/components/admin-users/admin-users.html - 225 + 226 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -4902,6 +4902,13 @@ 33 + + Sign in with OpenID Connect + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 55 + + Buy @@ -5000,7 +5007,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 32 + 35 @@ -5130,7 +5137,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 42 + 45 @@ -5541,7 +5548,7 @@ Execute Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 218 + 220 @@ -5841,7 +5848,7 @@ View Holding libs/ui/src/lib/activities-table/activities-table.component.html - 446 + 450 @@ -6058,7 +6065,7 @@ Role apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 36 + 14 @@ -6488,14 +6495,14 @@ Generate Ghostfolio Premium Data Provider API key for self-hosted environments... libs/ui/src/lib/membership-card/membership-card.component.html - 26 + 29 API Key libs/ui/src/lib/membership-card/membership-card.component.html - 18 + 21 @@ -6854,7 +6861,7 @@ Generate Security Token apps/client/src/app/components/admin-users/admin-users.html - 242 + 244 @@ -7168,7 +7175,7 @@ Limited Offer! apps/client/src/app/components/user-account-membership/user-account-membership.html - 40 + 41 apps/client/src/app/pages/pricing/pricing-page.html @@ -7179,7 +7186,7 @@ Get extra apps/client/src/app/components/user-account-membership/user-account-membership.html - 43 + 44 apps/client/src/app/pages/pricing/pricing-page.html @@ -7772,7 +7779,7 @@ Registration Date apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 20 + 26 diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index 5c2508f8d..6a9abc040 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -540,7 +540,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 453 + 457 @@ -576,7 +576,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 480 + 484 libs/ui/src/lib/benchmark/benchmark.component.html @@ -700,7 +700,7 @@ 查看堆栈跟踪 apps/client/src/app/components/admin-jobs/admin-jobs.html - 215 + 216 @@ -708,7 +708,7 @@ 删除任务 apps/client/src/app/components/admin-jobs/admin-jobs.html - 222 + 224 @@ -1340,7 +1340,7 @@ No auto-renewal on membership. apps/client/src/app/components/user-account-membership/user-account-membership.html - 73 + 74 @@ -1368,7 +1368,7 @@ 模拟用户 apps/client/src/app/components/admin-users/admin-users.html - 232 + 234 @@ -1376,7 +1376,7 @@ 删除用户 apps/client/src/app/components/admin-users/admin-users.html - 253 + 255 @@ -1468,11 +1468,11 @@ apps/client/src/app/components/header/header.component.ts - 290 + 297 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 68 + 79 libs/common/src/lib/routes/routes.ts @@ -1488,7 +1488,7 @@ 哎呀!安全令牌不正确。 apps/client/src/app/components/header/header.component.ts - 305 + 312 apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -1748,7 +1748,7 @@ 保持登录 apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html - 55 + 66 @@ -2068,7 +2068,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 20 + 21 apps/client/src/app/pages/pricing/pricing-page.html @@ -2196,7 +2196,7 @@ 每年 apps/client/src/app/components/user-account-membership/user-account-membership.html - 32 + 33 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -2212,7 +2212,7 @@ 尝试高级版 apps/client/src/app/components/user-account-membership/user-account-membership.html - 52 + 53 @@ -2220,7 +2220,7 @@ 兑换优惠券 apps/client/src/app/components/user-account-membership/user-account-membership.html - 66 + 67 @@ -3712,7 +3712,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 382 + 383 @@ -3728,7 +3728,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 394 + 397 @@ -4348,7 +4348,7 @@ apps/client/src/app/components/user-account-membership/user-account-membership.html - 18 + 19 apps/client/src/app/pages/pricing/pricing-page.html @@ -4777,7 +4777,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 37 + 40 @@ -4849,7 +4849,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 407 + 411 @@ -4861,7 +4861,7 @@ libs/ui/src/lib/activities-table/activities-table.component.html - 420 + 424 @@ -4877,7 +4877,7 @@ 克隆 libs/ui/src/lib/activities-table/activities-table.component.html - 459 + 463 @@ -4885,7 +4885,7 @@ 将汇票导出为 ICS libs/ui/src/lib/activities-table/activities-table.component.html - 469 + 473 @@ -5341,7 +5341,7 @@ 查看详细信息 apps/client/src/app/components/admin-users/admin-users.html - 225 + 226 libs/ui/src/lib/accounts-table/accounts-table.component.html @@ -5356,6 +5356,14 @@ 33 + + Sign in with OpenID Connect + Sign in with OpenID Connect + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 55 + + Buy 买入 @@ -5465,7 +5473,7 @@ Authentication apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 32 + 35 @@ -5613,7 +5621,7 @@ libs/ui/src/lib/membership-card/membership-card.component.html - 42 + 45 @@ -6070,7 +6078,7 @@ 执行作业 apps/client/src/app/components/admin-jobs/admin-jobs.html - 218 + 220 @@ -6462,7 +6470,7 @@ 查看持仓 libs/ui/src/lib/activities-table/activities-table.component.html - 446 + 450 @@ -6730,7 +6738,7 @@ 角色 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 36 + 14 @@ -7168,7 +7176,7 @@ API 密钥 libs/ui/src/lib/membership-card/membership-card.component.html - 18 + 21 @@ -7176,7 +7184,7 @@ 为自托管环境生成 Ghostfolio Premium 数据提供者 API 密钥... libs/ui/src/lib/membership-card/membership-card.component.html - 26 + 29 @@ -7532,7 +7540,7 @@ 生成安全令牌 apps/client/src/app/components/admin-users/admin-users.html - 242 + 244 @@ -7908,7 +7916,7 @@ 限时优惠! apps/client/src/app/components/user-account-membership/user-account-membership.html - 40 + 41 apps/client/src/app/pages/pricing/pricing-page.html @@ -7920,7 +7928,7 @@ 获取额外 apps/client/src/app/components/user-account-membership/user-account-membership.html - 43 + 44 apps/client/src/app/pages/pricing/pricing-page.html @@ -8593,7 +8601,7 @@ 注册日期 apps/client/src/app/components/user-detail-dialog/user-detail-dialog.html - 20 + 26 diff --git a/apps/client/src/main.ts b/apps/client/src/main.ts index fc8a9ef7a..2a22b7b7b 100644 --- a/apps/client/src/main.ts +++ b/apps/client/src/main.ts @@ -1,6 +1,7 @@ import { locale } from '@ghostfolio/common/config'; import { InfoResponse } from '@ghostfolio/common/interfaces'; import { filterGlobalPermissions } from '@ghostfolio/common/permissions'; +import { GfNotificationModule } from '@ghostfolio/ui/notifications'; import { Platform } from '@angular/cdk/platform'; import { @@ -33,7 +34,6 @@ import { authInterceptorProviders } from './app/core/auth.interceptor'; import { httpResponseInterceptorProviders } from './app/core/http-response.interceptor'; import { LanguageService } from './app/core/language.service'; import { ModulePreloadService } from './app/core/module-preload.service'; -import { GfNotificationModule } from './app/core/notification/notification.module'; import { PageTitleStrategy } from './app/services/page-title.strategy'; import { environment } from './environments/environment'; diff --git a/libs/common/src/lib/permissions.ts b/libs/common/src/lib/permissions.ts index 597c27690..2e244568c 100644 --- a/libs/common/src/lib/permissions.ts +++ b/libs/common/src/lib/permissions.ts @@ -29,6 +29,7 @@ export const permissions = { deleteUser: 'deleteUser', deleteWatchlistItem: 'deleteWatchlistItem', enableAuthGoogle: 'enableAuthGoogle', + enableAuthOidc: 'enableAuthOidc', enableAuthToken: 'enableAuthToken', enableDataProviderGhostfolio: 'enableDataProviderGhostfolio', enableFearAndGreedIndex: 'enableFearAndGreedIndex', @@ -159,6 +160,7 @@ export function filterGlobalPermissions( return globalPermissions.filter((permission) => { return ( permission !== permissions.enableAuthGoogle && + permission !== permissions.enableAuthOidc && permission !== permissions.enableSubscription ); }); diff --git a/libs/ui/src/lib/account-balances/account-balances.component.ts b/libs/ui/src/lib/account-balances/account-balances.component.ts index 5fe47347e..608ee1c75 100644 --- a/libs/ui/src/lib/account-balances/account-balances.component.ts +++ b/libs/ui/src/lib/account-balances/account-balances.component.ts @@ -1,10 +1,9 @@ -/* eslint-disable @nx/enforce-module-boundaries */ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { CreateAccountBalanceDto } from '@ghostfolio/common/dtos'; import { ConfirmationDialogType } from '@ghostfolio/common/enums'; import { DATE_FORMAT, getLocale } from '@ghostfolio/common/helper'; import { AccountBalancesResponse } from '@ghostfolio/common/interfaces'; import { validateObjectForForm } from '@ghostfolio/common/utils'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { CUSTOM_ELEMENTS_SCHEMA, diff --git a/libs/ui/src/lib/accounts-table/accounts-table.component.stories.ts b/libs/ui/src/lib/accounts-table/accounts-table.component.stories.ts index aeda82fd9..53c59a95f 100644 --- a/libs/ui/src/lib/accounts-table/accounts-table.component.stories.ts +++ b/libs/ui/src/lib/accounts-table/accounts-table.component.stories.ts @@ -7,10 +7,10 @@ import { RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; import { moduleMetadata } from '@storybook/angular'; import type { Meta, StoryObj } from '@storybook/angular'; -import { NotificationService } from 'apps/client/src/app/core/notification/notification.service'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { GfEntityLogoComponent } from '../entity-logo'; +import { NotificationService } from '../notifications'; import { GfValueComponent } from '../value'; import { GfAccountsTableComponent } from './accounts-table.component'; diff --git a/libs/ui/src/lib/accounts-table/accounts-table.component.ts b/libs/ui/src/lib/accounts-table/accounts-table.component.ts index 898231168..699de6d7e 100644 --- a/libs/ui/src/lib/accounts-table/accounts-table.component.ts +++ b/libs/ui/src/lib/accounts-table/accounts-table.component.ts @@ -1,8 +1,7 @@ -/* eslint-disable @nx/enforce-module-boundaries */ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { ConfirmationDialogType } from '@ghostfolio/common/enums'; import { getLocale } from '@ghostfolio/common/helper'; import { GfEntityLogoComponent } from '@ghostfolio/ui/entity-logo'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; diff --git a/libs/ui/src/lib/activities-table/activities-table.component.stories.ts b/libs/ui/src/lib/activities-table/activities-table.component.stories.ts index a0ad690d7..e7a2ba819 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.stories.ts +++ b/libs/ui/src/lib/activities-table/activities-table.component.stories.ts @@ -13,12 +13,12 @@ import { RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; import { moduleMetadata } from '@storybook/angular'; import type { Meta, StoryObj } from '@storybook/angular'; -import { NotificationService } from 'apps/client/src/app/core/notification/notification.service'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { GfActivityTypeComponent } from '../activity-type/activity-type.component'; import { GfEntityLogoComponent } from '../entity-logo'; import { GfNoTransactionsInfoComponent } from '../no-transactions-info/no-transactions-info.component'; +import { NotificationService } from '../notifications'; import { GfValueComponent } from '../value'; import { GfActivitiesTableComponent } from './activities-table.component'; diff --git a/libs/ui/src/lib/activities-table/activities-table.component.ts b/libs/ui/src/lib/activities-table/activities-table.component.ts index 476fca5fb..e53f37872 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.ts +++ b/libs/ui/src/lib/activities-table/activities-table.component.ts @@ -1,5 +1,3 @@ -/* eslint-disable @nx/enforce-module-boundaries */ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { DEFAULT_PAGE_SIZE, TAG_ID_EXCLUDE_FROM_ANALYSIS @@ -12,6 +10,7 @@ import { } from '@ghostfolio/common/interfaces'; import { GfSymbolPipe } from '@ghostfolio/common/pipes'; import { OrderWithAccount } from '@ghostfolio/common/types'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { SelectionModel } from '@angular/cdk/collections'; import { CommonModule } from '@angular/common'; diff --git a/libs/ui/src/lib/benchmark/benchmark.component.ts b/libs/ui/src/lib/benchmark/benchmark.component.ts index 5793300c1..fe53240ed 100644 --- a/libs/ui/src/lib/benchmark/benchmark.component.ts +++ b/libs/ui/src/lib/benchmark/benchmark.component.ts @@ -1,5 +1,3 @@ -/* eslint-disable @nx/enforce-module-boundaries */ -import { NotificationService } from '@ghostfolio/client/core/notification/notification.service'; import { ConfirmationDialogType } from '@ghostfolio/common/enums'; import { getLocale, resolveMarketCondition } from '@ghostfolio/common/helper'; import { @@ -7,6 +5,7 @@ import { Benchmark, User } from '@ghostfolio/common/interfaces'; +import { NotificationService } from '@ghostfolio/ui/notifications'; import { CommonModule } from '@angular/common'; import { diff --git a/apps/client/src/app/core/notification/alert-dialog/alert-dialog.component.ts b/libs/ui/src/lib/notifications/alert-dialog/alert-dialog.component.ts similarity index 100% rename from apps/client/src/app/core/notification/alert-dialog/alert-dialog.component.ts rename to libs/ui/src/lib/notifications/alert-dialog/alert-dialog.component.ts diff --git a/apps/client/src/app/core/notification/alert-dialog/alert-dialog.html b/libs/ui/src/lib/notifications/alert-dialog/alert-dialog.html similarity index 100% rename from apps/client/src/app/core/notification/alert-dialog/alert-dialog.html rename to libs/ui/src/lib/notifications/alert-dialog/alert-dialog.html diff --git a/apps/client/src/app/core/notification/alert-dialog/alert-dialog.scss b/libs/ui/src/lib/notifications/alert-dialog/alert-dialog.scss similarity index 100% rename from apps/client/src/app/core/notification/alert-dialog/alert-dialog.scss rename to libs/ui/src/lib/notifications/alert-dialog/alert-dialog.scss diff --git a/apps/client/src/app/core/notification/alert-dialog/interfaces/interfaces.ts b/libs/ui/src/lib/notifications/alert-dialog/interfaces/interfaces.ts similarity index 100% rename from apps/client/src/app/core/notification/alert-dialog/interfaces/interfaces.ts rename to libs/ui/src/lib/notifications/alert-dialog/interfaces/interfaces.ts diff --git a/apps/client/src/app/core/notification/confirmation-dialog/confirmation-dialog.component.ts b/libs/ui/src/lib/notifications/confirmation-dialog/confirmation-dialog.component.ts similarity index 100% rename from apps/client/src/app/core/notification/confirmation-dialog/confirmation-dialog.component.ts rename to libs/ui/src/lib/notifications/confirmation-dialog/confirmation-dialog.component.ts diff --git a/apps/client/src/app/core/notification/confirmation-dialog/confirmation-dialog.html b/libs/ui/src/lib/notifications/confirmation-dialog/confirmation-dialog.html similarity index 100% rename from apps/client/src/app/core/notification/confirmation-dialog/confirmation-dialog.html rename to libs/ui/src/lib/notifications/confirmation-dialog/confirmation-dialog.html diff --git a/apps/client/src/app/core/notification/confirmation-dialog/confirmation-dialog.scss b/libs/ui/src/lib/notifications/confirmation-dialog/confirmation-dialog.scss similarity index 100% rename from apps/client/src/app/core/notification/confirmation-dialog/confirmation-dialog.scss rename to libs/ui/src/lib/notifications/confirmation-dialog/confirmation-dialog.scss diff --git a/apps/client/src/app/core/notification/confirmation-dialog/interfaces/interfaces.ts b/libs/ui/src/lib/notifications/confirmation-dialog/interfaces/interfaces.ts similarity index 100% rename from apps/client/src/app/core/notification/confirmation-dialog/interfaces/interfaces.ts rename to libs/ui/src/lib/notifications/confirmation-dialog/interfaces/interfaces.ts diff --git a/libs/ui/src/lib/notifications/index.ts b/libs/ui/src/lib/notifications/index.ts new file mode 100644 index 000000000..864083b16 --- /dev/null +++ b/libs/ui/src/lib/notifications/index.ts @@ -0,0 +1,3 @@ +export * from './interfaces/interfaces'; +export * from './notification.module'; +export * from './notification.service'; diff --git a/apps/client/src/app/core/notification/interfaces/interfaces.ts b/libs/ui/src/lib/notifications/interfaces/interfaces.ts similarity index 100% rename from apps/client/src/app/core/notification/interfaces/interfaces.ts rename to libs/ui/src/lib/notifications/interfaces/interfaces.ts diff --git a/apps/client/src/app/core/notification/notification.module.ts b/libs/ui/src/lib/notifications/notification.module.ts similarity index 100% rename from apps/client/src/app/core/notification/notification.module.ts rename to libs/ui/src/lib/notifications/notification.module.ts diff --git a/apps/client/src/app/core/notification/notification.service.ts b/libs/ui/src/lib/notifications/notification.service.ts similarity index 100% rename from apps/client/src/app/core/notification/notification.service.ts rename to libs/ui/src/lib/notifications/notification.service.ts diff --git a/apps/client/src/app/core/notification/prompt-dialog/prompt-dialog.component.ts b/libs/ui/src/lib/notifications/prompt-dialog/prompt-dialog.component.ts similarity index 100% rename from apps/client/src/app/core/notification/prompt-dialog/prompt-dialog.component.ts rename to libs/ui/src/lib/notifications/prompt-dialog/prompt-dialog.component.ts diff --git a/apps/client/src/app/core/notification/prompt-dialog/prompt-dialog.html b/libs/ui/src/lib/notifications/prompt-dialog/prompt-dialog.html similarity index 100% rename from apps/client/src/app/core/notification/prompt-dialog/prompt-dialog.html rename to libs/ui/src/lib/notifications/prompt-dialog/prompt-dialog.html diff --git a/package-lock.json b/package-lock.json index 5023225af..3ff57109e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "ghostfolio", - "version": "2.221.0", + "version": "2.222.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "ghostfolio", - "version": "2.221.0", + "version": "2.222.0", "hasInstallScript": true, "license": "AGPL-3.0", "dependencies": { @@ -83,6 +83,7 @@ "passport-google-oauth20": "2.0.0", "passport-headerapikey": "1.2.2", "passport-jwt": "4.0.1", + "passport-openidconnect": "0.1.2", "reflect-metadata": "0.2.2", "rxjs": "7.8.1", "stripe": "18.5.0", @@ -129,6 +130,7 @@ "@types/node": "22.15.17", "@types/papaparse": "5.3.7", "@types/passport-google-oauth20": "2.0.16", + "@types/passport-openidconnect": "0.1.3", "@typescript-eslint/eslint-plugin": "8.43.0", "@typescript-eslint/parser": "8.43.0", "eslint": "9.35.0", @@ -13841,6 +13843,30 @@ "@types/passport": "*" } }, + "node_modules/@types/passport-openidconnect": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@types/passport-openidconnect/-/passport-openidconnect-0.1.3.tgz", + "integrity": "sha512-k1Ni7bG/9OZNo2Qpjg2W6GajL+pww6ZPaNWMXfpteCX4dXf4QgaZLt2hjR5IiPrqwBT9+W8KjCTJ/uhGIoBx/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*", + "@types/oauth": "*", + "@types/passport": "*", + "@types/passport-strategy": "*" + } + }, + "node_modules/@types/passport-strategy": { + "version": "0.2.38", + "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.38.tgz", + "integrity": "sha512-GC6eMqqojOooq993Tmnmp7AUTbbQSgilyvpCYQjT+H6JfG/g6RGc7nXEniZlp0zyKJ0WUdOiZWLBZft9Yug1uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*", + "@types/passport": "*" + } + }, "node_modules/@types/qs": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", @@ -31738,6 +31764,23 @@ "url": "https://github.com/sponsors/jaredhanson" } }, + "node_modules/passport-openidconnect": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/passport-openidconnect/-/passport-openidconnect-0.1.2.tgz", + "integrity": "sha512-JX3rTyW+KFZ/E9OF/IpXJPbyLO9vGzcmXB5FgSP2jfL3LGKJPdV7zUE8rWeKeeI/iueQggOeFa3onrCmhxXZTg==", + "license": "MIT", + "dependencies": { + "oauth": "0.10.x", + "passport-strategy": "1.x.x" + }, + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jaredhanson" + } + }, "node_modules/passport-strategy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", diff --git a/package.json b/package.json index d8804d543..4fd592e3d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.221.0", + "version": "2.222.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", @@ -127,6 +127,7 @@ "passport-google-oauth20": "2.0.0", "passport-headerapikey": "1.2.2", "passport-jwt": "4.0.1", + "passport-openidconnect": "0.1.2", "reflect-metadata": "0.2.2", "rxjs": "7.8.1", "stripe": "18.5.0", @@ -173,6 +174,7 @@ "@types/node": "22.15.17", "@types/papaparse": "5.3.7", "@types/passport-google-oauth20": "2.0.16", + "@types/passport-openidconnect": "0.1.3", "@typescript-eslint/eslint-plugin": "8.43.0", "@typescript-eslint/parser": "8.43.0", "eslint": "9.35.0", diff --git a/prisma/migrations/20251103162035_added_oidc_to_provider/migration.sql b/prisma/migrations/20251103162035_added_oidc_to_provider/migration.sql new file mode 100644 index 000000000..f71f6eded --- /dev/null +++ b/prisma/migrations/20251103162035_added_oidc_to_provider/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "Provider" ADD VALUE 'OIDC'; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 72ec79008..232dde9ca 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -335,6 +335,7 @@ enum Provider { ANONYMOUS GOOGLE INTERNET_IDENTITY + OIDC } enum Role {