mirror of https://github.com/wg-easy/wg-easy
11 changed files with 233 additions and 68 deletions
@ -41,6 +41,9 @@ importers: |
|||||
js-sha256: |
js-sha256: |
||||
specifier: ^0.11.0 |
specifier: ^0.11.0 |
||||
version: 0.11.0 |
version: 0.11.0 |
||||
|
lowdb: |
||||
|
specifier: ^7.0.1 |
||||
|
version: 7.0.1 |
||||
nuxt: |
nuxt: |
||||
specifier: ^3.12.4 |
specifier: ^3.12.4 |
||||
version: 3.12.4(@parcel/[email protected])(@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])([email protected])([email protected])([email protected](@types/[email protected])([email protected]))([email protected]([email protected])) |
version: 3.12.4(@parcel/[email protected])(@types/[email protected])([email protected])([email protected])([email protected])([email protected])([email protected])([email protected])([email protected])([email protected](@types/[email protected])([email protected]))([email protected]([email protected])) |
||||
@ -2868,6 +2871,10 @@ packages: |
|||||
[email protected]: |
[email protected]: |
||||
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} |
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} |
||||
|
|
||||
|
[email protected]: |
||||
|
resolution: {integrity: sha512-neJAj8GwF0e8EpycYIDFqEPcx9Qz4GUho20jWFR7YiFeXzF1YMLdxB36PypcTSPMA+4+LvgyMacYhlr18Zlymw==} |
||||
|
engines: {node: '>=18'} |
||||
|
|
||||
[email protected]: |
[email protected]: |
||||
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} |
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} |
||||
|
|
||||
@ -3841,6 +3848,10 @@ packages: |
|||||
[email protected]: |
[email protected]: |
||||
resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} |
resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} |
||||
|
|
||||
|
[email protected]: |
||||
|
resolution: {integrity: sha512-yhPIQXjrlt1xv7dyPQg2P17URmXbuM5pdGkpiMB3RenprfiBlvK415Lctfe0eshk90oA7/tNq7WEiMK8RSP39A==} |
||||
|
engines: {node: '>=18'} |
||||
|
|
||||
[email protected]: |
[email protected]: |
||||
resolution: {integrity: sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==} |
resolution: {integrity: sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==} |
||||
|
|
||||
@ -7582,6 +7593,10 @@ snapshots: |
|||||
|
|
||||
[email protected]: {} |
[email protected]: {} |
||||
|
|
||||
|
[email protected]: |
||||
|
dependencies: |
||||
|
steno: 4.0.2 |
||||
|
|
||||
[email protected]: {} |
[email protected]: {} |
||||
|
|
||||
[email protected]: |
[email protected]: |
||||
@ -8659,6 +8674,8 @@ snapshots: |
|||||
|
|
||||
[email protected]: {} |
[email protected]: {} |
||||
|
|
||||
|
[email protected]: {} |
||||
|
|
||||
[email protected]: |
[email protected]: |
||||
dependencies: |
dependencies: |
||||
fast-fifo: 1.3.2 |
fast-fifo: 1.3.2 |
||||
|
|||||
@ -0,0 +1,121 @@ |
|||||
|
import crypto from 'node:crypto'; |
||||
|
import debug from 'debug'; |
||||
|
import { join } from 'path'; |
||||
|
|
||||
|
import DatabaseProvider, { DatabaseError } from './repositories/database'; |
||||
|
import { hashPassword, isPasswordStrong } from '~/server/utils/password'; |
||||
|
import { JSONFilePreset } from 'lowdb/node'; |
||||
|
import { Lang } from './repositories/types'; |
||||
|
import SYSTEM from './repositories/system'; |
||||
|
|
||||
|
import type { User } from './repositories/user/model'; |
||||
|
import type { DBData } from './repositories/database'; |
||||
|
import type { ID } from './repositories/types'; |
||||
|
import type { Low } from 'lowdb'; |
||||
|
|
||||
|
const DEBUG = debug('LowDB'); |
||||
|
|
||||
|
export default class LowDB extends DatabaseProvider { |
||||
|
private _db!: Low<DBData>; |
||||
|
|
||||
|
private async __init() { |
||||
|
// TODO: assume path to db file
|
||||
|
const dbFilePath = join(WG_PATH, 'db.json'); |
||||
|
this._db = await JSONFilePreset(dbFilePath, this.data); |
||||
|
} |
||||
|
|
||||
|
async connect() { |
||||
|
try { |
||||
|
// load file db
|
||||
|
await this._db.read(); |
||||
|
DEBUG('Connection done'); |
||||
|
return; |
||||
|
} catch (error) { |
||||
|
DEBUG('Database does not exist : ', error); |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
await this.__init(); |
||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
|
} catch (error) { |
||||
|
throw new DatabaseError(DatabaseError.ERROR_INIT); |
||||
|
} |
||||
|
|
||||
|
this._db.update((data) => (data.system = SYSTEM)); |
||||
|
|
||||
|
DEBUG('Connection done'); |
||||
|
} |
||||
|
|
||||
|
async disconnect() { |
||||
|
DEBUG('Diconnect done'); |
||||
|
} |
||||
|
|
||||
|
async getSystem() { |
||||
|
DEBUG('Get System'); |
||||
|
return this._db.data.system; |
||||
|
} |
||||
|
|
||||
|
async getLang() { |
||||
|
return this._db.data.system?.lang || Lang.EN; |
||||
|
} |
||||
|
|
||||
|
async getUsers() { |
||||
|
return this._db.data.users; |
||||
|
} |
||||
|
|
||||
|
async getUser(id: ID) { |
||||
|
DEBUG('Get User'); |
||||
|
return this._db.data.users.find((user) => user.id === id); |
||||
|
} |
||||
|
|
||||
|
async newUserWithPassword(username: string, password: string) { |
||||
|
DEBUG('New User'); |
||||
|
|
||||
|
if (username.length < 8) { |
||||
|
throw new DatabaseError(DatabaseError.ERROR_USERNAME_REQ); |
||||
|
} |
||||
|
|
||||
|
if (!isPasswordStrong(password)) { |
||||
|
throw new DatabaseError(DatabaseError.ERROR_PASSWORD_REQ); |
||||
|
} |
||||
|
|
||||
|
const isUserExist = this._db.data.users.find( |
||||
|
(user) => user.username === username |
||||
|
); |
||||
|
if (isUserExist) { |
||||
|
throw new DatabaseError(DatabaseError.ERROR_USER_EXIST); |
||||
|
} |
||||
|
|
||||
|
const now = new Date(); |
||||
|
const isUserEmpty = this._db.data.users.length === 0; |
||||
|
|
||||
|
const newUser: User = { |
||||
|
id: crypto.randomUUID(), |
||||
|
password: hashPassword(password), |
||||
|
username, |
||||
|
role: isUserEmpty ? 'ADMIN' : 'CLIENT', |
||||
|
enabled: true, |
||||
|
createdAt: now, |
||||
|
updatedAt: now, |
||||
|
}; |
||||
|
|
||||
|
this._db.update((data) => data.users.push(newUser)); |
||||
|
} |
||||
|
|
||||
|
async updateUser(user: User) { |
||||
|
let _user = await this.getUser(user.id); |
||||
|
if (_user) { |
||||
|
DEBUG('Update User'); |
||||
|
_user = user; |
||||
|
this._db.write(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async deleteUser(id: ID) { |
||||
|
DEBUG('Delete User'); |
||||
|
const idx = this._db.data.users.findIndex((user) => user.id === id); |
||||
|
if (idx !== -1) { |
||||
|
this._db.update((data) => data.users.splice(idx, 1)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,55 @@ |
|||||
|
import packageJson from '@/package.json'; |
||||
|
|
||||
|
import { ChartType, Lang } from '../types'; |
||||
|
|
||||
|
import type { System } from './model'; |
||||
|
|
||||
|
const DEFAULT_SYSTEM_MODEL: System = { |
||||
|
release: packageJson.release.version, |
||||
|
interface: { |
||||
|
privateKey: '', |
||||
|
publicKey: '', |
||||
|
address: '10.8.0.1', |
||||
|
}, |
||||
|
port: PORT ? Number(PORT) : 51821, |
||||
|
webuiHost: '0.0.0.0', |
||||
|
sessionTimeout: 3600, // 1 hour
|
||||
|
lang: Lang.EN, |
||||
|
userConfig: { |
||||
|
mtu: 1420, |
||||
|
persistentKeepalive: 0, |
||||
|
// TODO: assume handle CIDR to compute next ip in WireGuard
|
||||
|
rangeAddress: '10.8.0.0/24', |
||||
|
defaultDns: ['1.1.1.1'], |
||||
|
allowedIps: ['0.0.0.0/0', '::/0'], |
||||
|
}, |
||||
|
wgPath: WG_PATH, |
||||
|
wgDevice: 'wg0', |
||||
|
wgHost: WG_HOST || '', |
||||
|
wgPort: 51820, |
||||
|
wgConfigPort: 51820, |
||||
|
iptables: { |
||||
|
wgPreUp: '', |
||||
|
wgPostUp: '', |
||||
|
wgPreDown: '', |
||||
|
wgPostDown: '', |
||||
|
}, |
||||
|
trafficStats: { |
||||
|
enabled: false, |
||||
|
type: ChartType.None, |
||||
|
}, |
||||
|
wgEnableExpiresTime: false, |
||||
|
wgEnableOneTimeLinks: false, |
||||
|
wgEnableSortClients: false, |
||||
|
prometheus: { |
||||
|
enabled: false, |
||||
|
password: null, |
||||
|
}, |
||||
|
sessionConfig: { |
||||
|
password: getRandomHex(256), |
||||
|
name: 'wg-easy', |
||||
|
cookie: undefined, |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
export default DEFAULT_SYSTEM_MODEL; |
||||
Loading…
Reference in new issue