From f9bb12152240ebd03c896169ae993f0c86425181 Mon Sep 17 00:00:00 2001 From: Erik Michelson Date: Mon, 5 May 2025 18:13:58 +0200 Subject: [PATCH] fix: use nanoid instead of shortid shortid is deprecated and they recommend nanoid instead. We're not sure if this has to do with possible name collisions or enumerability, but to be sure and on the safe side, we're changing this. nanoid seems quite safe since it uses node's crypto module underneath. Signed-off-by: Erik Michelson --- lib/models/note.js | 6 +++--- lib/models/revision.js | 4 ++-- lib/models/temp.js | 4 ++-- lib/web/note/actions.js | 4 ++-- package.json | 2 +- public/docs/release-notes.md | 4 ++++ yarn.lock | 20 ++++++++++---------- 7 files changed, 24 insertions(+), 20 deletions(-) diff --git a/lib/models/note.js b/lib/models/note.js index 628eb2547..d565bcdae 100644 --- a/lib/models/note.js +++ b/lib/models/note.js @@ -7,7 +7,7 @@ const base64url = require('base64url') const md = require('markdown-it')() const metaMarked = require('@hedgedoc/meta-marked') const cheerio = require('cheerio') -const shortId = require('shortid') +const nanoid = require('nanoid') const Sequelize = require('sequelize') const async = require('async') const moment = require('moment') @@ -37,7 +37,7 @@ module.exports = function (sequelize, DataTypes) { type: DataTypes.STRING, unique: true, allowNull: false, - defaultValue: shortId.generate + defaultValue: () => nanoid.nanoid(10) }, alias: { type: DataTypes.STRING, @@ -297,7 +297,7 @@ module.exports = function (sequelize, DataTypes) { parseNoteIdByShortId: function (_callback) { // try to parse note id by shortId try { - if (shortId.isValid(noteId)) { + if (noteId && noteId.length === 10) { Note.findOne({ where: utils.isMySQL(sequelize) ? sequelize.where(sequelize.fn('BINARY', sequelize.col('shortid')), noteId) diff --git a/lib/models/revision.js b/lib/models/revision.js index 0a3cfa608..2f7399ff4 100644 --- a/lib/models/revision.js +++ b/lib/models/revision.js @@ -4,7 +4,7 @@ const Sequelize = require('sequelize') const async = require('async') const moment = require('moment') const childProcess = require('child_process') -const shortId = require('shortid') +const nanoid = require('nanoid') const path = require('path') const Op = Sequelize.Op @@ -44,7 +44,7 @@ function createDmpWorker () { function sendDmpWorker (data, callback) { if (!dmpWorker) dmpWorker = createDmpWorker() - const cacheKey = Date.now() + '_' + shortId.generate() + const cacheKey = Date.now() + '_' + nanoid.nanoid() dmpCallbackCache[cacheKey] = callback data = Object.assign(data, { cacheKey diff --git a/lib/models/temp.js b/lib/models/temp.js index dee6c573b..2800dcb48 100644 --- a/lib/models/temp.js +++ b/lib/models/temp.js @@ -1,13 +1,13 @@ 'use strict' // external modules -const shortId = require('shortid') +const nanoid = require('nanoid') module.exports = function (sequelize, DataTypes) { const Temp = sequelize.define('Temp', { id: { type: DataTypes.STRING, primaryKey: true, - defaultValue: shortId.generate + defaultValue: nanoid.nanoid, }, data: { type: DataTypes.TEXT diff --git a/lib/web/note/actions.js b/lib/web/note/actions.js index 3c10887d5..61eab0ee3 100644 --- a/lib/web/note/actions.js +++ b/lib/web/note/actions.js @@ -2,7 +2,7 @@ const models = require('../../models') const logger = require('../../logger') const config = require('../../config') const errors = require('../../errors') -const shortId = require('shortid') +const nanoid = require('nanoid') const moment = require('moment') const querystring = require('querystring') @@ -36,7 +36,7 @@ exports.createGist = function createGist (req, res, note) { client_id: config.github.clientID, redirect_uri: config.serverURL + '/auth/github/callback/' + models.Note.encodeNoteId(note.id) + '/gist', scope: 'gist', - state: shortId.generate() + state: nanoid.nanoid() } const query = querystring.stringify(data) res.redirect('https://github.com/login/oauth/authorize?' + query) diff --git a/package.json b/package.json index 1d4c0b136..2456bd8b4 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "moment": "2.30.1", "morgan": "1.10.0", "mysql2": "3.14.0", + "nanoid": "5.1.5", "node-fetch": "2.7.0", "passport": "patch:passport@npm%3A0.7.0#~/.yarn/patches/passport-npm-0.7.0-df02531736.patch", "passport-dropbox-oauth2": "1.1.0", @@ -95,7 +96,6 @@ "sanitize-filename": "1.6.3", "scrypt-kdf": "2.0.1", "sequelize": "5.22.5", - "shortid": "2.2.17", "socket.io": "2.5.1", "sqlite3": "5.1.7", "store": "2.0.12", diff --git a/public/docs/release-notes.md b/public/docs/release-notes.md index 13ae57213..6507bae28 100644 --- a/public/docs/release-notes.md +++ b/public/docs/release-notes.md @@ -2,6 +2,10 @@ ## 1.x.x UNRELEASED +### Enhancements + +- Switch from deprecated shortid to nanoid module, with 10 character long aliases in "public" links + ## 1.10.3 2025-04-09 ### Security fixes diff --git a/yarn.lock b/yarn.lock index e44372beb..f50499476 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1461,6 +1461,7 @@ __metadata: moment: "npm:2.30.1" morgan: "npm:1.10.0" mysql2: "npm:3.14.0" + nanoid: "npm:5.1.5" node-fetch: "npm:2.7.0" optimize-css-assets-webpack-plugin: "npm:6.0.1" passport: "patch:passport@npm%3A0.7.0#~/.yarn/patches/passport-npm-0.7.0-df02531736.patch" @@ -1491,7 +1492,6 @@ __metadata: scrypt-kdf: "npm:2.0.1" select2: "npm:3.5.2-browserify" sequelize: "npm:5.22.5" - shortid: "npm:2.2.17" socket.io: "npm:2.5.1" socket.io-client: "npm:2.5.0" spin.js: "npm:4.1.2" @@ -11233,6 +11233,15 @@ __metadata: languageName: node linkType: hard +"nanoid@npm:5.1.5": + version: 5.1.5 + resolution: "nanoid@npm:5.1.5" + bin: + nanoid: bin/nanoid.js + checksum: 10/6de2d006b51c983be385ef7ee285f7f2a57bd96f8c0ca881c4111461644bd81fafc2544f8e07cb834ca0f3e0f3f676c1fe78052183f008b0809efe6e273119f5 + languageName: node + linkType: hard + "nanoid@npm:^3.3.8": version: 3.3.11 resolution: "nanoid@npm:3.3.11" @@ -14963,15 +14972,6 @@ __metadata: languageName: node linkType: hard -"shortid@npm:2.2.17": - version: 2.2.17 - resolution: "shortid@npm:2.2.17" - dependencies: - nanoid: "npm:^3.3.8" - checksum: 10/5c85635e31c08f8c6824b1802a0abb4cd26b39a5c84498dacc91b865f9a860979b010420423e5a4c0abf966aedf197a664a610e813745a6df1497f1376a72350 - languageName: node - linkType: hard - "side-channel-list@npm:^1.0.0": version: 1.0.0 resolution: "side-channel-list@npm:1.0.0"