mirror of https://github.com/requarks/wiki
parent
dc78af9156
commit
68e6a2787a
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"$schema": "./node_modules/oxfmt/configuration_schema.json",
|
"$schema": "./backend/node_modules/oxfmt/configuration_schema.json",
|
||||||
"semi": false,
|
"semi": false,
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"trailingComma": "none",
|
"trailingComma": "none",
|
||||||
@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"eslint.enable": false,
|
"eslint.enable": false,
|
||||||
"editor.formatOnSave": false,
|
|
||||||
"editor.tabSize": 2,
|
"editor.tabSize": 2,
|
||||||
"i18n-ally.localesPaths": [
|
"i18n-ally.localesPaths": ["backend/locales"],
|
||||||
"backend/locales",
|
|
||||||
],
|
|
||||||
"i18n-ally.pathMatcher": "{locale}.json",
|
"i18n-ally.pathMatcher": "{locale}.json",
|
||||||
"i18n-ally.keystyle": "flat",
|
"i18n-ally.keystyle": "flat",
|
||||||
"i18n-ally.sortKeys": true,
|
"i18n-ally.sortKeys": true,
|
||||||
"i18n-ally.enabledFrameworks": [
|
"i18n-ally.enabledFrameworks": ["vue"],
|
||||||
"vue"
|
"[javascript]": {
|
||||||
]
|
"editor.defaultFormatter": "oxc.oxc-vscode",
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.formatOnSaveMode": "file"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,24 +1,74 @@
|
|||||||
|
import path from 'node:path'
|
||||||
|
import os from 'node:os'
|
||||||
|
import { DateTime } from 'luxon'
|
||||||
|
import { filesize } from 'filesize'
|
||||||
|
import { isNil } from 'es-toolkit/predicate'
|
||||||
|
import { gte, sql } from 'drizzle-orm'
|
||||||
|
import {
|
||||||
|
groups as groupsTable,
|
||||||
|
pages as pagesTable,
|
||||||
|
tags as tagsTable,
|
||||||
|
users as usersTable
|
||||||
|
} from '../db/schema.mjs'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* System API Routes
|
* System API Routes
|
||||||
*/
|
*/
|
||||||
async function routes (app, options) {
|
async function routes(app, options) {
|
||||||
app.get('/info', {
|
app.get(
|
||||||
|
'/info',
|
||||||
|
{
|
||||||
|
config: {
|
||||||
|
permissions: ['read:dashboard', 'manage:sites']
|
||||||
|
},
|
||||||
schema: {
|
schema: {
|
||||||
summary: 'System Info',
|
summary: 'System Info',
|
||||||
tags: ['System']
|
tags: ['System']
|
||||||
}
|
}
|
||||||
}, async (request, reply) => {
|
},
|
||||||
return { hello: 'world' }
|
async (request, reply) => {
|
||||||
})
|
return {
|
||||||
|
configFile: path.join(process.cwd(), 'config.yml'),
|
||||||
|
cpuCores: os.cpus().length,
|
||||||
|
currentVersion: WIKI.version,
|
||||||
|
dbHost: WIKI.config.db.host,
|
||||||
|
dbVersion: WIKI.dbManager.VERSION,
|
||||||
|
groupsTotal: await WIKI.db.$count(groupsTable),
|
||||||
|
hostname: os.hostname(),
|
||||||
|
httpPort: 0,
|
||||||
|
isMailConfigured: WIKI.config?.mail?.host?.length > 2,
|
||||||
|
isSchedulerHealthy: true,
|
||||||
|
latestVersion: WIKI.config.update.version,
|
||||||
|
latestVersionReleaseDate: DateTime.fromISO(WIKI.config.update.versionDate).toJSDate(),
|
||||||
|
loginsPastDay: await WIKI.db.$count(
|
||||||
|
usersTable,
|
||||||
|
gte(usersTable.lastLoginAt, sql`NOW() - INTERVAL '1 DAY'`)
|
||||||
|
),
|
||||||
|
nodeVersion: process.version.substring(1),
|
||||||
|
operatingSystem: `${os.type()} (${os.platform()}) ${os.release()} ${os.arch()}`,
|
||||||
|
pagesTotal: await WIKI.db.$count(pagesTable),
|
||||||
|
platform: os.platform(),
|
||||||
|
ramTotal: filesize(os.totalmem()),
|
||||||
|
tagsTotal: await WIKI.db.$count(tagsTable),
|
||||||
|
upgradeCapable: !isNil(process.env.UPGRADE_COMPANION),
|
||||||
|
usersTotal: await WIKI.db.$count(usersTable),
|
||||||
|
workingDirectory: process.cwd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
app.get('/flags', {
|
app.get(
|
||||||
|
'/flags',
|
||||||
|
{
|
||||||
schema: {
|
schema: {
|
||||||
summary: 'System Flags',
|
summary: 'System Flags',
|
||||||
tags: ['System']
|
tags: ['System']
|
||||||
}
|
}
|
||||||
}, async (request, reply) => {
|
},
|
||||||
return { hello: 'world' }
|
async (request, reply) => {
|
||||||
})
|
return WIKI.config.flags
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default routes
|
export default routes
|
||||||
|
|||||||
@ -1,51 +1,95 @@
|
|||||||
/**
|
/**
|
||||||
* Users API Routes
|
* Users API Routes
|
||||||
*/
|
*/
|
||||||
async function routes (app, options) {
|
async function routes(app, options) {
|
||||||
app.get('/', {
|
app.get(
|
||||||
|
'/',
|
||||||
|
{
|
||||||
schema: {
|
schema: {
|
||||||
summary: 'List all users',
|
summary: 'List all users',
|
||||||
tags: ['Users']
|
tags: ['Users']
|
||||||
}
|
}
|
||||||
}, async (request, reply) => {
|
},
|
||||||
|
async (request, reply) => {
|
||||||
return { hello: 'world' }
|
return { hello: 'world' }
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
app.get('/:userId', {
|
app.get(
|
||||||
|
'/whoami',
|
||||||
|
{
|
||||||
|
schema: {
|
||||||
|
summary: 'Get currently logged in user info',
|
||||||
|
tags: ['Users']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async (req, reply) => {
|
||||||
|
reply.preventCache()
|
||||||
|
if (req.session?.authenticated) {
|
||||||
|
return {
|
||||||
|
authenticated: true,
|
||||||
|
...req.session.user,
|
||||||
|
permissions: ['manage:system']
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
authenticated: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
app.get(
|
||||||
|
'/:userId',
|
||||||
|
{
|
||||||
schema: {
|
schema: {
|
||||||
summary: 'Get user info',
|
summary: 'Get user info',
|
||||||
tags: ['Users']
|
tags: ['Users']
|
||||||
}
|
}
|
||||||
}, async (request, reply) => {
|
},
|
||||||
|
async (request, reply) => {
|
||||||
return { hello: 'world' }
|
return { hello: 'world' }
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
app.post('/', {
|
app.post(
|
||||||
|
'/',
|
||||||
|
{
|
||||||
schema: {
|
schema: {
|
||||||
summary: 'Create a new user',
|
summary: 'Create a new user',
|
||||||
tags: ['Users']
|
tags: ['Users']
|
||||||
}
|
}
|
||||||
}, async (request, reply) => {
|
},
|
||||||
|
async (request, reply) => {
|
||||||
return { hello: 'world' }
|
return { hello: 'world' }
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
app.put('/:userId', {
|
app.put(
|
||||||
|
'/:userId',
|
||||||
|
{
|
||||||
schema: {
|
schema: {
|
||||||
summary: 'Update a user',
|
summary: 'Update a user',
|
||||||
tags: ['Users']
|
tags: ['Users']
|
||||||
}
|
}
|
||||||
}, async (request, reply) => {
|
},
|
||||||
|
async (request, reply) => {
|
||||||
return { hello: 'world' }
|
return { hello: 'world' }
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
app.delete('/:userId', {
|
app.delete(
|
||||||
|
'/:userId',
|
||||||
|
{
|
||||||
schema: {
|
schema: {
|
||||||
summary: 'Delete a user',
|
summary: 'Delete a user',
|
||||||
tags: ['Users']
|
tags: ['Users']
|
||||||
}
|
}
|
||||||
}, async (request, reply) => {
|
},
|
||||||
|
async (request, reply) => {
|
||||||
return { hello: 'world' }
|
return { hello: 'world' }
|
||||||
})
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default routes
|
export default routes
|
||||||
|
|||||||
@ -0,0 +1,85 @@
|
|||||||
|
import { eq, sql } from 'drizzle-orm'
|
||||||
|
import { sessions as sessionsTable } from '../db/schema.mjs'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sessions model
|
||||||
|
*/
|
||||||
|
class Sessions {
|
||||||
|
/**
|
||||||
|
* Fetch all sessions from a single user
|
||||||
|
*
|
||||||
|
* @param {String} userId User ID
|
||||||
|
* @returns Promise<Array> User Sessions
|
||||||
|
*/
|
||||||
|
async getByUser(userId) {
|
||||||
|
return WIKI.db.select().from(sessionsTable).where(eq(sessionsTable.userId, userId))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a single session by id
|
||||||
|
*
|
||||||
|
* @param {String} id Session ID
|
||||||
|
* @returns Promise<Object> Session data
|
||||||
|
*/
|
||||||
|
async get(id) {
|
||||||
|
const res = await WIKI.db.select().from(sessionsTable).where(eq(sessionsTable.id, id))
|
||||||
|
return res?.[0]?.data ?? null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set / Update a session
|
||||||
|
*
|
||||||
|
* @param {String} id Session ID
|
||||||
|
* @param {Object} data Session Data
|
||||||
|
*/
|
||||||
|
async set(id, data) {
|
||||||
|
await WIKI.db
|
||||||
|
.insert(sessionsTable)
|
||||||
|
.values([
|
||||||
|
{
|
||||||
|
id,
|
||||||
|
userId: data?.user?.id ?? null,
|
||||||
|
data
|
||||||
|
}
|
||||||
|
])
|
||||||
|
.onConflictDoUpdate({
|
||||||
|
target: sessionsTable.id,
|
||||||
|
set: {
|
||||||
|
data,
|
||||||
|
userId: data?.user?.id ?? null,
|
||||||
|
updatedAt: sql`now()`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a session
|
||||||
|
*
|
||||||
|
* @param {String} id Session ID
|
||||||
|
* @returns Promise<void>
|
||||||
|
*/
|
||||||
|
async destroy(id) {
|
||||||
|
return WIKI.db.delete(sessionsTable).where(eq(sessionsTable.id, id))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all sessions from all users
|
||||||
|
*
|
||||||
|
* @returns Promise<void>
|
||||||
|
*/
|
||||||
|
async clearAllSessions() {
|
||||||
|
return WIKI.db.delete(sessionsTable)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all sessions from a single user
|
||||||
|
*
|
||||||
|
* @param {String} userId User ID
|
||||||
|
* @returns Promise<void>
|
||||||
|
*/
|
||||||
|
async clearSessionsFromUser(userId) {
|
||||||
|
return WIKI.db.delete(sessionsTable).where(eq(sessionsTable.userId, userId))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sessions = new Sessions()
|
||||||
@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "./node_modules/oxfmt/configuration_schema.json",
|
|
||||||
"semi": false,
|
|
||||||
"singleQuote": true,
|
|
||||||
"trailingComma": "none",
|
|
||||||
"bracketSameLine": true,
|
|
||||||
"endOfLine": "lf",
|
|
||||||
"insertFinalNewline": true
|
|
||||||
}
|
|
||||||
Loading…
Reference in new issue