From b392f44b81548ddbb9b7c483468ce894bdd025ea Mon Sep 17 00:00:00 2001 From: woxtu Date: Sat, 15 Jul 2023 18:39:38 +0900 Subject: [PATCH] refactor(backend): Improve UUID generation (#11286) * Replace with `crypto.randomUUID()` * Remove uuid --- packages/backend/package.json | 2 -- .../src/core/CreateSystemUserService.ts | 4 +-- packages/backend/src/core/DriveService.ts | 26 +++++++++---------- packages/backend/src/core/QueueService.ts | 4 +-- .../src/core/activitypub/ApRendererService.ts | 5 ++-- .../backend/src/server/api/ApiCallService.ts | 4 +-- .../api/endpoints/auth/session/generate.ts | 4 +-- .../src/server/web/ClientServerService.ts | 4 +-- pnpm-lock.yaml | 6 ----- 9 files changed, 25 insertions(+), 34 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index 777971527a..185651f394 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -158,7 +158,6 @@ "typescript": "5.1.6", "ulid": "2.3.0", "unzipper": "0.10.14", - "uuid": "9.0.0", "vary": "1.1.2", "web-push": "3.6.3", "ws": "8.13.0", @@ -201,7 +200,6 @@ "@types/tinycolor2": "1.4.3", "@types/tmp": "0.2.3", "@types/unzipper": "0.10.6", - "@types/uuid": "9.0.2", "@types/vary": "1.1.0", "@types/web-push": "3.3.2", "@types/websocket": "1.0.5", diff --git a/packages/backend/src/core/CreateSystemUserService.ts b/packages/backend/src/core/CreateSystemUserService.ts index 0bfbe2b173..2741cb41ee 100644 --- a/packages/backend/src/core/CreateSystemUserService.ts +++ b/packages/backend/src/core/CreateSystemUserService.ts @@ -1,6 +1,6 @@ +import { randomUUID } from 'node:crypto'; import { Inject, Injectable } from '@nestjs/common'; import bcrypt from 'bcryptjs'; -import { v4 as uuid } from 'uuid'; import { IsNull, DataSource } from 'typeorm'; import { genRsaKeyPair } from '@/misc/gen-key-pair.js'; import { User } from '@/models/entities/User.js'; @@ -24,7 +24,7 @@ export class CreateSystemUserService { @bindThis public async createSystemUser(username: string): Promise { - const password = uuid(); + const password = randomUUID(); // Generate hash of password const salt = await bcrypt.genSalt(8); diff --git a/packages/backend/src/core/DriveService.ts b/packages/backend/src/core/DriveService.ts index 1483b55469..355e5e8c0d 100644 --- a/packages/backend/src/core/DriveService.ts +++ b/packages/backend/src/core/DriveService.ts @@ -1,6 +1,6 @@ +import { randomUUID } from 'node:crypto'; import * as fs from 'node:fs'; import { Inject, Injectable } from '@nestjs/common'; -import { v4 as uuid } from 'uuid'; import sharp from 'sharp'; import { sharpBmp } from 'sharp-read-bmp'; import { IsNull } from 'typeorm'; @@ -162,7 +162,7 @@ export class DriveService { ?? `${ meta.objectStorageUseSSL ? 'https' : 'http' }://${ meta.objectStorageEndpoint }${ meta.objectStoragePort ? `:${meta.objectStoragePort}` : '' }/${ meta.objectStorageBucket }`; // for original - const key = `${meta.objectStoragePrefix}/${uuid()}${ext}`; + const key = `${meta.objectStoragePrefix}/${randomUUID()}${ext}`; const url = `${ baseUrl }/${ key }`; // for alts @@ -179,7 +179,7 @@ export class DriveService { ]; if (alts.webpublic) { - webpublicKey = `${meta.objectStoragePrefix}/webpublic-${uuid()}.${alts.webpublic.ext}`; + webpublicKey = `${meta.objectStoragePrefix}/webpublic-${randomUUID()}.${alts.webpublic.ext}`; webpublicUrl = `${ baseUrl }/${ webpublicKey }`; this.registerLogger.info(`uploading webpublic: ${webpublicKey}`); @@ -187,7 +187,7 @@ export class DriveService { } if (alts.thumbnail) { - thumbnailKey = `${meta.objectStoragePrefix}/thumbnail-${uuid()}.${alts.thumbnail.ext}`; + thumbnailKey = `${meta.objectStoragePrefix}/thumbnail-${randomUUID()}.${alts.thumbnail.ext}`; thumbnailUrl = `${ baseUrl }/${ thumbnailKey }`; this.registerLogger.info(`uploading thumbnail: ${thumbnailKey}`); @@ -212,9 +212,9 @@ export class DriveService { return await this.driveFilesRepository.insert(file).then(x => this.driveFilesRepository.findOneByOrFail(x.identifiers[0])); } else { // use internal storage - const accessKey = uuid(); - const thumbnailAccessKey = 'thumbnail-' + uuid(); - const webpublicAccessKey = 'webpublic-' + uuid(); + const accessKey = randomUUID(); + const thumbnailAccessKey = 'thumbnail-' + randomUUID(); + const webpublicAccessKey = 'webpublic-' + randomUUID(); const url = this.internalStorageService.saveFromPath(accessKey, path); @@ -584,9 +584,9 @@ export class DriveService { if (isLink) { file.url = url; // ローカルプロキシ用 - file.accessKey = uuid(); - file.thumbnailAccessKey = 'thumbnail-' + uuid(); - file.webpublicAccessKey = 'webpublic-' + uuid(); + file.accessKey = randomUUID(); + file.thumbnailAccessKey = 'thumbnail-' + randomUUID(); + file.webpublicAccessKey = 'webpublic-' + randomUUID(); } } @@ -713,9 +713,9 @@ export class DriveService { webpublicUrl: null, storedInternal: false, // ローカルプロキシ用 - accessKey: uuid(), - thumbnailAccessKey: 'thumbnail-' + uuid(), - webpublicAccessKey: 'webpublic-' + uuid(), + accessKey: randomUUID(), + thumbnailAccessKey: 'thumbnail-' + randomUUID(), + webpublicAccessKey: 'webpublic-' + randomUUID(), }); } else { this.driveFilesRepository.delete(file.id); diff --git a/packages/backend/src/core/QueueService.ts b/packages/backend/src/core/QueueService.ts index e1da0516d1..d0d4f802ee 100644 --- a/packages/backend/src/core/QueueService.ts +++ b/packages/backend/src/core/QueueService.ts @@ -1,5 +1,5 @@ +import { randomUUID } from 'node:crypto'; import { Inject, Injectable } from '@nestjs/common'; -import { v4 as uuid } from 'uuid'; import type { IActivity } from '@/core/activitypub/type.js'; import type { DriveFile } from '@/models/entities/DriveFile.js'; import type { Webhook, webhookEventTypes } from '@/models/entities/Webhook.js'; @@ -416,7 +416,7 @@ export class QueueService { to: webhook.url, secret: webhook.secret, createdAt: Date.now(), - eventId: uuid(), + eventId: randomUUID(), }; return this.webhookDeliverQueue.add(webhook.id, data, { diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index 95e3a936d2..797c6267b1 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -1,7 +1,6 @@ -import { createPublicKey } from 'node:crypto'; +import { createPublicKey, randomUUID } from 'node:crypto'; import { Inject, Injectable } from '@nestjs/common'; import { In } from 'typeorm'; -import { v4 as uuid } from 'uuid'; import * as mfm from 'mfm-js'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; @@ -613,7 +612,7 @@ export class ApRendererService { @bindThis public addContext(x: T): T & { '@context': any; id: string; } { if (typeof x === 'object' && x.id == null) { - x.id = `${this.config.url}/${uuid()}`; + x.id = `${this.config.url}/${randomUUID()}`; } return Object.assign({ diff --git a/packages/backend/src/server/api/ApiCallService.ts b/packages/backend/src/server/api/ApiCallService.ts index 09e3724394..c4c02e7afe 100644 --- a/packages/backend/src/server/api/ApiCallService.ts +++ b/packages/backend/src/server/api/ApiCallService.ts @@ -1,8 +1,8 @@ +import { randomUUID } from 'node:crypto'; import { pipeline } from 'node:stream'; import * as fs from 'node:fs'; import { promisify } from 'node:util'; import { Inject, Injectable } from '@nestjs/common'; -import { v4 as uuid } from 'uuid'; import { DI } from '@/di-symbols.js'; import { getIpHash } from '@/misc/get-ip-hash.js'; import type { LocalUser, User } from '@/models/entities/User.js'; @@ -362,7 +362,7 @@ export class ApiCallService implements OnApplicationShutdown { if (err instanceof ApiError || err instanceof AuthenticationError) { throw err; } else { - const errId = uuid(); + const errId = randomUUID(); this.logger.error(`Internal error occurred in ${ep.name}: ${err.message}`, { ep: ep.name, ps: data, diff --git a/packages/backend/src/server/api/endpoints/auth/session/generate.ts b/packages/backend/src/server/api/endpoints/auth/session/generate.ts index 6108d8202d..631fb4f024 100644 --- a/packages/backend/src/server/api/endpoints/auth/session/generate.ts +++ b/packages/backend/src/server/api/endpoints/auth/session/generate.ts @@ -1,4 +1,4 @@ -import { v4 as uuid } from 'uuid'; +import { randomUUID } from 'node:crypto'; import { Inject, Injectable } from '@nestjs/common'; import { Endpoint } from '@/server/api/endpoint-base.js'; import type { AppsRepository, AuthSessionsRepository } from '@/models/index.js'; @@ -71,7 +71,7 @@ export default class extends Endpoint { } // Generate token - const token = uuid(); + const token = randomUUID(); // Create session token document const doc = await this.authSessionsRepository.insert({ diff --git a/packages/backend/src/server/web/ClientServerService.ts b/packages/backend/src/server/web/ClientServerService.ts index 07ba2731c3..b5eea07775 100644 --- a/packages/backend/src/server/web/ClientServerService.ts +++ b/packages/backend/src/server/web/ClientServerService.ts @@ -1,7 +1,7 @@ +import { randomUUID } from 'node:crypto'; import { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import { Inject, Injectable } from '@nestjs/common'; -import { v4 as uuid } from 'uuid'; import { createBullBoard } from '@bull-board/api'; import { BullAdapter } from '@bull-board/api/bullAdapter.js'; import { FastifyAdapter } from '@bull-board/fastify'; @@ -676,7 +676,7 @@ export class ClientServerService { }); fastify.setErrorHandler(async (error, request, reply) => { - const errId = uuid(); + const errId = randomUUID(); this.clientLoggerService.logger.error(`Internal error occured in ${request.routerPath}: ${error.message}`, { path: request.routerPath, params: request.params, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 73a7cb1674..d97a8b7980 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -380,9 +380,6 @@ importers: unzipper: specifier: 0.10.14 version: 0.10.14 - uuid: - specifier: 9.0.0 - version: 9.0.0 vary: specifier: 1.1.2 version: 1.1.2 @@ -586,9 +583,6 @@ importers: '@types/unzipper': specifier: 0.10.6 version: 0.10.6 - '@types/uuid': - specifier: 9.0.2 - version: 9.0.2 '@types/vary': specifier: 1.1.0 version: 1.1.0