diff --git a/ghost/core/core/server/data/importer/import-manager.js b/ghost/core/core/server/data/importer/import-manager.js index 360c081af7..ce87eb4382 100644 --- a/ghost/core/core/server/data/importer/import-manager.js +++ b/ghost/core/core/server/data/importer/import-manager.js @@ -3,7 +3,7 @@ const fs = require('fs-extra'); const path = require('path'); const os = require('os'); const glob = require('glob'); -const uuid = require('uuid'); +const crypto = require('crypto'); const config = require('../../../shared/config'); const {extract} = require('@tryghost/zip'); const tpl = require('@tryghost/tpl'); @@ -220,7 +220,7 @@ class ImportManager { * @returns {Promise} full path to the extracted folder */ async extractZip(filePath) { - const tmpDir = path.join(os.tmpdir(), uuid.v4()); + const tmpDir = path.join(os.tmpdir(), crypto.randomUUID()); this.fileToDelete = tmpDir; try { diff --git a/ghost/core/core/server/data/importer/importers/data/PostsImporter.js b/ghost/core/core/server/data/importer/importers/data/PostsImporter.js index 5bd6ab3c84..3f66c832bc 100644 --- a/ghost/core/core/server/data/importer/importers/data/PostsImporter.js +++ b/ghost/core/core/server/data/importer/importers/data/PostsImporter.js @@ -1,6 +1,6 @@ const debug = require('@tryghost/debug')('importer:posts'); const _ = require('lodash'); -const uuid = require('uuid'); +const crypto = require('crypto'); const BaseImporter = require('./Base'); const mobiledocLib = require('../../../../lib/mobiledoc'); const validator = require('@tryghost/validator'); @@ -29,7 +29,7 @@ class PostsImporter extends BaseImporter { sanitizeAttributes() { _.each(this.dataToImport, (obj) => { if (!validator.isUUID(obj.uuid || '')) { - obj.uuid = uuid.v4(); + obj.uuid = crypto.randomUUID(); } // we used to have post.page=true/false diff --git a/ghost/core/core/server/data/migrations/versions/4.46/2022-04-13-12-58-fill-uuid-for-newsletters.js b/ghost/core/core/server/data/migrations/versions/4.46/2022-04-13-12-58-fill-uuid-for-newsletters.js index 27f0584597..3352abbce7 100644 --- a/ghost/core/core/server/data/migrations/versions/4.46/2022-04-13-12-58-fill-uuid-for-newsletters.js +++ b/ghost/core/core/server/data/migrations/versions/4.46/2022-04-13-12-58-fill-uuid-for-newsletters.js @@ -1,5 +1,5 @@ const logging = require('@tryghost/logging'); -const uuid = require('uuid'); +const crypto = require('crypto'); const {createTransactionalMigration} = require('../../utils'); module.exports = createTransactionalMigration( @@ -10,7 +10,7 @@ module.exports = createTransactionalMigration( // eslint-disable-next-line no-restricted-syntax for (const newsletter of newslettersWithoutUUID) { - await knex('newsletters').update('uuid', uuid.v4()).where('id', newsletter.id); + await knex('newsletters').update('uuid', crypto.randomUUID()).where('id', newsletter.id); } }, async function down() { diff --git a/ghost/core/core/server/data/migrations/versions/4.46/2022-04-13-13-00-add-default-newsletter.js b/ghost/core/core/server/data/migrations/versions/4.46/2022-04-13-13-00-add-default-newsletter.js index 8b6638e6db..1abe2a2c53 100644 --- a/ghost/core/core/server/data/migrations/versions/4.46/2022-04-13-13-00-add-default-newsletter.js +++ b/ghost/core/core/server/data/migrations/versions/4.46/2022-04-13-13-00-add-default-newsletter.js @@ -1,5 +1,5 @@ const ObjectId = require('bson-objectid').default; -const uuid = require('uuid'); +const crypto = require('crypto'); const logging = require('@tryghost/logging'); const startsWith = require('lodash/startsWith'); const {createTransactionalMigration} = require('../../utils'); @@ -9,7 +9,7 @@ module.exports = createTransactionalMigration( // This uses the default settings from core/server/data/schema/default-settings/default-settings.json const newsletter = { id: (new ObjectId()).toHexString(), - uuid: uuid.v4(), + uuid: crypto.randomUUID(), name: 'Ghost', description: '', slug: 'default-newsletter', diff --git a/ghost/core/core/server/models/email.js b/ghost/core/core/server/models/email.js index 61d188da7a..96f223d776 100644 --- a/ghost/core/core/server/models/email.js +++ b/ghost/core/core/server/models/email.js @@ -1,4 +1,4 @@ -const uuid = require('uuid'); +const crypto = require('crypto'); const ghostBookshelf = require('./base'); const Email = ghostBookshelf.Model.extend({ @@ -6,7 +6,7 @@ const Email = ghostBookshelf.Model.extend({ defaults: function defaults() { return { - uuid: uuid.v4(), + uuid: crypto.randomUUID(), status: 'pending', recipient_filter: 'status:-free', track_opens: false, diff --git a/ghost/core/core/server/models/member.js b/ghost/core/core/server/models/member.js index 5fe0456b2d..9138ddd37f 100644 --- a/ghost/core/core/server/models/member.js +++ b/ghost/core/core/server/models/member.js @@ -1,5 +1,5 @@ const ghostBookshelf = require('./base'); -const uuid = require('uuid'); +const crypto = require('crypto'); const _ = require('lodash'); const config = require('../../shared/config'); const {gravatar} = require('../lib/image'); @@ -10,8 +10,8 @@ const Member = ghostBookshelf.Model.extend({ defaults() { return { status: 'free', - uuid: uuid.v4(), - transient_id: uuid.v4(), + uuid: crypto.randomUUID(), + transient_id: crypto.randomUUID(), email_count: 0, email_opened_count: 0, enable_comment_notifications: true diff --git a/ghost/core/core/server/models/newsletter.js b/ghost/core/core/server/models/newsletter.js index 2e41447c60..a0c4c06f35 100644 --- a/ghost/core/core/server/models/newsletter.js +++ b/ghost/core/core/server/models/newsletter.js @@ -1,6 +1,6 @@ const ghostBookshelf = require('./base'); const ObjectID = require('bson-objectid').default; -const uuid = require('uuid'); +const crypto = require('crypto'); const urlUtils = require('../../shared/url-utils'); const Newsletter = ghostBookshelf.Model.extend({ @@ -8,7 +8,7 @@ const Newsletter = ghostBookshelf.Model.extend({ defaults: function defaults() { return { - uuid: uuid.v4(), + uuid: crypto.randomUUID(), sender_reply_to: 'newsletter', status: 'active', visibility: 'members', diff --git a/ghost/core/core/server/models/post.js b/ghost/core/core/server/models/post.js index c1313faa76..15a75c0b11 100644 --- a/ghost/core/core/server/models/post.js +++ b/ghost/core/core/server/models/post.js @@ -1,6 +1,6 @@ // # Post Model const _ = require('lodash'); -const uuid = require('uuid'); +const crypto = require('crypto'); const moment = require('moment'); const {sequence} = require('@tryghost/promise'); const tpl = require('@tryghost/tpl'); @@ -89,7 +89,7 @@ Post = ghostBookshelf.Model.extend({ } return { - uuid: uuid.v4(), + uuid: crypto.randomUUID(), status: 'draft', featured: false, type: 'post', diff --git a/ghost/core/core/server/models/settings.js b/ghost/core/core/server/models/settings.js index a355bd2809..7645565579 100644 --- a/ghost/core/core/server/models/settings.js +++ b/ghost/core/core/server/models/settings.js @@ -1,5 +1,4 @@ const _ = require('lodash'); -const uuid = require('uuid'); const crypto = require('crypto'); const keypair = require('keypair'); const ObjectID = require('bson-objectid').default; @@ -50,7 +49,7 @@ function parseDefaultSettings() { const defaultSettingsFlattened = {}; const dynamicDefault = { - db_hash: () => uuid.v4(), + db_hash: () => crypto.randomUUID(), public_hash: () => crypto.randomBytes(15).toString('hex'), admin_session_secret: () => crypto.randomBytes(32).toString('hex'), theme_session_secret: () => crypto.randomBytes(32).toString('hex'), diff --git a/ghost/core/core/server/web/parent/middleware/request-id.js b/ghost/core/core/server/web/parent/middleware/request-id.js index 1e537cb191..152b3b5092 100644 --- a/ghost/core/core/server/web/parent/middleware/request-id.js +++ b/ghost/core/core/server/web/parent/middleware/request-id.js @@ -1,4 +1,4 @@ -const uuid = require('uuid'); +const crypto = require('crypto'); /** * @TODO: move this middleware to Framework monorepo? @@ -8,7 +8,7 @@ const uuid = require('uuid'); * @param {import('express').NextFunction} next */ module.exports = function requestIdMw(req, res, next) { - const requestId = req.get('X-Request-ID') || uuid.v4(); + const requestId = req.get('X-Request-ID') || crypto.randomUUID(); // Set a value for internal use req.requestId = requestId; diff --git a/ghost/core/package.json b/ghost/core/package.json index d9c6a6fdae..00d726179f 100644 --- a/ghost/core/package.json +++ b/ghost/core/package.json @@ -220,7 +220,6 @@ "sanitize-html": "2.13.0", "semver": "7.6.3", "stoppable": "1.1.0", - "uuid": "9.0.1", "ws": "8.18.0", "xml": "1.0.1", "y-protocols": "1.0.6", diff --git a/ghost/core/test/e2e-api/admin/members-exporter.test.js b/ghost/core/test/e2e-api/admin/members-exporter.test.js index 84b81fb3f9..126d18a9bf 100644 --- a/ghost/core/test/e2e-api/admin/members-exporter.test.js +++ b/ghost/core/test/e2e-api/admin/members-exporter.test.js @@ -1,7 +1,7 @@ const {agentProvider, mockManager, fixtureManager, matchers} = require('../../utils/e2e-framework'); const {anyContentVersion, anyEtag, anyString, anyContentLength} = matchers; -const uuid = require('uuid'); +const crypto = require('crypto'); const should = require('should'); const Papa = require('papaparse'); const models = require('../../../core/server/models'); @@ -9,7 +9,7 @@ const moment = require('moment'); async function createMember(data) { const member = await models.Member.add({ - email: uuid.v4() + '@example.com', + email: crypto.randomUUID() + '@example.com', name: '', email_disabled: false, ...data diff --git a/ghost/core/test/regression/api/admin/db.test.js b/ghost/core/test/regression/api/admin/db.test.js index 611b700213..81a3dc66af 100644 --- a/ghost/core/test/regression/api/admin/db.test.js +++ b/ghost/core/test/regression/api/admin/db.test.js @@ -2,7 +2,7 @@ const path = require('path'); const _ = require('lodash'); const os = require('os'); const fs = require('fs-extra'); -const uuid = require('uuid'); +const crypto = require('crypto'); const should = require('should'); const supertest = require('supertest'); const sinon = require('sinon'); @@ -61,7 +61,7 @@ describe('DB API', function () { }); it('can export & import', function () { - const exportFolder = path.join(os.tmpdir(), uuid.v4()); + const exportFolder = path.join(os.tmpdir(), crypto.randomUUID()); const exportPath = path.join(exportFolder, 'export.json'); return request.put(localUtils.API.getApiQuery('settings/')) diff --git a/ghost/core/test/regression/api/admin/redirects.test.js b/ghost/core/test/regression/api/admin/redirects.test.js index ffbf70e0d8..7dc072f349 100644 --- a/ghost/core/test/regression/api/admin/redirects.test.js +++ b/ghost/core/test/regression/api/admin/redirects.test.js @@ -3,7 +3,7 @@ const supertest = require('supertest'); const fs = require('fs-extra'); const path = require('path'); const os = require('os'); -const uuid = require('uuid'); +const crypto = require('crypto'); const localUtils = require('./utils'); const config = require('../../../../core/shared/config'); @@ -23,7 +23,7 @@ describe('Redirects API', function () { // which is currently impossible with available test utils. // The test itself should be broken down into a unit test for the // Redirects service class. - const contentFolder = path.join(os.tmpdir(), uuid.v4(), 'ghost-test'); + const contentFolder = path.join(os.tmpdir(), crypto.randomUUID(), 'ghost-test'); fs.ensureDirSync(contentFolder); fs.ensureDirSync(path.join(contentFolder, 'data')); fs.writeFileSync(path.join(contentFolder, 'data', 'redirects.json'), JSON.stringify([])); diff --git a/ghost/core/test/utils/e2e-framework.js b/ghost/core/test/utils/e2e-framework.js index 1bc229df60..bcf727ae48 100644 --- a/ghost/core/test/utils/e2e-framework.js +++ b/ghost/core/test/utils/e2e-framework.js @@ -20,7 +20,7 @@ const {AsymmetricMatcher} = require('expect'); const fs = require('fs-extra'); const path = require('path'); const os = require('os'); -const uuid = require('uuid'); +const crypto = require('crypto'); const fixtureUtils = require('./fixture-utils'); const redirectsUtils = require('./redirects'); @@ -64,7 +64,7 @@ const startGhost = async (options = {}) => { * We never use the root content folder for testing! * We use a tmp folder. */ - const contentFolder = path.join(os.tmpdir(), uuid.v4(), 'ghost-test'); + const contentFolder = path.join(os.tmpdir(), crypto.randomUUID(), 'ghost-test'); await prepareContentFolder({contentFolder}); // NOTE: need to pass this config to the server instance diff --git a/ghost/core/test/utils/e2e-utils.js b/ghost/core/test/utils/e2e-utils.js index bd677076bd..a346094a6b 100644 --- a/ghost/core/test/utils/e2e-utils.js +++ b/ghost/core/test/utils/e2e-utils.js @@ -4,7 +4,7 @@ const _ = require('lodash'); const fs = require('fs-extra'); const path = require('path'); const os = require('os'); -const uuid = require('uuid'); +const crypto = require('crypto'); // Ghost Internals const boot = require('../../core/boot'); @@ -213,7 +213,7 @@ const startGhost = async (options) => { forceStart: false, copyThemes: false, copySettings: false, - contentFolder: path.join(os.tmpdir(), uuid.v4(), 'ghost-test'), + contentFolder: path.join(os.tmpdir(), crypto.randomUUID(), 'ghost-test'), subdir: false }, options); diff --git a/ghost/core/test/utils/fixture-utils.js b/ghost/core/test/utils/fixture-utils.js index 2077465bdb..6fd982f6e9 100644 --- a/ghost/core/test/utils/fixture-utils.js +++ b/ghost/core/test/utils/fixture-utils.js @@ -2,7 +2,7 @@ const _ = require('lodash'); const path = require('path'); const fs = require('fs-extra'); -const uuid = require('uuid'); +const crypto = require('crypto'); const ObjectId = require('bson-objectid').default; const KnexMigrator = require('knex-migrator'); const {sequence} = require('@tryghost/promise'); @@ -160,7 +160,7 @@ const fixtures = { let i; for (i = 0; i < max; i += 1) { - tagName = uuid.v4().split('-')[0]; + tagName = crypto.randomUUID().split('-')[0]; tags.push(DataGenerator.forKnex.createBasic({name: tagName, slug: tagName})); } diff --git a/ghost/core/test/utils/fixtures/data-generator.js b/ghost/core/test/utils/fixtures/data-generator.js index b1c5997acb..149ed421ad 100644 --- a/ghost/core/test/utils/fixtures/data-generator.js +++ b/ghost/core/test/utils/fixtures/data-generator.js @@ -1,5 +1,5 @@ const _ = require('lodash'); -const uuid = require('uuid'); +const crypto = require('crypto'); const ObjectId = require('bson-objectid').default; const moment = require('moment'); const constants = require('@tryghost/constants'); @@ -1037,7 +1037,7 @@ DataGenerator.forKnex = (function () { return _.defaults(newObj, { id: ObjectId().toHexString(), - uuid: uuid.v4(), + uuid: crypto.randomUUID(), title: 'title', status: 'published', feature_image: null, @@ -1107,7 +1107,7 @@ DataGenerator.forKnex = (function () { return _.defaults(newObj, { id: ObjectId().toHexString(), - uuid: uuid.v4(), + uuid: crypto.randomUUID(), secret: 'not_available', redirection_uri: 'http://localhost:9999', client_uri: 'http://localhost:9000', @@ -1156,7 +1156,7 @@ DataGenerator.forKnex = (function () { const newObj = _.cloneDeep(overrides); return _.defaults(newObj, { id: ObjectId().toHexString(), - uuid: uuid.v4(), + uuid: crypto.randomUUID(), slug: 'daily-newsletter', name: 'Daily Newsletter', sender_name: 'Jamie Larsen', @@ -1299,7 +1299,7 @@ DataGenerator.forKnex = (function () { return _.defaults(newObj, { id: ObjectId().toHexString(), - token: uuid.v4(), + token: crypto.randomUUID(), expires: Date.now() + constants.ONE_DAY_MS }); } @@ -1309,7 +1309,7 @@ DataGenerator.forKnex = (function () { return _.defaults(newObj, { id: ObjectId().toHexString(), - token: uuid.v4(), + token: crypto.randomUUID(), email: 'test@ghost.org', role_id: DataGenerator.Content.roles[0].id, expires: Date.now() + (60 * 1000), diff --git a/ghost/members-api/lib/repositories/MemberRepository.js b/ghost/members-api/lib/repositories/MemberRepository.js index bec24a2222..c54d55de4d 100644 --- a/ghost/members-api/lib/repositories/MemberRepository.js +++ b/ghost/members-api/lib/repositories/MemberRepository.js @@ -7,7 +7,7 @@ const {SubscriptionActivatedEvent, MemberCreatedEvent, SubscriptionCreatedEvent, const ObjectId = require('bson-objectid').default; const {NotFoundError} = require('@tryghost/errors'); const validator = require('@tryghost/validator'); -const uuid = require('uuid'); +const crypto = require('crypto'); const messages = { noStripeConnection: 'Cannot {action} without a Stripe Connection', @@ -228,7 +228,7 @@ module.exports = class MemberRepository { } _generateTransientId() { - return uuid.v4(); + return crypto.randomUUID(); } async cycleTransientId({id, email}) { diff --git a/ghost/security/test/tokens.test.js b/ghost/security/test/tokens.test.js index adfbf01287..f0c2d69259 100644 --- a/ghost/security/test/tokens.test.js +++ b/ghost/security/test/tokens.test.js @@ -1,12 +1,12 @@ require('./utils'); const should = require('should'); -const uuid = require('uuid'); +const crypto = require('crypto'); const security = require('../'); describe('Utils: tokens', function () { it('generate', function () { const expires = Date.now() + 60 * 1000; - const dbHash = uuid.v4(); + const dbHash = crypto.randomUUID(); let token; token = security.tokens.resetToken.generateHash({ @@ -22,7 +22,7 @@ describe('Utils: tokens', function () { it('compare: success', function () { const expires = Date.now() + 60 * 1000; - const dbHash = uuid.v4(); + const dbHash = crypto.randomUUID(); let token; let tokenIsCorrect; @@ -45,7 +45,7 @@ describe('Utils: tokens', function () { it('compare: error from invalid password', function () { const expires = Date.now() + 60 * 1000; - const dbHash = uuid.v4(); + const dbHash = crypto.randomUUID(); let token; let tokenIsCorrect; @@ -68,7 +68,7 @@ describe('Utils: tokens', function () { it('compare: error from invalid expires parameter', function () { const invalidDate = 'not a date'; - const dbHash = uuid.v4(); + const dbHash = crypto.randomUUID(); let token; let tokenIsCorrect; @@ -91,7 +91,7 @@ describe('Utils: tokens', function () { it('compare: error from expired token', function () { const dateInThePast = Date.now() - 60 * 1000; - const dbHash = uuid.v4(); + const dbHash = crypto.randomUUID(); let token; let tokenIsCorrect; @@ -114,7 +114,7 @@ describe('Utils: tokens', function () { it('extract', function () { const expires = Date.now() + 60 * 1000; - const dbHash = uuid.v4(); + const dbHash = crypto.randomUUID(); let token; let parts; const email = 'test1@ghost.org'; @@ -138,7 +138,7 @@ describe('Utils: tokens', function () { it('extract - hashed password', function () { const expires = Date.now() + 60 * 1000; - const dbHash = uuid.v4(); + const dbHash = crypto.randomUUID(); let token; let parts; const email = 'test3@ghost.org'; @@ -163,7 +163,7 @@ describe('Utils: tokens', function () { it('can validate an URI encoded reset token', function () { const expires = Date.now() + 60 * 1000; const email = 'test1@ghost.org'; - const dbHash = uuid.v4(); + const dbHash = crypto.randomUUID(); let token; let tokenIsCorrect; let parts; diff --git a/ghost/update-check-service/test/update-check-service.test.js b/ghost/update-check-service/test/update-check-service.test.js index aabd3ad1db..c3c2a5ff9c 100644 --- a/ghost/update-check-service/test/update-check-service.test.js +++ b/ghost/update-check-service/test/update-check-service.test.js @@ -2,7 +2,7 @@ require('./utils'); const sinon = require('sinon'); const moment = require('moment'); -const uuid = require('uuid'); +const crypto = require('crypto'); const assert = require('assert/strict'); const logging = require('@tryghost/logging'); @@ -196,7 +196,7 @@ describe('Update Check', function () { id: 1, custom: 0, messages: [{ - id: uuid.v4(), + id: crypto.randomUUID(), version: '999.9.x', content: '

Hey there! This is for 999.9.0 version

', dismissible: true, @@ -268,7 +268,7 @@ describe('Update Check', function () { const notification = { id: 1, messages: [{ - id: uuid.v4(), + id: crypto.randomUUID(), version: 'custom1', content: '

Critical message. Upgrade your site!

', dismissible: false,