Skip to content

Commit

Permalink
fixing startup config issues
Browse files Browse the repository at this point in the history
  • Loading branch information
SelfhostedPro committed Jan 6, 2024
1 parent 447b997 commit d22c32a
Show file tree
Hide file tree
Showing 22 changed files with 457 additions and 308 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"i18n-ally.sortKeys": true,
"prettier.enable": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
"source.fixAll.eslint": "explicit"
},
"files.associations": {
"*.css": "postcss"
Expand Down
11 changes: 5 additions & 6 deletions server/src/auth/jwt.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { PassportStrategy } from '@nestjs/passport';
import { Injectable } from '@nestjs/common';
import { ConfigService } from '../config/config.service';
import { Request as RequestType } from 'express';
import { Socket } from 'socket.io'
var cookie = require('cookie');
import cookieParser from 'cookie-parser'
import { Socket } from 'socket.io';
const cookie = require('cookie');
import cookieParser from 'cookie-parser';

type JwtPayload = {
sub: string;
Expand All @@ -30,9 +30,8 @@ export class AccessTokenStrategy extends PassportStrategy(Strategy, 'jwt') {
private static extractCookies(req: any): string | null {
if (req.cookies && 'access-token' in req.cookies) {
return req.cookies['access-token'];
}
else if (req.handshake && req.handshake.headers.cookie) {
return cookie.parse(req.handshake.headers.cookie)['access-token']
} else if (req.handshake && req.handshake.headers.cookie) {
return cookie.parse(req.handshake.headers.cookie)['access-token'];
}
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion server/src/auth/refresh.strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class RefreshTokenStrategy extends PassportStrategy(
}

validate(req: RequestType, payload: any) {
let refreshToken = req.cookies['refresh-token'];
const refreshToken = req.cookies['refresh-token'];
return { ...payload, refreshToken };
}

Expand Down
45 changes: 27 additions & 18 deletions server/src/common/notifications/notifications.controller.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,39 @@
import { Controller, HttpException, Sse, UseGuards, Get, Res } from '@nestjs/common';
import {
Controller,
HttpException,
Sse,
UseGuards,
Get,
Res,
} from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { AccessTokenGuard } from '../guards/accessToken.guard';
import { NotificationsService } from './notifications.service';
import { Observable } from 'rxjs';


import { Observable, fromEvent, map } from 'rxjs';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { NotificationEvent } from '@yacht/types';

@ApiTags('Notifications')
@ApiBearerAuth()
@UseGuards(AccessTokenGuard)
@Controller('notifications')
export class NotificationsController {
constructor(private readonly notificationsService: NotificationsService) { }
constructor(
private readonly notificationsService: NotificationsService,
private eventEmitter: EventEmitter2,
) {}

@Sse()
async streamNotifications(): Promise<Observable<any>> {
try {
return this.notificationsService.getStream()
} catch (err) {
// Error Handling
if (err.statusCode) {
throw new HttpException(err.message, err.statusCode);
} else {
throw new HttpException(err.message, 500);
}
}
@Sse()
async streamNotifications(): Promise<Observable<any>> {
try {
return fromEvent(this.eventEmitter, 'message');
} catch (err) {
// Error Handling
if (err.statusCode) {
throw new HttpException(err.message, err.statusCode);
} else {
throw new HttpException(err.message, 500);
}
}

}
}
12 changes: 11 additions & 1 deletion server/src/common/notifications/notifications.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,24 @@ import { NotificationsService } from './notifications.service';
import { LoggerModule } from '../logger/logger.module';
import { PassportModule } from '@nestjs/passport';
import { NotificationsController } from './notifications.controller';
import { EventEmitterModule } from '@nestjs/event-emitter';

@Global()
@Module({
imports: [
PassportModule.register({ defaultStrategy: 'jwt' }),
EventEmitterModule.forRoot({
wildcard: true,
delimiter: '.',
newListener: false,
removeListener: false,
maxListeners: 10,
verboseMemoryLeak: true,
ignoreErrors: false,
})
],
controllers: [NotificationsController],
providers: [NotificationsService],
exports: [NotificationsService],
})
export class NotificationsModule {}
export class NotificationsModule { }
25 changes: 12 additions & 13 deletions server/src/common/notifications/notifications.service.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
import { fromEvent, map } from 'rxjs';
import { Injectable } from "@nestjs/common"
import { fromEvent } from 'rxjs';
import { Injectable, Scope } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { NotificationEvent } from '@yacht/types'

@Injectable()
@Injectable({ scope: Scope.TRANSIENT })
export class NotificationsService {
constructor(private notifications: EventEmitter2) {
constructor(private eventEmitter: EventEmitter2) {
}
debug(message: string) {
if (process.env.DEBUG === '1') {
this.notifications.emit('message', { data: { message: message, level: 'debug', timeout: -1 } } as NotificationEvent)
this.eventEmitter.emit('message', { data: { message: message, level: 'debug', timeout: -1 } } as NotificationEvent)
}
}
info(message: string) {
this.notifications.emit('message', { data: { message: message, level: 'info', timeout: -1 } } as NotificationEvent)
this.eventEmitter.emit('message', { data: { message: message, level: 'info', timeout: -1 } } as NotificationEvent)
}
warn(message: string) {
this.notifications.emit('message', { data: { message: message, level: 'warn', timeout: -1 } } as NotificationEvent)
this.eventEmitter.emit('message', { data: { message: message, level: 'warn', timeout: -1 } } as NotificationEvent)
}
error(message: string) {
this.notifications.emit('message', { data: { message: message, level: 'error', timeout: -1 } } as NotificationEvent)
this.eventEmitter.emit('message', { data: { message: message, level: 'error', timeout: -1 } } as NotificationEvent)
}
success(message: string) {
this.notifications.emit('message', { data: { message: message, level: 'success', timeout: -1 } } as NotificationEvent)
}
getStream() {
return fromEvent(this.notifications, 'message')
this.eventEmitter.emit('message', { data: { message: message, level: 'success', timeout: -1 } } as NotificationEvent)
}
// getStream() {
// return fromEvent(this.eventEmitter, 'message')
// }
}
113 changes: 57 additions & 56 deletions server/src/config/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,29 @@ import * as _ from 'lodash';
import { YachtConfig } from '@yacht/types';
import { Logger } from '../common/logger/logger.service';

const defaultConfig: YachtConfig = {
base: {
name: 'Yacht',
servers: [
{
name: 'local',
options: {
socketPath: process.env.DOCKER_HOST ?? '/var/run/docker.sock',
},
},
],
auth: true,
theme: {
type: 'dark',
},
plugins: null,
sessionTimeout: 3600,
},
};

@Injectable()
export class ConfigService implements OnModuleInit {
onModuleInit() { }
onModuleInit() {}

public name = 'yacht';

Expand Down Expand Up @@ -86,17 +106,11 @@ export class ConfigService implements OnModuleInit {
public instanceId: string;

constructor(private logger: Logger) {

/**
* Check file/folder locations to see if they exist, if not create them
*/

const yachtConfig: YachtConfig = <YachtConfig>(
fs.existsSync(this.configPath) ? parse(fs.readFileSync(this.configPath).toString()) : () => {
fs.mkdirSync(path.dirname(this.configPath), { recursive: true });
fs.writeFileSync(this.configPath, '');
}
);
const yachtConfig: YachtConfig = this.getConfig();
this.logger.setContext(ConfigService.name);
this.parseConfig(yachtConfig);
}
Expand All @@ -105,7 +119,7 @@ export class ConfigService implements OnModuleInit {
* Loads the config from the config.json
*/
public parseConfig(yachtConfig: YachtConfig) {
this.yachtConfig = yachtConfig || {} as YachtConfig;
this.yachtConfig = yachtConfig || ({} as YachtConfig);

if (!Object(this.yachtConfig).hasOwnProperty('base')) {
this.yachtConfig['base'] = {} as YachtConfig['base'];
Expand Down Expand Up @@ -289,10 +303,10 @@ export class ConfigService implements OnModuleInit {

// check secrets path exists, if not create it
const secretsExist = fs.existsSync(this.secretPath);
fs.existsSync(this.secretPath) ? fs.writeJsonSync(this.secretPath, secrets) : (
fs.mkdirSync(path.dirname(this.secretPath), { recursive: true }),
fs.writeJsonSync(this.secretPath, secrets)
);
fs.existsSync(this.secretPath)
? fs.writeJsonSync(this.secretPath, secrets)
: (fs.mkdirSync(path.dirname(this.secretPath), { recursive: true }),
fs.writeJsonSync(this.secretPath, secrets));

return secrets;
}
Expand All @@ -306,52 +320,39 @@ export class ConfigService implements OnModuleInit {
.update(this.secrets.accessSecret)
.digest('hex');
}
public getStartupConfig(): YachtConfig {

private createConfig(): YachtConfig {
this.logger.setContext('StartupConfig');
this.logger.log('Getting startup config...');
const configPath = path.resolve('../config/config.yaml');
const defaultConfig: YachtConfig = {
base: {
name: 'Yacht',
servers: [
{
name: 'local',
options: {
socketPath: process.env.DOCKER_HOST ?? '/var/run/docker.sock',
},
},
],
auth: true,
theme: {
type: 'dark',
},
plugins: null,
sessionTimeout: 3600,
},
};
let config;
if (fs.existsSync(configPath)) {
try {
config = parse(fs.readFileSync(configPath, 'utf8'));
this.logger.log('Config Exists!');
} catch (e) {
this.logger.error(e);
}
} else {
try {
fs.mkdirSync(path.resolve('../config/storage/templates'), {
recursive: true,
});
fs.mkdirSync(path.resolve('../config/storage/.ssh'), {
recursive: true,
});
fs.writeFileSync(configPath, stringify(defaultConfig), { flag: 'w' });
this.logger.success('Config Created!');
} catch (e) {
this.logger.error(e);
}
this.logger.log('Creating startup config...');
try {
fs.pathExistsSync(path.dirname(this.configPath))
? null
: fs.mkdirSync(path.dirname(this.configPath));
fs.existsSync(this.configPath)
? null
: fs.writeFileSync(this.configPath, stringify(defaultConfig), {
flag: 'w',
});
fs.existsSync(path.dirname(this.configPath) + '/storage/templates')
? null
: fs.mkdirSync(path.dirname(this.configPath) + '/storage/templates', {
recursive: true,
});
fs.mkdirSync(path.dirname(this.configPath) + '/storage/.ssh', {
recursive: true,
});
} catch (e) {
this.logger.error(e);
}
return defaultConfig;
}

public getConfig(): YachtConfig {
this.logger.setContext('StartupConfig');
this.logger.log('Getting startup config...');
const config = fs.existsSync(this.configPath)
? parse(fs.readFileSync(this.configPath, 'utf-8'))
: this.createConfig();
return config;
}
}
Loading

0 comments on commit d22c32a

Please sign in to comment.