aboutsummaryrefslogtreecommitdiffhomepage
path: root/apps/peertube-cli/src/peertube-auth.ts
diff options
context:
space:
mode:
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}