From 3a4992633ee62d5edfbb484d9c6bcb3cf158489d Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 31 Jul 2023 14:34:36 +0200 Subject: Migrate server to ESM Sorry for the very big commit that may lead to git log issues and merge conflicts, but it's a major step forward: * Server can be faster at startup because imports() are async and we can easily lazy import big modules * Angular doesn't seem to support ES import (with .js extension), so we had to correctly organize peertube into a monorepo: * Use yarn workspace feature * Use typescript reference projects for dependencies * Shared projects have been moved into "packages", each one is now a node module (with a dedicated package.json/tsconfig.json) * server/tools have been moved into apps/ and is now a dedicated app bundled and published on NPM so users don't have to build peertube cli tools manually * server/tests have been moved into packages/ so we don't compile them every time we want to run the server * Use isolatedModule option: * Had to move from const enum to const (https://www.typescriptlang.org/docs/handbook/enums.html#objects-vs-enums) * Had to explictely specify "type" imports when used in decorators * Prefer tsx (that uses esbuild under the hood) instead of ts-node to load typescript files (tests with mocha or scripts): * To reduce test complexity as esbuild doesn't support decorator metadata, we only test server files that do not import server models * We still build tests files into js files for a faster CI * Remove unmaintained peertube CLI import script * Removed some barrels to speed up execution (less imports) --- apps/peertube-cli/src/peertube-auth.ts | 171 +++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 apps/peertube-cli/src/peertube-auth.ts (limited to 'apps/peertube-cli/src/peertube-auth.ts') diff --git a/apps/peertube-cli/src/peertube-auth.ts b/apps/peertube-cli/src/peertube-auth.ts new file mode 100644 index 000000000..1d30207c7 --- /dev/null +++ b/apps/peertube-cli/src/peertube-auth.ts @@ -0,0 +1,171 @@ +import CliTable3 from 'cli-table3' +import prompt from 'prompt' +import { Command } from '@commander-js/extra-typings' +import { assignToken, buildServer, getNetrc, getSettings, writeSettings } from './shared/index.js' + +export function defineAuthProgram () { + const program = new Command() + .name('auth') + .description('Register your accounts on remote instances to use them with other commands') + + program + .command('add') + .description('remember your accounts on remote instances for easier use') + .option('-u, --url ', 'Server url') + .option('-U, --username ', 'Username') + .option('-p, --password ', 'Password') + .option('--default', 'add the entry as the new default') + .action(options => { + /* eslint-disable no-import-assign */ + prompt.override = options + prompt.start() + prompt.get({ + properties: { + url: { + description: 'instance url', + conform: value => isURLaPeerTubeInstance(value), + message: 'It should be an URL (https://peertube.example.com)', + required: true + }, + username: { + conform: value => typeof value === 'string' && value.length !== 0, + message: 'Name must be only letters, spaces, or dashes', + required: true + }, + password: { + hidden: true, + replace: '*', + required: true + } + } + }, async (_, result) => { + + // Check credentials + try { + // Strip out everything after the domain:port. + // See https://github.com/Chocobozzz/PeerTube/issues/3520 + result.url = stripExtraneousFromPeerTubeUrl(result.url) + + const server = buildServer(result.url) + await assignToken(server, result.username, result.password) + } catch (err) { + console.error(err.message) + process.exit(-1) + } + + await setInstance(result.url, result.username, result.password, options.default) + + process.exit(0) + }) + }) + + program + .command('del ') + .description('Unregisters a remote instance') + .action(async url => { + await delInstance(url) + + process.exit(0) + }) + + program + .command('list') + .description('List registered remote instances') + .action(async () => { + const [ settings, netrc ] = await Promise.all([ getSettings(), getNetrc() ]) + + const table = new CliTable3({ + head: [ 'instance', 'login' ], + colWidths: [ 30, 30 ] + }) as any + + settings.remotes.forEach(element => { + if (!netrc.machines[element]) return + + table.push([ + element, + netrc.machines[element].login + ]) + }) + + console.log(table.toString()) + + process.exit(0) + }) + + program + .command('set-default ') + .description('Set an existing entry as default') + .action(async url => { + const settings = await getSettings() + const instanceExists = settings.remotes.includes(url) + + if (instanceExists) { + settings.default = settings.remotes.indexOf(url) + await writeSettings(settings) + + process.exit(0) + } else { + console.log(' is not a registered instance.') + process.exit(-1) + } + }) + + program.addHelpText('after', '\n\n Examples:\n\n' + + ' $ peertube auth add -u https://peertube.cpy.re -U "PEERTUBE_USER" --password "PEERTUBE_PASSWORD"\n' + + ' $ peertube auth add -u https://peertube.cpy.re -U root\n' + + ' $ peertube auth list\n' + + ' $ peertube auth del https://peertube.cpy.re\n' + ) + + return program +} + +// --------------------------------------------------------------------------- +// Private +// --------------------------------------------------------------------------- + +async function delInstance (url: string) { + const [ settings, netrc ] = await Promise.all([ getSettings(), getNetrc() ]) + + const index = settings.remotes.indexOf(url) + settings.remotes.splice(index) + + if (settings.default === index) settings.default = -1 + + await writeSettings(settings) + + delete netrc.machines[url] + + await netrc.save() +} + +async function setInstance (url: string, username: string, password: string, isDefault: boolean) { + const [ settings, netrc ] = await Promise.all([ getSettings(), getNetrc() ]) + + if (settings.remotes.includes(url) === false) { + settings.remotes.push(url) + } + + if (isDefault || settings.remotes.length === 1) { + settings.default = settings.remotes.length - 1 + } + + await writeSettings(settings) + + netrc.machines[url] = { login: username, password } + await netrc.save() +} + +function isURLaPeerTubeInstance (url: string) { + return url.startsWith('http://') || url.startsWith('https://') +} + +function stripExtraneousFromPeerTubeUrl (url: string) { + // Get everything before the 3rd /. + const urlLength = url.includes('/', 8) + ? url.indexOf('/', 8) + : url.length + + return url.substring(0, urlLength) +} -- cgit v1.2.3