mirror of
https://github.com/rustfs/console.git
synced 2026-10-30 19:33:40 +08:00
fix: security value problem
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
|
||||
## Build, Test, and Development Commands
|
||||
|
||||
- **Node version requirement**: Before running `pnpm` commands (especially checks/tests), run `nvm use v22` in this repository.
|
||||
|
||||
- `pnpm dev` – start the Next.js development server with hot reload.
|
||||
- `pnpm build` – create a production build.
|
||||
- `pnpm start` – run the production bundle locally.
|
||||
|
||||
@@ -47,8 +47,14 @@ export function AccessKeysNewItem({ visible, onVisibleChange, onSuccess, onNotic
|
||||
|
||||
React.useEffect(() => {
|
||||
if (visible) {
|
||||
setAccessKey(makeRandomString(20))
|
||||
setSecretKey(makeRandomString(40))
|
||||
try {
|
||||
setAccessKey(makeRandomString(20))
|
||||
setSecretKey(makeRandomString(40))
|
||||
} catch {
|
||||
setAccessKey("")
|
||||
setSecretKey("")
|
||||
message.error(t("Failed to generate secure random keys"))
|
||||
}
|
||||
setName("")
|
||||
setDescription("")
|
||||
setExpiry(null)
|
||||
@@ -63,7 +69,7 @@ export function AccessKeysNewItem({ visible, onVisibleChange, onSuccess, onNotic
|
||||
setPolicy("{}")
|
||||
})
|
||||
}
|
||||
}, [visible, api])
|
||||
}, [visible, api, message, t])
|
||||
|
||||
const closeModal = () => {
|
||||
onVisibleChange(false)
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
import { DeleteObjectCommand, DeleteObjectsCommand, ListObjectsV2Command, ListObjectVersionsCommand, S3Client } from "@aws-sdk/client-s3"
|
||||
import type { ManagedTask, TaskHandler, TaskLifecycleStatus } from "./task-manager"
|
||||
import { createTaskId } from "./task-id"
|
||||
|
||||
export type DeleteStatus = "pending" | "running" | "completed" | "failed" | "canceled"
|
||||
|
||||
@@ -203,7 +204,7 @@ export function createDeleteTaskHelpers(s3Client: S3Client, config: DeleteTaskCo
|
||||
prefix?: string,
|
||||
): DeleteTask[] =>
|
||||
items.map((item) => ({
|
||||
id: `${Date.now()}-${Math.random().toString(36).slice(2, 11)}-${item.key}-${item.versionId ?? "latest"}`,
|
||||
id: createTaskId(`${item.key}-${item.versionId ?? "latest"}`),
|
||||
kind: "delete" as const,
|
||||
key: item.key,
|
||||
versionId: item.versionId,
|
||||
@@ -244,7 +245,7 @@ export function createDeleteTaskHelpers(s3Client: S3Client, config: DeleteTaskCo
|
||||
bucketName: string,
|
||||
options?: { forceDelete?: boolean },
|
||||
): FolderDeleteTask => ({
|
||||
id: `${Date.now()}-${Math.random().toString(36).slice(2, 11)}-${prefix}`,
|
||||
id: createTaskId(prefix),
|
||||
kind: "delete-folder" as const,
|
||||
bucketName,
|
||||
prefix,
|
||||
|
||||
+18
-11
@@ -33,19 +33,26 @@ function convertToBytes(value: string, unit: string, fromK8s = false): number {
|
||||
}
|
||||
|
||||
export function makeRandomString(length = 20): string {
|
||||
let initstr = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
|
||||
const arr = initstr.split("")
|
||||
const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
|
||||
if (length <= 0) return ""
|
||||
|
||||
for (let i = arr.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1))
|
||||
const current = arr[i]
|
||||
const swapWith = arr[j]
|
||||
if (current !== undefined && swapWith !== undefined) {
|
||||
arr[i] = swapWith
|
||||
arr[j] = current
|
||||
const cryptoApi = globalThis.crypto
|
||||
if (!cryptoApi?.getRandomValues) {
|
||||
throw new Error("Secure random generator is not available")
|
||||
}
|
||||
|
||||
const result: string[] = []
|
||||
const alphabetLength = alphabet.length
|
||||
const maxByte = 256 - (256 % alphabetLength)
|
||||
|
||||
while (result.length < length) {
|
||||
const bytes = cryptoApi.getRandomValues(new Uint8Array(length))
|
||||
for (const byte of bytes) {
|
||||
if (byte >= maxByte) continue
|
||||
result.push(alphabet[byte % alphabetLength] ?? "")
|
||||
if (result.length === length) break
|
||||
}
|
||||
}
|
||||
|
||||
initstr = arr.join("")
|
||||
return initstr.slice(0, length)
|
||||
return result.join("")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
const FALLBACK_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
function createSecureSuffix(length = 12): string {
|
||||
const cryptoApi = globalThis.crypto
|
||||
if (!cryptoApi?.getRandomValues) {
|
||||
throw new Error("Secure random generator is not available")
|
||||
}
|
||||
|
||||
const chars: string[] = []
|
||||
const alphabetLength = FALLBACK_ALPHABET.length
|
||||
const maxByte = 256 - (256 % alphabetLength)
|
||||
|
||||
while (chars.length < length) {
|
||||
const bytes = cryptoApi.getRandomValues(new Uint8Array(length))
|
||||
for (const byte of bytes) {
|
||||
if (byte >= maxByte) continue
|
||||
chars.push(FALLBACK_ALPHABET[byte % alphabetLength] ?? "")
|
||||
if (chars.length === length) break
|
||||
}
|
||||
}
|
||||
|
||||
return chars.join("")
|
||||
}
|
||||
|
||||
export function createTaskId(seed: string): string {
|
||||
const prefix = Date.now()
|
||||
const cryptoApi = globalThis.crypto
|
||||
|
||||
if (cryptoApi?.randomUUID) {
|
||||
return `${prefix}-${cryptoApi.randomUUID()}-${seed}`
|
||||
}
|
||||
|
||||
return `${prefix}-${createSecureSuffix()}-${seed}`
|
||||
}
|
||||
|
||||
+2
-1
@@ -7,6 +7,7 @@ import {
|
||||
} from "@aws-sdk/client-s3"
|
||||
import type { ManagedTask, TaskHandler, TaskLifecycleStatus } from "./task-manager"
|
||||
import { formatBytes } from "./functions"
|
||||
import { createTaskId } from "./task-id"
|
||||
|
||||
export type UploadStatus = "pending" | "running" | "completed" | "failed" | "canceled" | "paused"
|
||||
|
||||
@@ -105,7 +106,7 @@ export function createUploadTaskHelpers(s3Client: S3Client, config: UploadTaskCo
|
||||
existKeys.add(`${bucketName}/${item.key}`)
|
||||
const displayName = item.key.split("/").pop() ?? item.key
|
||||
return {
|
||||
id: `${Date.now()}-${Math.random().toString(36).slice(2, 11)}-${item.key}`,
|
||||
id: createTaskId(item.key),
|
||||
kind: "upload" as const,
|
||||
file: item.file,
|
||||
key: item.key,
|
||||
|
||||
Reference in New Issue
Block a user