aboutsummaryrefslogtreecommitdiffhomepage
path: root/apps/peertube-cli/src/peertube-auth.ts
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-07-31 14:34:36 +0200
committerChocobozzz <me@florianbigard.com>2023-08-11 15:02:33 +0200
commit3a4992633ee62d5edfbb484d9c6bcb3cf158489d (patch)
treee4510b39bdac9c318fdb4b47018d08f15368b8f0 /apps/peertube-cli/src/peertube-auth.ts
parent04d1da5621d25d59bd5fa1543b725c497bf5d9a8 (diff)
downloadPeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.gz
PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.zst
PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.zip
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)
Diffstat (limited to 'apps/peertube-cli/src/peertube-auth.ts')
-rw-r--r--apps/peertube-cli/src/peertube-auth.ts171
1 files changed, 171 insertions, 0 deletions
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 @@
1import CliTable3 from 'cli-table3'
2import prompt from 'prompt'
3import { Command } from '@commander-js/extra-typings'
4import { assignToken, buildServer, getNetrc, getSettings, writeSettings } from './shared/index.js'
5
6export function defineAuthProgram () {
7 const program = new Command()
8 .name('auth')
9 .description('Register your accounts on remote instances to use them with other commands')
10
11 program
12 .command('add')
13 .description('remember your accounts on remote instances for easier use')
14 .option('-u, --url <url>', 'Server url')
15 .option('-U, --username <username>', 'Username')
16 .option('-p, --password <token>', 'Password')
17 .option('--default', 'add the entry as the new default')
18 .action(options => {
19 /* eslint-disable no-import-assign */
20 prompt.override = options
21 prompt.start()
22 prompt.get({
23 properties: {
24 url: {
25 description: 'instance url',
26 conform: value => isURLaPeerTubeInstance(value),
27 message: 'It should be an URL (https://peertube.example.com)',
28 required: true
29 },
30 username: {
31 conform: value => typeof value === 'string' && value.length !== 0,
32 message: 'Name must be only letters, spaces, or dashes',
33 required: true
34 },
35 password: {
36 hidden: true,
37 replace: '*',
38 required: true
39 }
40 }
41 }, async (_, result) => {
42
43 // Check credentials
44 try {
45 // Strip out everything after the domain:port.
46 // See https://github.com/Chocobozzz/PeerTube/issues/3520
47 result.url = stripExtraneousFromPeerTubeUrl(result.url)
48
49 const server = buildServer(result.url)
50 await assignToken(server, result.username, result.password)
51 } catch (err) {
52 console.error(err.message)
53 process.exit(-1)
54 }
55
56 await setInstance(result.url, result.username, result.password, options.default)
57
58 process.exit(0)
59 })
60 })
61
62 program
63 .command('del <url>')
64 .description('Unregisters a remote instance')
65 .action(async url => {
66 await delInstance(url)
67
68 process.exit(0)
69 })
70
71 program
72 .command('list')
73 .description('List registered remote instances')
74 .action(async () => {
75 const [ settings, netrc ] = await Promise.all([ getSettings(), getNetrc() ])
76
77 const table = new CliTable3({
78 head: [ 'instance', 'login' ],
79 colWidths: [ 30, 30 ]
80 }) as any
81
82 settings.remotes.forEach(element => {
83 if (!netrc.machines[element]) return
84
85 table.push([
86 element,
87 netrc.machines[element].login
88 ])
89 })
90
91 console.log(table.toString())
92
93 process.exit(0)
94 })
95
96 program
97 .command('set-default <url>')
98 .description('Set an existing entry as default')
99 .action(async url => {
100 const settings = await getSettings()
101 const instanceExists = settings.remotes.includes(url)
102
103 if (instanceExists) {
104 settings.default = settings.remotes.indexOf(url)
105 await writeSettings(settings)
106
107 process.exit(0)
108 } else {
109 console.log('<url> is not a registered instance.')
110 process.exit(-1)
111 }
112 })
113
114 program.addHelpText('after', '\n\n Examples:\n\n' +
115 ' $ peertube auth add -u https://peertube.cpy.re -U "PEERTUBE_USER" --password "PEERTUBE_PASSWORD"\n' +
116 ' $ peertube auth add -u https://peertube.cpy.re -U root\n' +
117 ' $ peertube auth list\n' +
118 ' $ peertube auth del https://peertube.cpy.re\n'
119 )
120
121 return program
122}
123
124// ---------------------------------------------------------------------------
125// Private
126// ---------------------------------------------------------------------------
127
128async function delInstance (url: string) {
129 const [ settings, netrc ] = await Promise.all([ getSettings(), getNetrc() ])
130
131 const index = settings.remotes.indexOf(url)
132 settings.remotes.splice(index)
133
134 if (settings.default === index) settings.default = -1
135
136 await writeSettings(settings)
137
138 delete netrc.machines[url]
139
140 await netrc.save()
141}
142
143async function setInstance (url: string, username: string, password: string, isDefault: boolean) {
144 const [ settings, netrc ] = await Promise.all([ getSettings(), getNetrc() ])
145
146 if (settings.remotes.includes(url) === false) {
147 settings.remotes.push(url)
148 }
149
150 if (isDefault || settings.remotes.length === 1) {
151 settings.default = settings.remotes.length - 1
152 }
153
154 await writeSettings(settings)
155
156 netrc.machines[url] = { login: username, password }
157 await netrc.save()
158}
159
160function isURLaPeerTubeInstance (url: string) {
161 return url.startsWith('http://') || url.startsWith('https://')
162}
163
164function stripExtraneousFromPeerTubeUrl (url: string) {
165 // Get everything before the 3rd /.
166 const urlLength = url.includes('/', 8)
167 ? url.indexOf('/', 8)
168 : url.length
169
170 return url.substring(0, urlLength)
171}