mirror of
https://github.com/CaramelFur/Picsur.git
synced 2025-11-14 15:45:49 +01:00
add preference db
This commit is contained in:
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 { 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 { Repository } from 'typeorm';
|
||||||
|
import { SysPreferenceDefaults } from '../../models/dto/syspreference.dto';
|
||||||
import { ESysPreferenceBackend } from '../../models/entities/syspreference.entity';
|
import { ESysPreferenceBackend } from '../../models/entities/syspreference.entity';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SysPreferenceService {
|
export class SysPreferenceService {
|
||||||
|
private readonly logger = new Logger('SysPreferenceService');
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@InjectRepository(ESysPreferenceBackend)
|
@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 { ESysPreference } from 'picsur-shared/dist/entities/syspreference.entity';
|
||||||
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
|
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
|
||||||
|
|
||||||
@@ -7,7 +8,7 @@ export class ESysPreferenceBackend extends ESysPreference {
|
|||||||
override id?: number;
|
override id?: number;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
override name: string;
|
override key: SysPreferences;
|
||||||
|
|
||||||
@Column()
|
@Column()
|
||||||
override value: string;
|
override value: string;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const tuple = <T extends string[]>(...args: T): T => args;
|
import tuple from '../types/tuple';
|
||||||
|
|
||||||
// Config
|
// 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 {
|
export class ESysPreference {
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
id?: number;
|
id?: number;
|
||||||
|
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
name: string;
|
@IsEnum(SysPreferences)
|
||||||
|
key: SysPreferences;
|
||||||
|
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
value: string;
|
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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user