refactor: fix locales + add _site controller

scarlett
NGPixel 2 weeks ago
parent 2e9ef68a4d
commit f4707f31d9
No known key found for this signature in database

@ -16,12 +16,32 @@ async function routes (app, options) {
app.get('/:siteIdorHostname', {
schema: {
summary: 'Get site info',
tags: ['Sites']
tags: ['Sites'],
params: {
type: 'object',
properties: {
siteId: {
type: 'string',
description: 'Either a site ID, hostname or "current" to use the request hostname.',
oneOf: [
{ format: 'uuid' },
{ enum: ['current'] },
{ pattern: '^[a-f0-9]+$' }
]
}
},
required: ['siteIdorHostname']
},
}
}, async (req, reply) => {
const site = (uuidValidate(req.params.siteId))
? await WIKI.models.sites.getSiteById({ id: req.params.siteId })
: await WIKI.models.sites.getSiteByHostname({ hostname: req.params.siteId })
let site
if (req.params.siteId === 'current' && req.hostname) {
site = await WIKI.models.sites.getSiteByHostname({ hostname: req.hostname })
} else if (uuidValidate(req.params.siteId)) {
site = await WIKI.models.sites.getSiteById({ id: req.params.siteId })
} else {
site = await WIKI.models.sites.getSiteByHostname({ hostname: req.params.siteId })
}
return site
? {
...site.config,

@ -0,0 +1,55 @@
import { validate as uuidValidate } from 'uuid'
import { replyWithFile } from '../helpers/common.mjs'
import path from 'node:path'
/**
* _site Routes
*/
async function routes (app, options) {
const siteAssetsPath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, 'assets')
app.get('/:siteId/:resource', async (req, reply) => {
let site
if (req.params.siteId === 'current' && req.hostname) {
site = await WIKI.models.sites.getSiteByHostname({ hostname: req.hostname })
} else if (uuidValidate(req.params.siteId)) {
site = await WIKI.models.sites.getSiteById({ id: req.params.siteId })
} else {
site = await WIKI.models.sites.getSiteByHostname({ hostname: req.params.siteId })
}
if (!site) {
return reply.notFound('Site not found')
}
switch (req.params.resource) {
case 'logo': {
if (site.config.assets.logo) {
// TODO: Fetch from db if not in disk cache
return replyWithFile(reply, path.join(siteAssetsPath, `logo-${site.id}.${site.config.assets.logoExt}`))
} else {
return replyWithFile(reply, path.join(WIKI.ROOTPATH, 'assets/_assets/logo-wikijs.svg'))
}
}
case 'favicon': {
if (site.config.assets.favicon) {
// TODO: Fetch from db if not in disk cache
return replyWithFile(reply, path.join(siteAssetsPath, `favicon-${site.id}.${site.config.assets.faviconExt}`))
} else {
return replyWithFile(reply, path.join(WIKI.ROOTPATH, 'assets/_assets/logo-wikijs.svg'))
}
}
case 'loginbg': {
if (site.config.assets.loginBg) {
// TODO: Fetch from db if not in disk cache
return replyWithFile(reply, path.join(siteAssetsPath, `loginbg-${site.id}.jpg`))
} else {
return replyWithFile(reply, path.join(WIKI.ROOTPATH, 'assets/_assets/bg/login.jpg'))
}
}
default: {
return reply.badRequest('Invalid Site Resource')
}
}
})
}
export default routes

@ -1,5 +1,7 @@
import { isNil, isPlainObject, set, startCase, transform } from 'lodash-es'
import crypto from 'node:crypto'
import mime from 'mime'
import fs from 'node:fs'
/* eslint-disable promise/param-names */
export function createDeferred () {
@ -110,3 +112,9 @@ export function getDictNameFromLocale (locale) {
return WIKI.data.tsDictMappings[loc] ?? 'simple'
}
}
export function replyWithFile (reply, filePath) {
const stream = fs.createReadStream(filePath)
reply.header('Content-Type', mime.getType(filePath))
return reply.send(stream)
}

@ -393,6 +393,7 @@ async function initHTTPServer () {
// })
app.register(import('./api/index.mjs'), { prefix: '/_api' })
app.register(import('./controllers/site.mjs'), { prefix: '/_site' })
// ----------------------------------------
// Error handling

@ -29,6 +29,7 @@
"fastify-favicon": "5.0.0",
"lodash-es": "4.17.23",
"luxon": "3.7.2",
"mime": "4.1.0",
"nanoid": "5.1.6",
"node-cache": "5.1.2",
"pem-jwk": "2.0.0",
@ -1319,6 +1320,18 @@
"mime": "^3"
}
},
"node_modules/@fastify/send/node_modules/mime": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
"integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
"license": "MIT",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/@fastify/sensible": {
"version": "6.0.4",
"resolved": "https://registry.npmjs.org/@fastify/sensible/-/sensible-6.0.4.tgz",
@ -6045,15 +6058,18 @@
}
},
"node_modules/mime": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
"integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-4.1.0.tgz",
"integrity": "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==",
"funding": [
"https://github.com/sponsors/broofa"
],
"license": "MIT",
"bin": {
"mime": "cli.js"
"mime": "bin/cli.js"
},
"engines": {
"node": ">=10.0.0"
"node": ">=16"
}
},
"node_modules/mime-db": {

@ -58,6 +58,7 @@
"fastify-favicon": "5.0.0",
"lodash-es": "4.17.23",
"luxon": "3.7.2",
"mime": "4.1.0",
"nanoid": "5.1.6",
"node-cache": "5.1.2",
"pem-jwk": "2.0.0",

@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/_site/favicon" />
<link rel="icon" href="/_site/current/favicon" />
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">

@ -143,9 +143,8 @@ router.beforeEach(async (to, from) => {
// -> Locale
if (!commonStore.desiredLocale || !siteStore.locales.active.some(l => l.code === commonStore.desiredLocale)) {
commonStore.setLocale(siteStore.locales.primary)
} else {
applyLocale(commonStore.desiredLocale)
}
applyLocale(commonStore.desiredLocale)
// -> User Profile
if (userStore.authenticated && !userStore.profileLoaded) {

@ -983,7 +983,7 @@ async function finishSetupTFA () {
// MOUNTED
onMounted(async () => {
await fetchStrategies()
// await fetchStrategies()
})
</script>

@ -17,10 +17,10 @@ q-header.bg-header.text-white.site-header(
size='34px'
square
)
img(:src='`/_site/logo`')
img(:src='`/_site/current/logo`')
img(
v-else
:src='`/_site/logo`'
:src='`/_site/current/logo`'
style='height: 34px'
)
q-toolbar-title.text-h6(v-if='siteStore.logoText') {{siteStore.title}}

@ -2,12 +2,12 @@
.auth
.auth-content
.auth-logo
img(:src='`/_site/logo`' :alt='siteStore.title')
img(:src='`/_site/current/logo`' :alt='siteStore.title')
h2.auth-site-title(v-if='siteStore.logoText') {{ siteStore.title }}
p.text-grey-7 Login to continue
auth-login-panel
.auth-bg(aria-hidden="true")
img(:src='`/_site/loginbg`' alt='')
img(:src='`/_site/current/loginbg`' alt='')
</template>
<script setup>

@ -13,7 +13,7 @@ export const useCommonStore = defineStore('common', {
actions: {
async fetchLocaleStrings (locale) {
try {
return API_CLIENT.get(`locales/${locale}/strings`)
return API_CLIENT.get(`locales/${locale}/strings`).json()
} catch (err) {
console.warn(err)
throw err

Loading…
Cancel
Save