From 4eb9dabb63ff8aaea45fe5516040a123e8884dc1 Mon Sep 17 00:00:00 2001 From: NGPixel Date: Sat, 3 Jan 2026 03:03:15 -0500 Subject: [PATCH] refactor: update docker images to Node 24 and fix promisify calls --- .nvmrc | 2 +- dev/build/Dockerfile | 6 +++--- dev/containers/Dockerfile | 2 +- dev/containers/docker-compose.yml | 2 +- package.json | 4 ++-- server/core/auth.js | 8 +++---- server/core/db.js | 6 +++--- server/core/system.js | 21 +++++++++---------- server/graph/resolvers/system.js | 7 ++++--- server/modules/search/algolia/engine.js | 6 ++---- server/modules/search/aws/engine.js | 6 ++---- server/modules/search/azure/engine.js | 6 ++---- server/modules/search/elasticsearch/engine.js | 8 +++---- server/modules/search/postgres/engine.js | 6 ++---- server/modules/storage/azure/storage.js | 8 +++---- server/modules/storage/disk/common.js | 6 ++---- server/modules/storage/disk/storage.js | 8 +++---- server/modules/storage/git/storage.js | 10 ++++----- server/modules/storage/s3/common.js | 10 ++++----- server/modules/storage/sftp/storage.js | 8 +++---- server/setup.js | 7 ++++--- 21 files changed, 63 insertions(+), 84 deletions(-) diff --git a/.nvmrc b/.nvmrc index 860cc500..821e3957 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v18.17.1 +v24.12.0 diff --git a/dev/build/Dockerfile b/dev/build/Dockerfile index fa95ac99..072fad81 100644 --- a/dev/build/Dockerfile +++ b/dev/build/Dockerfile @@ -1,7 +1,7 @@ # ==================== # --- Build Assets --- # ==================== -FROM node:20-alpine AS assets +FROM node:24-alpine AS assets RUN apk add yarn g++ make cmake python3 --no-cache @@ -25,7 +25,7 @@ RUN yarn patch-package # =============== # --- Release --- # =============== -FROM node:20-alpine +FROM node:24-alpine LABEL maintainer="requarks.io" RUN apk add bash curl git openssh gnupg sqlite --no-cache && \ @@ -53,4 +53,4 @@ EXPOSE 3443 # HEALTHCHECK --interval=30s --timeout=30s --start-period=30s --retries=3 CMD curl -f http://localhost:3000/healthz -CMD ["node", "server"] +CMD ["node", "--no-deprecation", "server"] diff --git a/dev/containers/Dockerfile b/dev/containers/Dockerfile index 5d404880..148edc6d 100644 --- a/dev/containers/Dockerfile +++ b/dev/containers/Dockerfile @@ -1,7 +1,7 @@ # -- DEV DOCKERFILE -- # -- DO NOT USE IN PRODUCTION! -- -FROM node:18 +FROM node:24 LABEL maintainer "requarks.io" RUN apt-get update && \ diff --git a/dev/containers/docker-compose.yml b/dev/containers/docker-compose.yml index 147d81ae..9fe1fa61 100644 --- a/dev/containers/docker-compose.yml +++ b/dev/containers/docker-compose.yml @@ -5,7 +5,7 @@ version: "3" services: db: container_name: wiki-db - image: postgres:15-alpine + image: postgres:17-alpine environment: POSTGRES_DB: wiki POSTGRES_PASSWORD: wikijsrocks diff --git a/package.json b/package.json index 51ba5b58..ed7d73e8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "wiki", "version": "2.0.0", - "releaseDate": "2019-01-01T01:01:01.000Z", + "releaseDate": "2026-01-01T01:01:01.000Z", "description": "A modern, lightweight and powerful wiki app built on NodeJS, Git and Markdown", "main": "wiki.js", "dev": true, @@ -34,7 +34,7 @@ }, "homepage": "https://github.com/Requarks/wiki#readme", "engines": { - "node": ">=10.12" + "node": ">=20" }, "dependencies": { "@azure/storage-blob": "12.12.0", diff --git a/server/core/auth.js b/server/core/auth.js index 91ef2101..6eb06b08 100644 --- a/server/core/auth.js +++ b/server/core/auth.js @@ -4,9 +4,9 @@ const _ = require('lodash') const jwt = require('jsonwebtoken') const ms = require('ms') const { DateTime } = require('luxon') -const Promise = require('bluebird') -const crypto = Promise.promisifyAll(require('crypto')) +const crypto = require('crypto') const pem2jwk = require('pem-jwk').pem2jwk +const randomBytesAsync = require('util').promisify(crypto.randomBytes) const securityHelper = require('../helpers/security') @@ -82,7 +82,7 @@ module.exports = { const strategy = require(`../modules/authentication/${stg.strategyKey}/authentication.js`) stg.config.callbackURL = `${WIKI.config.host}/login/${stg.key}/callback` - stg.config.key = stg.key; + stg.config.key = stg.key strategy.init(passport, stg.config) strategy.config = stg.config @@ -366,7 +366,7 @@ module.exports = { async regenerateCertificates () { WIKI.logger.info('Regenerating certificates...') - _.set(WIKI.config, 'sessionSecret', (await crypto.randomBytesAsync(32)).toString('hex')) + _.set(WIKI.config, 'sessionSecret', (await randomBytesAsync(32)).toString('hex')) const certs = crypto.generateKeyPairSync('rsa', { modulusLength: 2048, publicKeyEncoding: { diff --git a/server/core/db.js b/server/core/db.js index 3ce2e8bf..f6a9d708 100644 --- a/server/core/db.js +++ b/server/core/db.js @@ -93,9 +93,9 @@ module.exports = { // Prune host and port if socketPath is configured if (WIKI.config.db.socketPath) { - const { host, port, ...prunedConfig} = dbConfig - dbConfig = prunedConfig - dbConfig.socketPath = WIKI.config.db.socketPath.toString() + const { host, port, ...prunedConfig } = dbConfig + dbConfig = prunedConfig + dbConfig.socketPath = WIKI.config.db.socketPath.toString() } // Fix mysql boolean handling... diff --git a/server/core/system.js b/server/core/system.js index 5d606fc7..e3fbf1dd 100644 --- a/server/core/system.js +++ b/server/core/system.js @@ -4,8 +4,7 @@ const Promise = require('bluebird') const fs = require('fs-extra') const path = require('path') const zlib = require('zlib') -const stream = require('stream') -const pipeline = Promise.promisify(stream.pipeline) +const { pipeline, Readable, Transform } = require('stream') /* global WIKI */ @@ -121,7 +120,7 @@ module.exports = { await pipeline( WIKI.models.knex.select('filename', 'folderId', 'data').from('assets').join('assetData', 'assets.id', '=', 'assetData.id').stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (asset, enc, cb) => { const filename = (asset.folderId && asset.folderId > 0) ? `${_.get(assetFolders, asset.folderId)}/${asset.filename}` : asset.filename @@ -150,7 +149,7 @@ module.exports = { const commentsProgressMultiplier = progressMultiplier / Math.ceil(commentsCount / 50) WIKI.logger.info(`Found ${commentsCount} comments to export. Streaming to file...`) - const rs = stream.Readable({ objectMode: true }) + const rs = Readable({ objectMode: true }) rs._read = () => {} const fetchCommentsBatch = async (offset) => { @@ -177,7 +176,7 @@ module.exports = { let marker = 0 await pipeline( rs, - new stream.Transform({ + new Transform({ objectMode: true, transform (chunk, encoding, callback) { marker++ @@ -225,7 +224,7 @@ module.exports = { const pagesProgressMultiplier = progressMultiplier / Math.ceil(pagesCount / 10) WIKI.logger.info(`Found ${pagesCount} pages history to export. Streaming to file...`) - const rs = stream.Readable({ objectMode: true }) + const rs = Readable({ objectMode: true }) rs._read = () => {} const fetchPagesBatch = async (offset) => { @@ -255,7 +254,7 @@ module.exports = { let marker = 0 await pipeline( rs, - new stream.Transform({ + new Transform({ objectMode: true, transform (chunk, encoding, callback) { marker++ @@ -307,7 +306,7 @@ module.exports = { const pagesProgressMultiplier = progressMultiplier / Math.ceil(pagesCount / 10) WIKI.logger.info(`Found ${pagesCount} pages to export. Streaming to file...`) - const rs = stream.Readable({ objectMode: true }) + const rs = Readable({ objectMode: true }) rs._read = () => {} const fetchPagesBatch = async (offset) => { @@ -337,7 +336,7 @@ module.exports = { let marker = 0 await pipeline( rs, - new stream.Transform({ + new Transform({ objectMode: true, transform (chunk, encoding, callback) { marker++ @@ -400,7 +399,7 @@ module.exports = { const usersProgressMultiplier = progressMultiplier / Math.ceil(usersCount / 50) WIKI.logger.info(`Found ${usersCount} users to export. Streaming to file...`) - const rs = stream.Readable({ objectMode: true }) + const rs = Readable({ objectMode: true }) rs._read = () => {} const fetchUsersBatch = async (offset) => { @@ -427,7 +426,7 @@ module.exports = { let marker = 0 await pipeline( rs, - new stream.Transform({ + new Transform({ objectMode: true, transform (chunk, encoding, callback) { marker++ diff --git a/server/graph/resolvers/system.js b/server/graph/resolvers/system.js index 51e57637..d28ab04c 100644 --- a/server/graph/resolvers/system.js +++ b/server/graph/resolvers/system.js @@ -1,6 +1,5 @@ const _ = require('lodash') -const Promise = require('bluebird') -const getos = Promise.promisify(require('getos')) +const getos = require('getos') const os = require('os') const filesize = require('filesize') const path = require('path') @@ -11,6 +10,8 @@ const request = require('request-promise') const crypto = require('crypto') const nanoid = require('nanoid/non-secure').customAlphabet('1234567890abcdef', 10) +const getosAsync = require('util').promisify(getos) + /* global WIKI */ const dbTypes = { @@ -371,7 +372,7 @@ module.exports = { async operatingSystem () { let osLabel = `${os.type()} (${os.platform()}) ${os.release()} ${os.arch()}` if (os.platform() === 'linux') { - const osInfo = await getos() + const osInfo = await getosAsync() osLabel = `${os.type()} - ${osInfo.dist} (${osInfo.codename || os.platform()}) ${osInfo.release || os.release()} ${os.arch()}` } return osLabel diff --git a/server/modules/search/algolia/engine.js b/server/modules/search/algolia/engine.js index e13b3c4a..ead51a8f 100644 --- a/server/modules/search/algolia/engine.js +++ b/server/modules/search/algolia/engine.js @@ -1,8 +1,6 @@ const _ = require('lodash') const algoliasearch = require('algoliasearch') -const stream = require('stream') -const Promise = require('bluebird') -const pipeline = Promise.promisify(stream.pipeline) +const { pipeline, Transform } = require('stream') /* global WIKI */ @@ -192,7 +190,7 @@ module.exports = { isPublished: true, isPrivate: false }).stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (chunk, enc, cb) => processDocument(cb, chunk), flush: async (cb) => processDocument(cb) diff --git a/server/modules/search/aws/engine.js b/server/modules/search/aws/engine.js index e703e5c3..b1ec23ae 100644 --- a/server/modules/search/aws/engine.js +++ b/server/modules/search/aws/engine.js @@ -1,8 +1,6 @@ const _ = require('lodash') const AWS = require('aws-sdk') -const stream = require('stream') -const Promise = require('bluebird') -const pipeline = Promise.promisify(stream.pipeline) +const { pipeline, Transform } = require('stream') /* global WIKI */ @@ -353,7 +351,7 @@ module.exports = { isPublished: true, isPrivate: false }).stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (chunk, enc, cb) => processDocument(cb, chunk), flush: async (cb) => processDocument(cb) diff --git a/server/modules/search/azure/engine.js b/server/modules/search/azure/engine.js index 7dffcd07..8d254702 100644 --- a/server/modules/search/azure/engine.js +++ b/server/modules/search/azure/engine.js @@ -1,9 +1,7 @@ const _ = require('lodash') const { SearchService, QueryType } = require('azure-search-client') const request = require('request-promise') -const stream = require('stream') -const Promise = require('bluebird') -const pipeline = Promise.promisify(stream.pipeline) +const { pipeline, Transform } = require('stream') /* global WIKI */ @@ -215,7 +213,7 @@ module.exports = { isPublished: true, isPrivate: false }).stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: (chunk, enc, cb) => { cb(null, { diff --git a/server/modules/search/elasticsearch/engine.js b/server/modules/search/elasticsearch/engine.js index 0daf0037..6d72ee5f 100644 --- a/server/modules/search/elasticsearch/engine.js +++ b/server/modules/search/elasticsearch/engine.js @@ -1,8 +1,6 @@ const _ = require('lodash') -const stream = require('stream') -const Promise = require('bluebird') const fs = require('fs') -const pipeline = Promise.promisify(stream.pipeline) +const { pipeline, Transform } = require('stream') /* global WIKI */ @@ -135,7 +133,7 @@ module.exports = { } catch (err) { WIKI.logger.error(`(SEARCH/ELASTICSEARCH) Create Index Error: `, _.get(err, 'meta.body.error', err)) } - } + } } catch (err) { WIKI.logger.error(`(SEARCH/ELASTICSEARCH) Index Check Error: `, _.get(err, 'meta.body.error', err)) } @@ -392,7 +390,7 @@ module.exports = { isPublished: true, isPrivate: false }).stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (chunk, enc, cb) => processDocument(cb, chunk), flush: async (cb) => processDocument(cb) diff --git a/server/modules/search/postgres/engine.js b/server/modules/search/postgres/engine.js index 33204b84..397afdd6 100644 --- a/server/modules/search/postgres/engine.js +++ b/server/modules/search/postgres/engine.js @@ -1,7 +1,5 @@ const tsquery = require('pg-tsquery')() -const stream = require('stream') -const Promise = require('bluebird') -const pipeline = Promise.promisify(stream.pipeline) +const { pipeline, Transform } = require('stream') /* global WIKI */ @@ -166,7 +164,7 @@ module.exports = { isPublished: true, isPrivate: false }).stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (page, enc, cb) => { const content = WIKI.models.pages.cleanHTML(page.render) diff --git a/server/modules/storage/azure/storage.js b/server/modules/storage/azure/storage.js index f7320146..9ad955e3 100644 --- a/server/modules/storage/azure/storage.js +++ b/server/modules/storage/azure/storage.js @@ -1,7 +1,5 @@ const { BlobServiceClient, StorageSharedKeyCredential } = require('@azure/storage-blob') -const stream = require('stream') -const Promise = require('bluebird') -const pipeline = Promise.promisify(stream.pipeline) +const { pipeline, Transform } = require('stream') const pageHelper = require('../../../helpers/page.js') const _ = require('lodash') @@ -129,7 +127,7 @@ module.exports = { WIKI.models.knex.column('path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt', 'createdAt').select().from('pages').where({ isPrivate: false }).stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (page, enc, cb) => { const filePath = getFilePath(page, 'path') @@ -147,7 +145,7 @@ module.exports = { await pipeline( WIKI.models.knex.column('filename', 'folderId', 'data').select().from('assets').join('assetData', 'assets.id', '=', 'assetData.id').stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (asset, enc, cb) => { const filename = (asset.folderId && asset.folderId > 0) ? `${_.get(assetFolders, asset.folderId)}/${asset.filename}` : asset.filename diff --git a/server/modules/storage/disk/common.js b/server/modules/storage/disk/common.js index 9ed0b986..38dd5b89 100644 --- a/server/modules/storage/disk/common.js +++ b/server/modules/storage/disk/common.js @@ -1,8 +1,6 @@ const fs = require('fs-extra') const path = require('path') -const stream = require('stream') -const Promise = require('bluebird') -const pipeline = Promise.promisify(stream.pipeline) +const { pipeline, Transform } = require('stream') const klaw = require('klaw') const mime = require('mime-types').lookup const _ = require('lodash') @@ -22,7 +20,7 @@ module.exports = { return !_.includes(f, '.git') } }), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (file, enc, cb) => { const relPath = file.path.substr(fullPath.length + 1) diff --git a/server/modules/storage/disk/storage.js b/server/modules/storage/disk/storage.js index 8e4e4661..c5006988 100644 --- a/server/modules/storage/disk/storage.js +++ b/server/modules/storage/disk/storage.js @@ -2,10 +2,8 @@ const fs = require('fs-extra') const path = require('path') const tar = require('tar-fs') const zlib = require('zlib') -const stream = require('stream') const _ = require('lodash') -const Promise = require('bluebird') -const pipeline = Promise.promisify(stream.pipeline) +const { pipeline, Transform } = require('stream') const moment = require('moment') const pageHelper = require('../../../helpers/page') @@ -130,7 +128,7 @@ module.exports = { WIKI.models.knex.column('id', 'path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt', 'createdAt', 'editorKey').select().from('pages').where({ isPrivate: false }).stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (page, enc, cb) => { const pageObject = await WIKI.models.pages.query().findById(page.id) @@ -153,7 +151,7 @@ module.exports = { await pipeline( WIKI.models.knex.column('filename', 'folderId', 'data').select().from('assets').join('assetData', 'assets.id', '=', 'assetData.id').stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (asset, enc, cb) => { const filename = (asset.folderId && asset.folderId > 0) ? `${_.get(assetFolders, asset.folderId)}/${asset.filename}` : asset.filename diff --git a/server/modules/storage/git/storage.js b/server/modules/storage/git/storage.js index fcb197bc..5429d4c5 100644 --- a/server/modules/storage/git/storage.js +++ b/server/modules/storage/git/storage.js @@ -2,9 +2,7 @@ const path = require('path') const sgit = require('simple-git') const fs = require('fs-extra') const _ = require('lodash') -const stream = require('stream') -const Promise = require('bluebird') -const pipeline = Promise.promisify(stream.pipeline) +const { pipeline, Transform } = require('stream') const klaw = require('klaw') const os = require('os') @@ -441,7 +439,7 @@ module.exports = { return !_.includes(f, '.git') } }), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (file, enc, cb) => { const relPath = file.path.substr(this.repoPath.length + 1) @@ -476,7 +474,7 @@ module.exports = { WIKI.models.knex.column('id', 'path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt', 'createdAt', 'editorKey').select().from('pages').where({ isPrivate: false }).stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (page, enc, cb) => { const pageObject = await WIKI.models.pages.query().findById(page.id) @@ -500,7 +498,7 @@ module.exports = { await pipeline( WIKI.models.knex.column('filename', 'folderId', 'data').select().from('assets').join('assetData', 'assets.id', '=', 'assetData.id').stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (asset, enc, cb) => { const filename = (asset.folderId && asset.folderId > 0) ? `${_.get(assetFolders, asset.folderId)}/${asset.filename}` : asset.filename diff --git a/server/modules/storage/s3/common.js b/server/modules/storage/s3/common.js index fa1bc5dc..b436a665 100644 --- a/server/modules/storage/s3/common.js +++ b/server/modules/storage/s3/common.js @@ -1,7 +1,5 @@ const S3 = require('aws-sdk/clients/s3') -const stream = require('stream') -const Promise = require('bluebird') -const pipeline = Promise.promisify(stream.pipeline) +const { pipeline, Transform } = require('stream') const _ = require('lodash') const pageHelper = require('../../../helpers/page.js') @@ -22,7 +20,7 @@ const getFilePath = (page, pathKey) => { module.exports = class S3CompatibleStorage { constructor(storageName) { this.storageName = storageName - this.bucketName = "" + this.bucketName = '' } async activated() { // not used @@ -136,7 +134,7 @@ module.exports = class S3CompatibleStorage { WIKI.models.knex.column('path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt', 'createdAt').select().from('pages').where({ isPrivate: false }).stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (page, enc, cb) => { const filePath = getFilePath(page, 'path') @@ -152,7 +150,7 @@ module.exports = class S3CompatibleStorage { await pipeline( WIKI.models.knex.column('filename', 'folderId', 'data').select().from('assets').join('assetData', 'assets.id', '=', 'assetData.id').stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (asset, enc, cb) => { const filename = (asset.folderId && asset.folderId > 0) ? `${_.get(assetFolders, asset.folderId)}/${asset.filename}` : asset.filename diff --git a/server/modules/storage/sftp/storage.js b/server/modules/storage/sftp/storage.js index 49d5ae1d..07a9bbb4 100644 --- a/server/modules/storage/sftp/storage.js +++ b/server/modules/storage/sftp/storage.js @@ -1,9 +1,7 @@ const SSH2Promise = require('ssh2-promise') const _ = require('lodash') const path = require('path') -const stream = require('stream') -const Promise = require('bluebird') -const pipeline = Promise.promisify(stream.pipeline) +const { pipeline, Transform } = require('stream') const pageHelper = require('../../../helpers/page.js') /* global WIKI */ @@ -118,7 +116,7 @@ module.exports = { WIKI.models.knex.column('path', 'localeCode', 'title', 'description', 'contentType', 'content', 'isPublished', 'updatedAt', 'createdAt').select().from('pages').where({ isPrivate: false }).stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (page, enc, cb) => { const filePath = getFilePath(page, 'path') @@ -135,7 +133,7 @@ module.exports = { await pipeline( WIKI.models.knex.column('filename', 'folderId', 'data').select().from('assets').join('assetData', 'assets.id', '=', 'assetData.id').stream(), - new stream.Transform({ + new Transform({ objectMode: true, transform: async (asset, enc, cb) => { const filename = (asset.folderId && asset.folderId > 0) ? `${_.get(assetFolders, asset.folderId)}/${asset.filename}` : asset.filename diff --git a/server/setup.js b/server/setup.js index 44da308b..9763fc03 100644 --- a/server/setup.js +++ b/server/setup.js @@ -5,13 +5,14 @@ const compression = require('compression') const express = require('express') const favicon = require('serve-favicon') const http = require('http') -const Promise = require('bluebird') const fs = require('fs-extra') const _ = require('lodash') -const crypto = Promise.promisifyAll(require('crypto')) +const crypto = require('crypto') const pem2jwk = require('pem-jwk').pem2jwk const semver = require('semver') +const randomBytesAsync = require('util').promisify(crypto.randomBytes) + /* global WIKI */ module.exports = () => { @@ -119,7 +120,7 @@ module.exports = () => { analyticsService: '', analyticsId: '' }) - _.set(WIKI.config, 'sessionSecret', (await crypto.randomBytesAsync(32)).toString('hex')) + _.set(WIKI.config, 'sessionSecret', (await randomBytesAsync(32)).toString('hex')) _.set(WIKI.config, 'telemetry', { isEnabled: req.body.telemetry === true, clientId: uuid()