Browse Source

Initial setup

pull/6501/head
Thomas Kaul 3 weeks ago
parent
commit
6172cf22bf
  1. 5
      apps/api/src/app/app.module.ts
  2. 6
      apps/api/src/main.ts
  3. 7
      apps/api/src/middlewares/bull-board-auth.middleware.ts
  4. 6
      apps/client/src/app/components/admin-jobs/admin-jobs.component.ts
  5. 8
      libs/common/src/lib/config.ts
  6. 31
      package-lock.json
  7. 2
      package.json

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

@ -11,6 +11,7 @@ import { PropertyModule } from '@ghostfolio/api/services/property/property.modul
import { DataGatheringModule } from '@ghostfolio/api/services/queues/data-gathering/data-gathering.module';
import { PortfolioSnapshotQueueModule } from '@ghostfolio/api/services/queues/portfolio-snapshot/portfolio-snapshot.module';
import {
BULL_BOARD_ROUTE,
DEFAULT_LANGUAGE_CODE,
SUPPORTED_LANGUAGE_CODES
} from '@ghostfolio/common/config';
@ -90,7 +91,7 @@ import { UserModule } from './user/user.module';
}
},
middleware: BullBoardAuthMiddleware,
route: '/admin/queues'
route: BULL_BOARD_ROUTE
}),
BullModule.forRoot({
redis: {
@ -128,8 +129,8 @@ import { UserModule } from './user/user.module';
ScheduleModule.forRoot(),
ServeStaticModule.forRoot({
exclude: [
`${BULL_BOARD_ROUTE}/*wildcard`,
'/.well-known/*wildcard',
'/admin/queues/*wildcard',
'/api/*wildcard',
'/sitemap.xml'
],

6
apps/api/src/main.ts

@ -1,4 +1,5 @@
import {
BULL_BOARD_ROUTE,
DEFAULT_HOST,
DEFAULT_PORT,
STORYBOOK_PATH,
@ -14,6 +15,7 @@ import {
import { ConfigService } from '@nestjs/config';
import { NestFactory } from '@nestjs/core';
import type { NestExpressApplication } from '@nestjs/platform-express';
import cookieParser from 'cookie-parser';
import { NextFunction, Request, Response } from 'express';
import helmet from 'helmet';
@ -46,7 +48,7 @@ async function bootstrap() {
});
app.setGlobalPrefix('api', {
exclude: [
'admin/queues{/*wildcard}',
`${BULL_BOARD_ROUTE.substring(1)}{/*wildcard}`,
'sitemap.xml',
...SUPPORTED_LANGUAGE_CODES.map((languageCode) => {
// Exclude language-specific routes with an optional wildcard
@ -66,6 +68,8 @@ async function bootstrap() {
// Support 10mb csv/json files for importing activities
app.useBodyParser('json', { limit: '10mb' });
app.use(cookieParser());
if (configService.get<string>('ENABLE_FEATURE_SUBSCRIPTION') === 'true') {
app.use((req: Request, res: Response, next: NextFunction) => {
if (req.path.startsWith(STORYBOOK_PATH)) {

7
apps/api/src/middlewares/bull-board-auth.middleware.ts

@ -1,3 +1,4 @@
import { BULL_BOARD_COOKIE_NAME } from '@ghostfolio/common/config';
import { hasPermission, permissions } from '@ghostfolio/common/permissions';
import { Injectable, NestMiddleware } from '@nestjs/common';
@ -8,11 +9,7 @@ import passport from 'passport';
@Injectable()
export class BullBoardAuthMiddleware implements NestMiddleware {
public use(req: Request, res: Response, next: NextFunction) {
const token = req.headers.cookie
?.split(';')
.map((c) => c.trim())
.find((c) => c.startsWith('bull_board_token='))
?.split('=')[1];
const token = req.cookies?.[BULL_BOARD_COOKIE_NAME];
if (token) {
req.headers.authorization = `Bearer ${token}`;

6
apps/client/src/app/components/admin-jobs/admin-jobs.component.ts

@ -1,6 +1,8 @@
import { TokenStorageService } from '@ghostfolio/client/services/token-storage.service';
import { UserService } from '@ghostfolio/client/services/user/user.service';
import {
BULL_BOARD_COOKIE_NAME,
BULL_BOARD_ROUTE,
DATA_GATHERING_QUEUE_PRIORITY_HIGH,
DATA_GATHERING_QUEUE_PRIORITY_LOW,
DATA_GATHERING_QUEUE_PRIORITY_MEDIUM,
@ -184,9 +186,9 @@ export class GfAdminJobsComponent implements OnDestroy, OnInit {
public onOpenBullBoard() {
const token = this.tokenStorageService.getToken();
document.cookie = `bull_board_token=${token}; path=/admin/queues; SameSite=Strict`;
document.cookie = `${BULL_BOARD_COOKIE_NAME}=${token}; path=${BULL_BOARD_ROUTE}; SameSite=Strict`;
window.open('/admin/queues', '_blank');
window.open(BULL_BOARD_ROUTE, '_blank');
}
public onViewData(aData: AdminJobs['jobs'][0]['data']) {

8
libs/common/src/lib/config.ts

@ -51,6 +51,14 @@ export const ASSET_CLASS_MAPPING = new Map<AssetClass, AssetSubClass[]>([
[AssetClass.REAL_ESTATE, []]
]);
export const BULL_BOARD_COOKIE_NAME = 'bull_board_token';
/**
* WARNING: This route is mirrored in `apps/client/proxy.conf.json`.
* If you update this value, you must also update the proxy configuration.
*/
export const BULL_BOARD_ROUTE = '/admin/queues';
export const CACHE_TTL_NO_CACHE = 1;
export const CACHE_TTL_INFINITE = 0;

31
package-lock.json

@ -58,6 +58,7 @@
"class-transformer": "0.5.1",
"class-validator": "0.14.3",
"color": "5.0.3",
"cookie-parser": "1.4.7",
"countries-and-timezones": "3.8.0",
"countries-list": "3.2.2",
"countup.js": "2.9.0",
@ -126,6 +127,7 @@
"@storybook/angular": "10.1.10",
"@trivago/prettier-plugin-sort-imports": "5.2.2",
"@types/big.js": "6.2.2",
"@types/cookie-parser": "1.4.10",
"@types/fast-redact": "3.0.4",
"@types/google-spreadsheet": "3.1.5",
"@types/jest": "30.0.0",
@ -12738,6 +12740,16 @@
"@types/node": "*"
}
},
"node_modules/@types/cookie-parser": {
"version": "1.4.10",
"resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.10.tgz",
"integrity": "sha512-B4xqkqfZ8Wek+rCOeRxsjMS9OgvzebEzzLYw7NHYuvzb7IdxOkI0ZHGgeEBX4PUM7QGVvNSK60T3OvWj3YfBRg==",
"dev": true,
"license": "MIT",
"peerDependencies": {
"@types/express": "*"
}
},
"node_modules/@types/d3": {
"version": "7.4.3",
"resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz",
@ -16970,6 +16982,25 @@
"node": ">= 0.6"
}
},
"node_modules/cookie-parser": {
"version": "1.4.7",
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz",
"integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==",
"license": "MIT",
"dependencies": {
"cookie": "0.7.2",
"cookie-signature": "1.0.6"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/cookie-parser/node_modules/cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
"license": "MIT"
},
"node_modules/cookie-signature": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",

2
package.json

@ -103,6 +103,7 @@
"class-transformer": "0.5.1",
"class-validator": "0.14.3",
"color": "5.0.3",
"cookie-parser": "1.4.7",
"countries-and-timezones": "3.8.0",
"countries-list": "3.2.2",
"countup.js": "2.9.0",
@ -171,6 +172,7 @@
"@storybook/angular": "10.1.10",
"@trivago/prettier-plugin-sort-imports": "5.2.2",
"@types/big.js": "6.2.2",
"@types/cookie-parser": "1.4.10",
"@types/fast-redact": "3.0.4",
"@types/google-spreadsheet": "3.1.5",
"@types/jest": "30.0.0",

Loading…
Cancel
Save