add preference db
This commit is contained in:
parent
f26c71c429
commit
9cbfdf92fb
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"vsicons.presets.angular": true
|
||||
}
|
|
@ -1,14 +1,70 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { validate } from 'class-validator';
|
||||
import { SysPreferences } from 'picsur-shared/dist/dto/syspreferences.dto';
|
||||
import { AsyncFailable, Fail } from 'picsur-shared/dist/types';
|
||||
import { Repository } from 'typeorm';
|
||||
import { SysPreferenceDefaults } from '../../models/dto/syspreference.dto';
|
||||
import { ESysPreferenceBackend } from '../../models/entities/syspreference.entity';
|
||||
|
||||
@Injectable()
|
||||
export class SysPreferenceService {
|
||||
private readonly logger = new Logger('SysPreferenceService');
|
||||
|
||||
constructor(
|
||||
@InjectRepository(ESysPreferenceBackend)
|
||||
private usersRepository: Repository<ESysPreferenceBackend>,
|
||||
private sysPreferenceRepository: Repository<ESysPreferenceBackend>,
|
||||
) {}
|
||||
|
||||
public async setPreference(
|
||||
key: SysPreferences,
|
||||
value: string,
|
||||
): AsyncFailable<ESysPreferenceBackend> {
|
||||
let sysPreference = new ESysPreferenceBackend();
|
||||
sysPreference.key = key;
|
||||
sysPreference.value = value;
|
||||
|
||||
const errors = await validate(sysPreference);
|
||||
if (errors.length > 0) {
|
||||
this.logger.warn(errors);
|
||||
return Fail('Invalid preference');
|
||||
}
|
||||
|
||||
try {
|
||||
sysPreference = await this.sysPreferenceRepository.save(sysPreference, {
|
||||
reload: true,
|
||||
});
|
||||
} catch (e: any) {
|
||||
this.logger.warn(e);
|
||||
return Fail('Could not save preference');
|
||||
}
|
||||
|
||||
return sysPreference;
|
||||
}
|
||||
|
||||
public async getPreference(
|
||||
key: SysPreferences,
|
||||
): AsyncFailable<ESysPreferenceBackend> {
|
||||
let sysPreference: ESysPreferenceBackend | undefined;
|
||||
try {
|
||||
sysPreference = await this.sysPreferenceRepository.findOne({
|
||||
key,
|
||||
});
|
||||
} catch (e: any) {
|
||||
this.logger.warn(e);
|
||||
return Fail('Could not get preference');
|
||||
}
|
||||
|
||||
if (!sysPreference) {
|
||||
return this.saveDefault(key);
|
||||
}
|
||||
|
||||
return sysPreference;
|
||||
}
|
||||
|
||||
private async saveDefault(
|
||||
key: SysPreferences,
|
||||
): AsyncFailable<ESysPreferenceBackend> {
|
||||
return this.setPreference(key, SysPreferenceDefaults[key]());
|
||||
}
|
||||
}
|
||||
|
|
12
backend/src/models/dto/syspreference.dto.ts
Normal file
12
backend/src/models/dto/syspreference.dto.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { SysPreferences } from 'picsur-shared/dist/dto/syspreferences.dto';
|
||||
import { generateRandomString } from 'picsur-shared/dist/util/random';
|
||||
import Config from '../../env';
|
||||
|
||||
export const SysPreferenceDefaults: {
|
||||
[key in SysPreferences]: () => string;
|
||||
} = {
|
||||
jwt_secret: () => {
|
||||
if (Config.jwt.secret !== 'CHANGE_ME') return Config.jwt.secret;
|
||||
return generateRandomString(32);
|
||||
},
|
||||
};
|
|
@ -1,3 +1,4 @@
|
|||
import { SysPreferences } from 'picsur-shared/dist/dto/syspreferences.dto';
|
||||
import { ESysPreference } from 'picsur-shared/dist/entities/syspreference.entity';
|
||||
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
|
||||
|
||||
|
@ -7,7 +8,7 @@ export class ESysPreferenceBackend extends ESysPreference {
|
|||
override id?: number;
|
||||
|
||||
@Column()
|
||||
override name: string;
|
||||
override key: SysPreferences;
|
||||
|
||||
@Column()
|
||||
override value: string;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const tuple = <T extends string[]>(...args: T): T => args;
|
||||
import tuple from '../types/tuple';
|
||||
|
||||
// Config
|
||||
|
||||
|
|
8
shared/src/dto/syspreferences.dto.ts
Normal file
8
shared/src/dto/syspreferences.dto.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { generateRandomString } from '../util/random';
|
||||
import tuple from '../types/tuple';
|
||||
import { randomBytes } from 'crypto';
|
||||
|
||||
const SysPreferencesTuple = tuple('jwt_secret');
|
||||
|
||||
export const SysPreferences: string[] = SysPreferencesTuple;
|
||||
export type SysPreferences = typeof SysPreferencesTuple[number];
|
|
@ -1,11 +1,13 @@
|
|||
import { IsNotEmpty, IsOptional } from 'class-validator';
|
||||
import { IsEnum, IsNotEmpty, IsOptional } from 'class-validator';
|
||||
import { SysPreferences } from '../dto/syspreferences.dto';
|
||||
|
||||
export class ESysPreference {
|
||||
@IsOptional()
|
||||
id?: number;
|
||||
|
||||
@IsNotEmpty()
|
||||
name: string;
|
||||
@IsEnum(SysPreferences)
|
||||
key: SysPreferences;
|
||||
|
||||
@IsNotEmpty()
|
||||
value: string;
|
||||
|
|
3
shared/src/types/tuple.ts
Normal file
3
shared/src/types/tuple.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
const tuple = <T extends string[]>(...args: T): T => args;
|
||||
|
||||
export default tuple;
|
12
shared/src/util/random.ts
Normal file
12
shared/src/util/random.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import crypto from 'crypto';
|
||||
|
||||
const randomCharacters =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
|
||||
export function generateRandomString(length: number): string {
|
||||
let out = '';
|
||||
for (let i = 0; i < length; i++) {
|
||||
out += randomCharacters[crypto.randomInt(0, randomCharacters.length - 1)];
|
||||
}
|
||||
return out;
|
||||
}
|
Loading…
Reference in a new issue