update: icon store

This commit is contained in:
maix0 2025-06-14 03:16:48 +02:00 committed by Maieul BOYER
parent b1243d7346
commit aa96d79e47
8 changed files with 235 additions and 64 deletions

View file

@ -10,11 +10,14 @@
"license": "ISC",
"dependencies": {
"@fastify/autoload": "^6.3.1",
"@fastify/formbody": "^8.0.2",
"@fastify/multipart": "^9.0.3",
"@fastify/sensible": "^6.0.0",
"@fastify/static": "^8.2.0",
"fastify": "^5.0.0",
"fastify-cli": "^7.4.0",
"fastify-plugin": "^5.0.0",
"fastify-raw-body": "^5.0.0",
"sharp": "^0.34.2"
},
"devDependencies": {
@ -112,6 +115,12 @@
],
"license": "MIT"
},
"node_modules/@fastify/busboy": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-3.1.1.tgz",
"integrity": "sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw==",
"license": "MIT"
},
"node_modules/@fastify/deepmerge": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@fastify/deepmerge/-/deepmerge-2.0.2.tgz",
@ -163,6 +172,26 @@
"fast-json-stringify": "^6.0.0"
}
},
"node_modules/@fastify/formbody": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@fastify/formbody/-/formbody-8.0.2.tgz",
"integrity": "sha512-84v5J2KrkXzjgBpYnaNRPqwgMsmY7ZDjuj0YVuMR3NXCJRCgKEZy/taSP1wUYGn0onfxJpLyRGDLa+NMaDJtnA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"license": "MIT",
"dependencies": {
"fast-querystring": "^1.1.2",
"fastify-plugin": "^5.0.0"
}
},
"node_modules/@fastify/forwarded": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@fastify/forwarded/-/forwarded-3.0.0.tgz",
@ -188,6 +217,45 @@
"dequal": "^2.0.3"
}
},
"node_modules/@fastify/multipart": {
"version": "9.0.3",
"resolved": "https://registry.npmjs.org/@fastify/multipart/-/multipart-9.0.3.tgz",
"integrity": "sha512-pJogxQCrT12/6I5Fh6jr3narwcymA0pv4B0jbC7c6Bl9wnrxomEUnV0d26w6gUls7gSXmhG8JGRMmHFIPsxt1g==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"license": "MIT",
"dependencies": {
"@fastify/busboy": "^3.0.0",
"@fastify/deepmerge": "^2.0.0",
"@fastify/error": "^4.0.0",
"fastify-plugin": "^5.0.0",
"secure-json-parse": "^3.0.0"
}
},
"node_modules/@fastify/multipart/node_modules/secure-json-parse": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-3.0.2.tgz",
"integrity": "sha512-H6nS2o8bWfpFEV6U38sOSjS7bTbdgbCGU9wEM6W14P5H0QOsz94KCusifV44GpHDTu2nqZbuDNhTzu+mjDSw1w==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/fastify"
},
{
"type": "opencollective",
"url": "https://opencollective.com/fastify"
}
],
"license": "BSD-3-Clause"
},
"node_modules/@fastify/proxy-addr": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@fastify/proxy-addr/-/proxy-addr-5.0.0.tgz",
@ -1020,6 +1088,15 @@
"balanced-match": "^1.0.0"
}
},
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/c8": {
"version": "10.1.3",
"resolved": "https://registry.npmjs.org/c8/-/c8-10.1.3.tgz",
@ -1552,6 +1629,29 @@
"integrity": "sha512-HCxs+YnRaWzCl+cWRYFnHmeRFyR5GVnJTAaCJQiYzQSDwK9MgJdyAsuL3nh0EWRCYMgQ5MeziymvmAhUHYHDUQ==",
"license": "MIT"
},
"node_modules/fastify-raw-body": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/fastify-raw-body/-/fastify-raw-body-5.0.0.tgz",
"integrity": "sha512-2qfoaQ3BQDhZ1gtbkKZd6n0kKxJISJGM6u/skD9ljdWItAscjXrtZ1lnjr7PavmXX9j4EyCPmBDiIsLn07d5vA==",
"license": "MIT",
"dependencies": {
"fastify-plugin": "^5.0.0",
"raw-body": "^3.0.0",
"secure-json-parse": "^2.4.0"
},
"engines": {
"node": ">= 10"
},
"funding": {
"url": "https://github.com/Eomm/fastify-raw-body?sponsor=1"
}
},
"node_modules/fastify-raw-body/node_modules/secure-json-parse": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz",
"integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==",
"license": "BSD-3-Clause"
},
"node_modules/fastify-tsconfig": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/fastify-tsconfig/-/fastify-tsconfig-3.0.0.tgz",
@ -1721,6 +1821,18 @@
"node": ">= 0.8"
}
},
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
@ -2343,6 +2455,21 @@
"integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==",
"license": "MIT"
},
"node_modules/raw-body": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
"integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
"license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.6.3",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@ -2490,6 +2617,12 @@
"node": ">=10"
}
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
},
"node_modules/secure-json-parse": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.0.0.tgz",
@ -2929,6 +3062,15 @@
"dev": true,
"license": "MIT"
},
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",

View file

@ -20,11 +20,14 @@
"license": "ISC",
"dependencies": {
"@fastify/autoload": "^6.3.1",
"@fastify/formbody": "^8.0.2",
"@fastify/multipart": "^9.0.3",
"@fastify/sensible": "^6.0.0",
"@fastify/static": "^8.2.0",
"fastify": "^5.0.0",
"fastify-cli": "^7.4.0",
"fastify-plugin": "^5.0.0",
"fastify-raw-body": "^5.0.0",
"sharp": "^0.34.2"
},
"devDependencies": {

View file

@ -2,6 +2,10 @@ import * as path from 'node:path'
import AutoLoad, { AutoloadPluginOptions } from '@fastify/autoload'
import { FastifyPluginAsync } from 'fastify'
import { fileURLToPath } from 'node:url'
import fastifyFormBody from '@fastify/formbody'
import fastifyMultipart from '@fastify/multipart'
import { mkdir } from 'node:fs/promises'
import fp from 'fastify-plugin'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
@ -14,12 +18,32 @@ export type AppOptions = {
const options: AppOptions = {
}
// When using .decorate you have to specify added properties for Typescript
declare module 'fastify' {
export interface FastifyInstance {
image_store: string;
}
}
const app: FastifyPluginAsync<AppOptions> = async (
fastify,
opts
): Promise<void> => {
// Place here your custom code!
void fastify.register(fastifyFormBody, {})
void fastify.register(fastifyMultipart, {})
// The use of fastify-plugin is required to be able
// to export the decorators to the outer scope
void fastify.register(fp(async (fastify) => {
const image_store = process.env.USER_ICONS_STORE ?? "/tmp/icons";
fastify.decorate('image_store', image_store)
await mkdir(fastify.image_store, { recursive: true })
}))
// Do not touch the following lines
// This loads all plugins defined in plugins
@ -40,6 +64,7 @@ const app: FastifyPluginAsync<AppOptions> = async (
options: opts,
forceESM: true
})
}
export default app

View file

@ -1,20 +0,0 @@
import fp from 'fastify-plugin'
export interface SupportPluginOptions {
// Specify Support plugin options here
}
// The use of fastify-plugin is required to be able
// to export the decorators to the outer scope
export default fp<SupportPluginOptions>(async (fastify, opts) => {
fastify.decorate('someSupport', function () {
return 'hugs'
})
})
// When using .decorate you have to specify added properties for Typescript
declare module 'fastify' {
export interface FastifyInstance {
someSupport(): string;
}
}

View file

@ -0,0 +1,16 @@
import { FastifyPluginAsync } from 'fastify'
import fastifyStatic from '@fastify/static'
const example: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
fastify.register(fastifyStatic, {
root: fastify.getDecorator<string>('image_store')!,
prefix: '/',
})
fastify.get('/:userid', async (req, res) => {
const filename = (req.params as any)['userid'] + '.png';
await res.sendFile(filename)
})
}
export default example

View file

@ -1,17 +0,0 @@
import { fastifyStatic } from '@fastify/static'
import process from 'node:process'
import { FastifyPluginAsync } from 'fastify'
const example: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
console.log("HELLO ????")
fastify.post('/set/:userid', async function(request, reply) {
console.log(request.params)
})
fastify.register(fastifyStatic, {
root: process.env.USER_ICONS_STORE ?? "/tmp/icons",
prefix: '/get',
})
}
export default example

View file

@ -1,9 +1,8 @@
import { FastifyPluginAsync } from 'fastify'
const root: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
fastify.get('/', async function (request, reply) {
return { root: true }
})
const example: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
fastify.get('*', async (req, res) => res.code(403))
}
export default root
export default example

View file

@ -0,0 +1,23 @@
import { FastifyPluginAsync } from 'fastify'
import { join } from 'node:path'
import { open } from 'node:fs/promises'
import fastifyRawBody from 'fastify-raw-body'
const example: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
// fastify.register(DeadgeInternalApi, {})
await fastify.register(fastifyRawBody, { encoding: false });
fastify.post('/:userid', { config: { rawBody: true, encoding: false } }, async function(request, reply) {
const userid: string | undefined = (request.params as any)['userid'];
if (userid === undefined) {
return await reply.code(403);
}
const image_store: string = fastify.getDecorator('image_store')
const image_path = join(image_store, userid + ".png")
let image_file = await open(image_path, "w", 0o666)
await image_file.write(request.rawBody as Buffer);
await image_file.close()
})
}
export default example