mirror of
https://github.com/cupcakearmy/cryptgeon.git
synced 2024-12-22 08:16:28 +00:00
add --all option, stdin and password option
This commit is contained in:
parent
2e89007c83
commit
b43b802221
@ -7,7 +7,7 @@ import pretty from 'pretty-bytes'
|
|||||||
|
|
||||||
import { exit } from './utils'
|
import { exit } from './utils'
|
||||||
|
|
||||||
export async function download(url: URL) {
|
export async function download(url: URL, all: boolean, suggestedPassword?: string) {
|
||||||
setBase(url.origin)
|
setBase(url.origin)
|
||||||
const id = url.pathname.split('/')[2]
|
const id = url.pathname.split('/')[2]
|
||||||
const preview = await info(id).catch(() => exit('Note does not exist or is expired'))
|
const preview = await info(id).catch(() => exit('Note does not exist or is expired'))
|
||||||
@ -16,14 +16,18 @@ export async function download(url: URL) {
|
|||||||
let password: string
|
let password: string
|
||||||
const derivation = preview?.meta.derivation
|
const derivation = preview?.meta.derivation
|
||||||
if (derivation) {
|
if (derivation) {
|
||||||
const response = await inquirer.prompt([
|
if (suggestedPassword) {
|
||||||
{
|
password = suggestedPassword
|
||||||
type: 'password',
|
} else {
|
||||||
message: 'Note password',
|
const response = await inquirer.prompt([
|
||||||
name: 'password',
|
{
|
||||||
},
|
type: 'password',
|
||||||
])
|
message: 'Note password',
|
||||||
password = response.password
|
name: 'password',
|
||||||
|
},
|
||||||
|
])
|
||||||
|
password = response.password
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
password = url.hash.slice(1)
|
password = url.hash.slice(1)
|
||||||
}
|
}
|
||||||
@ -39,25 +43,29 @@ export async function download(url: URL) {
|
|||||||
exit('No files found in note')
|
exit('No files found in note')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const { names } = await inquirer.prompt([
|
|
||||||
{
|
|
||||||
type: 'checkbox',
|
|
||||||
message: 'What files should be saved?',
|
|
||||||
name: 'names',
|
|
||||||
choices: files.map((file) => ({
|
|
||||||
value: file.name,
|
|
||||||
name: `${file.name} - ${file.type} - ${pretty(file.size, { binary: true })}`,
|
|
||||||
checked: true,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
const selected = files.filter((file) => names.includes(file.name))
|
let selected: typeof files
|
||||||
|
if (all) {
|
||||||
|
selected = files
|
||||||
|
} else {
|
||||||
|
const { names } = await inquirer.prompt([
|
||||||
|
{
|
||||||
|
type: 'checkbox',
|
||||||
|
message: 'What files should be saved?',
|
||||||
|
name: 'names',
|
||||||
|
choices: files.map((file) => ({
|
||||||
|
value: file.name,
|
||||||
|
name: `${file.name} - ${file.type} - ${pretty(file.size, { binary: true })}`,
|
||||||
|
checked: true,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
])
|
||||||
|
selected = files.filter((file) => names.includes(file.name))
|
||||||
|
}
|
||||||
|
|
||||||
if (!selected.length) exit('No files selected')
|
if (!selected.length) exit('No files selected')
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
files.map(async (file) => {
|
selected.map(async (file) => {
|
||||||
let filename = resolve(file.name)
|
let filename = resolve(file.name)
|
||||||
try {
|
try {
|
||||||
// If exists -> prepend timestamp to not overwrite the current file
|
// If exists -> prepend timestamp to not overwrite the current file
|
||||||
@ -68,6 +76,7 @@ export async function download(url: URL) {
|
|||||||
console.log(`Saved: ${basename(filename)}`)
|
console.log(`Saved: ${basename(filename)}`)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
break
|
break
|
||||||
case 'text':
|
case 'text':
|
||||||
const plaintext = await Adapters.Text.decrypt(note.contents, key).catch(couldNotDecrypt)
|
const plaintext = await Adapters.Text.decrypt(note.contents, key).catch(couldNotDecrypt)
|
||||||
|
@ -15,6 +15,7 @@ const server = new Option('-s --server <url>', 'the cryptgeon server to use').de
|
|||||||
const files = new Argument('<file...>', 'Files to be sent').argParser(parseFile)
|
const files = new Argument('<file...>', 'Files to be sent').argParser(parseFile)
|
||||||
const text = new Argument('<text>', 'Text content of the note')
|
const text = new Argument('<text>', 'Text content of the note')
|
||||||
const password = new Option('-p --password <string>', 'manually set a password')
|
const password = new Option('-p --password <string>', 'manually set a password')
|
||||||
|
const all = new Option('-a --all', 'Save all files without prompt').default(false)
|
||||||
const url = new Argument('<url>', 'The url to open')
|
const url = new Argument('<url>', 'The url to open')
|
||||||
const views = new Option('-v --views <number>', 'Amount of views before getting destroyed').argParser(parseNumber)
|
const views = new Option('-v --views <number>', 'Amount of views before getting destroyed').argParser(parseNumber)
|
||||||
const minutes = new Option('-m --minutes <number>', 'Minutes before the note expires').argParser(parseNumber)
|
const minutes = new Option('-m --minutes <number>', 'Minutes before the note expires').argParser(parseNumber)
|
||||||
@ -86,10 +87,13 @@ send
|
|||||||
program
|
program
|
||||||
.command('open')
|
.command('open')
|
||||||
.addArgument(url)
|
.addArgument(url)
|
||||||
|
.addOption(password)
|
||||||
|
.addOption(all)
|
||||||
.action(async (note, options) => {
|
.action(async (note, options) => {
|
||||||
try {
|
try {
|
||||||
const url = new URL(note)
|
const url = new URL(note)
|
||||||
await download(url)
|
options.password ||= await getStdin()
|
||||||
|
await download(url, options.all, options.password)
|
||||||
} catch {
|
} catch {
|
||||||
exit('Invalid URL')
|
exit('Invalid URL')
|
||||||
}
|
}
|
||||||
|
@ -2,19 +2,23 @@ export function getStdin(timeout: number = 10): Promise<string> {
|
|||||||
return new Promise<string>((resolve, reject) => {
|
return new Promise<string>((resolve, reject) => {
|
||||||
// Store the data from stdin in a buffer
|
// Store the data from stdin in a buffer
|
||||||
let buffer = ''
|
let buffer = ''
|
||||||
process.stdin.on('data', (d) => (buffer += d.toString()))
|
let t: NodeJS.Timeout
|
||||||
|
|
||||||
|
const dataHandler = (d: Buffer) => (buffer += d.toString())
|
||||||
|
const endHandler = () => {
|
||||||
|
clearTimeout(t)
|
||||||
|
resolve(buffer.trim())
|
||||||
|
}
|
||||||
|
|
||||||
// Stop listening for data after the timeout, otherwise hangs indefinitely
|
// Stop listening for data after the timeout, otherwise hangs indefinitely
|
||||||
const t = setTimeout(() => {
|
t = setTimeout(() => {
|
||||||
process.stdin.destroy()
|
process.stdin.removeListener('data', dataHandler)
|
||||||
|
process.stdin.removeListener('end', endHandler)
|
||||||
|
process.stdin.pause()
|
||||||
resolve('')
|
resolve('')
|
||||||
}, timeout)
|
}, timeout)
|
||||||
|
|
||||||
// Listen for end and error events
|
process.stdin.on('data', dataHandler)
|
||||||
process.stdin.on('end', () => {
|
process.stdin.on('end', endHandler)
|
||||||
clearTimeout(t)
|
|
||||||
resolve(buffer.trim())
|
|
||||||
})
|
|
||||||
process.stdin.on('error', reject)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user