1 import { HttpStatusCode, PeerTubeProblemDocument } from '@shared/models'
2 import { unwrapBody } from '../requests'
3 import { AbstractCommand, OverrideCommandOptions } from '../shared'
5 type LoginOptions = OverrideCommandOptions & {
6 client?: { id?: string, secret?: string }
7 user?: { username: string, password?: string }
11 export class LoginCommand extends AbstractCommand {
13 async login (options: LoginOptions = {}) {
14 const res = await this._login(options)
16 return this.unwrapLoginBody(res.body)
19 async loginAndGetResponse (options: LoginOptions = {}) {
20 const res = await this._login(options)
24 body: this.unwrapLoginBody(res.body)
28 getAccessToken (arg1?: { username: string, password?: string }): Promise<string>
29 getAccessToken (arg1: string, password?: string): Promise<string>
30 async getAccessToken (arg1?: { username: string, password?: string } | string, password?: string) {
31 let user: { username: string, password?: string }
33 if (!arg1) user = this.server.store.user
34 else if (typeof arg1 === 'object') user = arg1
35 else user = { username: arg1, password }
38 const body = await this.login({ user })
40 return body.access_token
42 throw new Error(`Cannot authenticate. Please check your username/password. (${err})`)
46 loginUsingExternalToken (options: OverrideCommandOptions & {
48 externalAuthToken: string
50 const { username, externalAuthToken } = options
51 const path = '/api/v1/users/token'
54 client_id: this.server.store.client.id,
55 client_secret: this.server.store.client.secret,
57 response_type: 'code',
58 grant_type: 'password',
63 return this.postBodyRequest({
70 defaultExpectedStatus: HttpStatusCode.OK_200
74 logout (options: OverrideCommandOptions & {
77 const path = '/api/v1/users/revoke-token'
79 return unwrapBody<{ redirectUrl: string }>(this.postBodyRequest({
85 defaultExpectedStatus: HttpStatusCode.OK_200
89 refreshToken (options: OverrideCommandOptions & {
92 const path = '/api/v1/users/token'
95 client_id: this.server.store.client.id,
96 client_secret: this.server.store.client.secret,
97 refresh_token: options.refreshToken,
98 response_type: 'code',
99 grant_type: 'refresh_token'
102 return this.postBodyRequest({
108 implicitToken: false,
109 defaultExpectedStatus: HttpStatusCode.OK_200
113 getClient (options: OverrideCommandOptions = {}) {
114 const path = '/api/v1/oauth-clients/local'
116 return this.getRequestBody<{ client_id: string, client_secret: string }>({
120 host: this.server.host,
121 implicitToken: false,
122 defaultExpectedStatus: HttpStatusCode.OK_200
126 private _login (options: LoginOptions) {
127 const { client = this.server.store.client, user = this.server.store.user, otpToken } = options
128 const path = '/api/v1/users/token'
131 client_id: client.id,
132 client_secret: client.secret,
133 username: user.username,
134 password: user.password ?? 'password',
135 response_type: 'code',
136 grant_type: 'password',
140 const headers = otpToken
141 ? { 'x-peertube-otp': otpToken }
144 return this.postBodyRequest({
151 implicitToken: false,
152 defaultExpectedStatus: HttpStatusCode.OK_200
156 private unwrapLoginBody (body: any) {
157 return body as { access_token: string, refresh_token: string } & PeerTubeProblemDocument