mirror of
https://github.com/cupcakearmy/cryptgeon.git
synced 2026-09-27 04:51:45 +00:00
refactor: extract payload pack/unpack pipeline into @cryptgeon/shared
This commit is contained in:
@@ -1,43 +1,38 @@
|
||||
import { readFile } from 'node:fs/promises'
|
||||
import { basename } from 'node:path'
|
||||
|
||||
import { encode } from '@msgpack/msgpack'
|
||||
import mime from 'mime'
|
||||
import { encrypt, generateKey, deriveKey, randomBytes, getServer, create, compress } from '@cryptgeon/shared'
|
||||
import { getServer, create, packContent, type FileDTO } from '@cryptgeon/shared'
|
||||
|
||||
export type UploadOptions = { views?: number; expiration?: number; password?: string }
|
||||
|
||||
export async function upload(input: string | string[], options: UploadOptions): Promise<string> {
|
||||
const { password, ...noteOptions } = options
|
||||
|
||||
let key: Uint8Array
|
||||
let extra = new Uint8Array()
|
||||
if (password) {
|
||||
const salt = randomBytes(16)
|
||||
key = deriveKey(password, salt)
|
||||
extra = encode({ salt, N: 32768, r: 8, p: 1 })
|
||||
} else {
|
||||
key = generateKey()
|
||||
}
|
||||
const payload = packContent(
|
||||
typeof input === 'string'
|
||||
? { type: 'text', text: input }
|
||||
: { type: 'files', files: await fileDTOSfromPaths(input) },
|
||||
password
|
||||
)
|
||||
|
||||
let inner: Uint8Array
|
||||
if (typeof input === 'string') {
|
||||
inner = encode({ type: 'text', data: input })
|
||||
} else {
|
||||
const files = await Promise.all(
|
||||
input.map(async (path) => {
|
||||
const data = new Uint8Array(await readFile(path))
|
||||
const extension = path.substring(path.indexOf('.') + 1)
|
||||
const type = mime.getType(extension) ?? 'application/octet-stream'
|
||||
return { name: basename(path), mime: type, size: data.length, data }
|
||||
})
|
||||
)
|
||||
inner = encode({ type: 'files', data: files })
|
||||
}
|
||||
|
||||
const data = encrypt(compress(inner), key)
|
||||
const result = await create({ meta: { ...noteOptions, extra }, data })
|
||||
const result = await create({ meta: { ...noteOptions, extra: payload.extra }, data: payload.data })
|
||||
let url = `${getServer()}/note/${result.id}`
|
||||
if (!password) url += `#${Buffer.from(key).toString('hex')}`
|
||||
if (!password) url += `#${Buffer.from(payload.key).toString('hex')}`
|
||||
return url
|
||||
}
|
||||
|
||||
async function fileDTOSfromPaths(paths: string[]): Promise<FileDTO[]> {
|
||||
return Promise.all(
|
||||
paths.map(async (path) => {
|
||||
const extension = path.substring(path.indexOf('.') + 1)
|
||||
const data = new Uint8Array(await readFile(path))
|
||||
return {
|
||||
name: basename(path),
|
||||
mime: mime.getType(extension) ?? 'application/octet-stream',
|
||||
size: data.length,
|
||||
data,
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user