Browse Source

update: get lang from database

pull/1330/head
tetuaoro 8 months ago
parent
commit
25da7b11b3
  1. 10
      src/server/api/lang.get.ts
  2. 36
      src/server/databases/database.ts
  3. 70
      src/server/databases/entities/system.ts
  4. 14
      src/server/databases/entities/user.ts
  5. 66
      src/server/databases/providers/inmemory.ts
  6. 14
      src/server/databases/repositories/system.ts
  7. 24
      src/server/databases/repositories/user.ts
  8. 17
      src/server/utils/databases/InMemory.ts

10
src/server/api/lang.get.ts

@ -1,4 +1,10 @@
export default defineEventHandler((event) => {
export default defineEventHandler(async (event) => {
setHeader(event, 'Content-Type', 'application/json');
return LANG;
const system = await InMemory.getSystem();
if (system) {
const { lang } = system;
return lang;
}
return 'en';
});

36
src/server/databases/database.ts

@ -1,24 +1,14 @@
import type System from './entities/system';
import type User from './entities/user';
type Undefined = null | undefined | 0 | '';
export type Undefined = null | undefined | 0 | '';
/**
* `id` of T or T.
*
* @template T - The specific type that can be used in place of id string.
*/
type Identity<T> = string | T;
export { Undefined, Identity };
export type Identity<T> = string | T;
/**
* Abstract class for database operations.
* Provides methods to connect, disconnect, and interact with system and user data.
*
* **Note:** This class does not handle errors directly. Error handling should be implemented in the API methods
* that use this class. The methods here should not throw errors themselves but should rely on the consuming code
* to manage any exceptions or failures.
*/
export default abstract class DatabaseProvider {
/**
@ -29,26 +19,4 @@ export default abstract class DatabaseProvider {
* Disconnects from the database.
*/
abstract disconnect(): Promise<void>;
/**
* Retrieves system data from the database.
* @returns {Promise<System | Undefined>} The system data or null if not found.
*/
abstract getSystem(): Promise<System | Undefined>;
/**
* Retrieves a user by their ID or by User structure from the database.
* @param {Identity<User>} id - The ID of the user or a user.
* @returns {Promise<User | Undefined>} The user data or null if not found.
*/
abstract getUser(id: Identity<User>): Promise<User | Undefined>;
/**
* Creates or Updates a user in the database.
* @param {User} user - The user to be saved.
*
* **Note:** If the user already exists, this method will update their details.
* If the user does not exist, it will create a new user entry.
*/
abstract saveUser(user: User): Promise<void>;
}

70
src/server/databases/entities/system.ts

@ -1,10 +1,74 @@
import type { SessionConfig } from 'h3';
import type { Undefined } from '../database';
export type Lang = 'en' | 'ua' | 'ru' | 'tr' | 'no' | 'pl' | 'fr';
export type Version = string;
export type SessionTimeOut = number;
export type Port = number;
export type Address = string;
export type PassordHash = string;
export type Command = string;
export type Key = string;
export type IpTables = {
wgPreUp: Command;
wgPostUp: Command;
wgPreDown: Command;
wgPostDown: Command;
};
export type WGInterface = {
privateKey: Key;
publicKey: Key;
address: Address;
};
export type WGConfig = {
mtu: number;
persistentKeepalive: number;
rangeAddress: Address;
defaultDns: Array<Address>;
allowedIps: Array<Address>;
};
export enum ChartType {
None = 0,
Line = 1,
Area = 2,
Bar = 3,
}
export type TrafficStats = {
enabled: boolean;
type: ChartType;
};
export type Prometheus = {
enabled: boolean;
password?: PassordHash | Undefined;
};
/**
* Representing the WireGuard network configuration data structure of a computer interface system.
*/
type System = {
privateKey: string;
publicKey: string;
address: string;
interface: WGInterface;
release: Version;
port: number;
webuiHost: string;
// maxAge
sessionTimeout: SessionTimeOut;
lang: Lang;
userConfig: WGConfig;
wgPath: string;
wgDevice: string;
wgHost: Address;
wgPort: Port;
wgConfigPort: Port;
iptables: IpTables;
trafficStats: TrafficStats;
wgEnableExpiresTime: boolean;
prometheus: Prometheus;
sessionConfig: SessionConfig;
};
export default System;

14
src/server/databases/entities/user.ts

@ -1,3 +1,5 @@
import type { Address, Key, PassordHash } from './system';
export type ROLE = 'ADMIN';
/**
@ -6,13 +8,15 @@ export type ROLE = 'ADMIN';
type User = {
id: string;
roles: Array<ROLE>;
username: string;
password: PassordHash;
name: string;
address: string;
privateKey: string;
publicKey: string;
address: Address;
privateKey: Key;
publicKey: Key;
preSharedKey: string;
createdAt: string;
updatedAt: string;
createdAt: Date;
updatedAt: Date;
enabled: boolean;
};

66
src/server/databases/providers/inmemory.ts

@ -1,8 +1,16 @@
import DatabaseProvider, { type Identity } from '../database';
import type { SessionConfig } from 'h3';
import type { Identity } from '../database';
import type UserRepository from '../repositories/user';
import type SystemRepository from '../repositories/system';
import type System from '../entities/system';
import type User from '../entities/user';
import DatabaseProvider from '../database';
import { ChartType } from '../entities/system';
import debug from 'debug';
import packageJson from '@/package.json';
const INMDP_DEBUG = debug('InMemoryDP');
// Represent in-memory data structure
@ -12,15 +20,65 @@ type InMemoryData = {
};
// In-Memory Database Provider
export class InMemoryDP extends DatabaseProvider {
export default class InMemoryDP
extends DatabaseProvider
implements UserRepository, SystemRepository
{
private data: InMemoryData = { users: [] };
async connect() {
// No connection needed for in-memory
INMDP_DEBUG('Connection...');
const system: System = {
release: packageJson.release.version,
interface: {
privateKey: '',
publicKey: '',
address: '10.8.0.1',
},
port: 51821,
webuiHost: '0.0.0.0',
sessionTimeout: 3600, // 1 hour
lang: 'en',
userConfig: {
mtu: 1420,
persistentKeepalive: 0,
rangeAddress: '10.8.0.x',
defaultDns: ['1.1.1.1'],
allowedIps: ['0.0.0.0/0', '::/0'],
},
wgPath: '/etc/wireguard/',
wgDevice: 'wg0',
wgHost: '',
wgPort: 51820,
wgConfigPort: 51820,
iptables: {
wgPreUp: '',
wgPostUp: '',
wgPreDown: '',
wgPostDown: '',
},
trafficStats: {
enabled: false,
type: ChartType.None,
},
wgEnableExpiresTime: false,
prometheus: {
enabled: false,
password: null,
},
sessionConfig: {
password: '',
name: 'wg-easy',
cookie: undefined,
} satisfies SessionConfig,
};
this.data.system = system;
INMDP_DEBUG('Connection done');
}
async disconnect() {
// No disconnection needed for in-memory
// TODO
}
async getSystem() {

14
src/server/databases/repositories/system.ts

@ -0,0 +1,14 @@
import type { Undefined } from '../database';
import type System from '../entities/system';
/**
* Abstract class for system-related database operations.
* This class provides a method for retrieving system configuration data from the database.
*/
export default abstract class SystemRepository {
/**
* Retrieves system data from the database.
* @returns {Promise<System | Undefined>} The system data or null if not found.
*/
abstract getSystem(): Promise<System | Undefined>;
}

24
src/server/databases/repositories/user.ts

@ -0,0 +1,24 @@
import type User from '../entities/user';
import type { Identity, Undefined } from '../database';
/**
* Abstract class for user-related database operations.
* This class provides methods for retrieving and saving user data.
*/
export default abstract class UserRepository {
/**
* Retrieves a user by their ID or by User structure from the database.
* @param {Identity<User>} id - The ID of the user or a user.
* @returns {Promise<User | Undefined>} The user data or null if not found.
*/
abstract getUser(id: Identity<User>): Promise<User | Undefined>;
/**
* Creates or Updates a user in the database.
* @param {User} user - The user to be saved.
*
* **Note:** If the user already exists, this method will update their details.
* If the user does not exist, it will create a new user entry.
*/
abstract saveUser(user: User): Promise<void>;
}

17
src/server/utils/databases/InMemory.ts

@ -0,0 +1,17 @@
import InMemoryDP from '@/server/databases/providers/inmemory';
const provider = new InMemoryDP(); // TODO manage multiple providers
provider.connect().catch((err) => {
console.error(err);
provider
.disconnect()
.catch((err) => {
console.error(err);
})
.finally(() => {
process.exit(1);
});
});
export default provider;
Loading…
Cancel
Save