Browse Source

fix: review

pull/1330/head
tetuaoro 2 years ago
parent
commit
044f1a6e45
  1. 12
      src/localeDetector.ts
  2. 2
      src/server/api/account/new.post.ts
  3. 2
      src/server/api/lang.get.ts
  4. 13
      src/server/api/session.post.ts
  5. 9
      src/server/middleware/session.ts
  6. 6
      src/server/utils/session.ts
  7. 21
      src/services/database/inmemory.ts
  8. 6
      src/services/database/repositories/database.ts
  9. 0
      src/services/database/repositories/system/model.ts
  10. 6
      src/services/database/repositories/system/repository.ts
  11. 3
      src/services/database/repositories/types.ts
  12. 0
      src/services/database/repositories/user/model.ts
  13. 6
      src/services/database/repositories/user/repository.ts.ts

12
src/localeDetector.ts

@ -1,24 +1,18 @@
// https://i18n.nuxtjs.org/docs/guide/server-side-translations
// Detect based on query, cookie, header
export default defineI18nLocaleDetector((event, config) => {
// try to get locale from query
const query = tryQueryLocale(event, { lang: '' }); // disable locale default value with `lang` option
const query = tryQueryLocale(event, { lang: '' });
if (query) {
return query.toString();
}
// try to get locale from cookie
const cookie = tryCookieLocale(event, { lang: '', name: 'i18n_locale' }); // disable locale default value with `lang` option
const cookie = tryCookieLocale(event, { lang: '', name: 'i18n_locale' });
if (cookie) {
return cookie.toString();
}
// try to get locale from header (`accept-header`)
const header = tryHeaderLocale(event, { lang: '' }); // disable locale default value with `lang` option
const header = tryHeaderLocale(event, { lang: '' });
if (header) {
return header.toString();
}
// If the locale cannot be resolved up to this point, it is resolved with the value `defaultLocale` of the locale config passed to the function
return config.defaultLocale;
});

2
src/server/api/account/new.post.ts

@ -1,4 +1,4 @@
import { DatabaseError } from '~/repositories/database';
import { DatabaseError } from '~/services/database/repositories/database';
export default defineEventHandler(async (event) => {
setHeader(event, 'Content-Type', 'application/json');

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

@ -1,4 +1,4 @@
export default defineEventHandler(async (event) => {
export default defineEventHandler((event) => {
setHeader(event, 'Content-Type', 'application/json');
return Database.getLang();
});

13
src/server/api/session.post.ts

@ -24,16 +24,23 @@ export default defineEventHandler(async (event) => {
// TODO: timing againts timing attack
const conf: SessionConfig = SESSION_CONFIG;
const system = await Database.getSystem();
if (!system)
throw createError({
statusCode: 500,
statusMessage: 'Invalid',
});
const conf: SessionConfig = system.sessionConfig;
if (MAX_AGE && remember) {
conf.cookie = {
...(SESSION_CONFIG.cookie ?? {}),
...(system.sessionConfig.cookie ?? {}),
maxAge: MAX_AGE,
};
}
const session = await useSession(event, {
...SESSION_CONFIG,
...system.sessionConfig,
});
const data = await session.update({

9
src/server/middleware/session.ts

@ -11,7 +11,14 @@ export default defineEventHandler(async (event) => {
) {
return;
}
const session = await getSession(event, SESSION_CONFIG);
const system = await Database.getSystem();
if (!system)
throw createError({
statusCode: 500,
statusMessage: 'Invalid',
});
const session = await getSession(event, system.sessionConfig);
if (session.id && session.data.authenticated) {
return;
}

6
src/server/utils/session.ts

@ -4,6 +4,8 @@ export type WGSession = {
authenticated: boolean;
};
export function useWGSession(event: H3Event) {
return useSession<Partial<WGSession>>(event, SESSION_CONFIG);
export async function useWGSession(event: H3Event) {
const system = await Database.getSystem();
if (!system) throw new Error('Invalid');
return useSession<Partial<WGSession>>(event, system.sessionConfig);
}

21
src/services/database/inmemory.ts

@ -2,26 +2,25 @@ import debug from 'debug';
import packageJson from '@/package.json';
import crypto from 'node:crypto';
import DatabaseProvider, { DatabaseError } from '~/repositories/database';
import { ChartType, Lang } from '~/repositories/types';
import DatabaseProvider, { DatabaseError } from './repositories/database';
import { ChartType, Lang } from './repositories/types';
import type { SessionConfig } from 'h3';
import type { ID } from '~/repositories/types';
import type { System } from '~/repositories/system/model';
import type { User } from '~/repositories/user/model';
import type { ID } from './repositories/types';
import type { System } from './repositories/system/model';
import type { User } from './repositories/user/model';
import { hashPassword, isPasswordStrong } from '~/server/utils/password';
const DEBUG = debug('InMemoryDB');
// Represent in-memory data structure
type InMemoryData = {
system?: System;
users: Array<User>;
system: System | null;
users: User[];
};
// In-Memory Database Provider
export default class InMemory extends DatabaseProvider {
protected data: InMemoryData = { users: [] };
protected data: InMemoryData = { system: null, users: [] };
async connect() {
DEBUG('Connection...');
@ -69,7 +68,7 @@ export default class InMemory extends DatabaseProvider {
password: '',
name: 'wg-easy',
cookie: undefined,
} satisfies SessionConfig,
},
};
this.data.system = system;
@ -77,7 +76,7 @@ export default class InMemory extends DatabaseProvider {
}
async disconnect() {
this.data = { users: [] };
this.data = { system: null, users: [] };
}
async getSystem() {

6
src/repositories/database.ts → src/services/database/repositories/database.ts

@ -1,6 +1,6 @@
import type SystemRepository from './system/repository';
import type UserRepository from './user/repository.ts';
import type { Undefined, Lang, ID } from './types';
import type { Lang, ID } from './types';
import type { User } from './user/model';
import type { System } from './system/model';
@ -24,11 +24,11 @@ export default abstract class DatabaseProvider
*/
abstract disconnect(): Promise<void>;
abstract getSystem(): Promise<System | Undefined>;
abstract getSystem(): Promise<System | null>;
abstract getLang(): Promise<Lang>;
abstract getUsers(): Promise<Array<User>>;
abstract getUser(id: ID): Promise<User | Undefined>;
abstract getUser(id: ID): Promise<User | undefined>;
abstract newUserWithPassword(
username: string,
password: string

0
src/repositories/system/model.ts → src/services/database/repositories/system/model.ts

6
src/repositories/system/repository.ts → src/services/database/repositories/system/repository.ts

@ -1,4 +1,4 @@
import type { Lang, Undefined } from '../types';
import type { Lang } from '../types';
import type { System } from './model';
/**
@ -9,10 +9,10 @@ import type { System } from './model';
export default interface SystemRepository {
/**
* Retrieves the system configuration data from the database.
* @returns {Promise<System | Undefined>} A promise that resolves to the system data
* @returns {Promise<System | null>} A promise that resolves to the system data
* if found, or `undefined` if the system data is not available.
*/
getSystem(): Promise<System | Undefined>;
getSystem(): Promise<System | null>;
/**
* Retrieves the system's language setting.

3
src/repositories/types.ts → src/services/database/repositories/types.ts

@ -1,6 +1,5 @@
import type * as crypto from 'node:crypto';
export type Undefined = null | undefined | 0 | '';
export enum Lang {
/* english */
EN = 'en',
@ -46,5 +45,5 @@ export type TrafficStats = {
};
export type Prometheus = {
enabled: boolean;
password?: HashPassword | Undefined;
password: HashPassword | null;
};

0
src/repositories/user/model.ts → src/services/database/repositories/user/model.ts

6
src/repositories/user/repository.ts.ts → src/services/database/repositories/user/repository.ts.ts

@ -1,4 +1,4 @@
import type { ID, Undefined } from '../types';
import type { ID } from '../types';
import type { User } from './model';
/**
@ -15,10 +15,10 @@ export default interface UserRepository {
/**
* Retrieves a user by their ID or User object from the database.
* @param {ID} id - The ID of the user or a User object.
* @returns {Promise<User | Undefined>} A promise that resolves to the user data
* @returns {Promise<User | undefined>} A promise that resolves to the user data
* if found, or `undefined` if the user is not available.
*/
getUser(id: ID): Promise<User | Undefined>;
getUser(id: ID): Promise<User | undefined>;
newUserWithPassword(username: string, password: string): Promise<void>;
Loading…
Cancel
Save