2021-07-16 14:27:30 +02:00
|
|
|
import { HttpStatusCode, PeerTubeProblemDocument } from '@shared/models'
|
2021-07-13 11:05:15 +02:00
|
|
|
import { unwrapBody } from '../requests'
|
|
|
|
import { AbstractCommand, OverrideCommandOptions } from '../shared'
|
|
|
|
|
2022-10-05 15:37:15 +02:00
|
|
|
type LoginOptions = OverrideCommandOptions & {
|
|
|
|
client?: { id?: string, secret?: string }
|
|
|
|
user?: { username: string, password?: string }
|
|
|
|
otpToken?: string
|
|
|
|
}
|
|
|
|
|
2021-07-13 11:05:15 +02:00
|
|
|
export class LoginCommand extends AbstractCommand {
|
|
|
|
|
2022-10-05 15:37:15 +02:00
|
|
|
async login (options: LoginOptions = {}) {
|
|
|
|
const res = await this._login(options)
|
2021-07-13 11:05:15 +02:00
|
|
|
|
2022-10-05 15:37:15 +02:00
|
|
|
return this.unwrapLoginBody(res.body)
|
|
|
|
}
|
2021-07-13 11:05:15 +02:00
|
|
|
|
2022-10-05 15:37:15 +02:00
|
|
|
async loginAndGetResponse (options: LoginOptions = {}) {
|
|
|
|
const res = await this._login(options)
|
2021-07-13 11:05:15 +02:00
|
|
|
|
2022-10-05 15:37:15 +02:00
|
|
|
return {
|
|
|
|
res,
|
|
|
|
body: this.unwrapLoginBody(res.body)
|
|
|
|
}
|
2021-07-13 11:05:15 +02:00
|
|
|
}
|
|
|
|
|
2021-07-13 14:23:01 +02:00
|
|
|
getAccessToken (arg1?: { username: string, password?: string }): Promise<string>
|
|
|
|
getAccessToken (arg1: string, password?: string): Promise<string>
|
|
|
|
async getAccessToken (arg1?: { username: string, password?: string } | string, password?: string) {
|
|
|
|
let user: { username: string, password?: string }
|
2021-07-13 11:05:15 +02:00
|
|
|
|
2021-07-16 09:04:35 +02:00
|
|
|
if (!arg1) user = this.server.store.user
|
2021-07-13 11:05:15 +02:00
|
|
|
else if (typeof arg1 === 'object') user = arg1
|
|
|
|
else user = { username: arg1, password }
|
|
|
|
|
|
|
|
try {
|
|
|
|
const body = await this.login({ user })
|
|
|
|
|
|
|
|
return body.access_token
|
|
|
|
} catch (err) {
|
2021-07-13 11:44:16 +02:00
|
|
|
throw new Error(`Cannot authenticate. Please check your username/password. (${err})`)
|
2021-07-13 11:05:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
loginUsingExternalToken (options: OverrideCommandOptions & {
|
|
|
|
username: string
|
|
|
|
externalAuthToken: string
|
|
|
|
}) {
|
|
|
|
const { username, externalAuthToken } = options
|
|
|
|
const path = '/api/v1/users/token'
|
|
|
|
|
|
|
|
const body = {
|
2021-07-16 09:04:35 +02:00
|
|
|
client_id: this.server.store.client.id,
|
|
|
|
client_secret: this.server.store.client.secret,
|
2022-07-13 11:58:01 +02:00
|
|
|
username,
|
2021-07-13 11:05:15 +02:00
|
|
|
response_type: 'code',
|
|
|
|
grant_type: 'password',
|
|
|
|
scope: 'upload',
|
|
|
|
externalAuthToken
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.postBodyRequest({
|
|
|
|
...options,
|
|
|
|
|
|
|
|
path,
|
2021-07-16 10:42:24 +02:00
|
|
|
requestType: 'form',
|
2021-07-13 11:05:15 +02:00
|
|
|
fields: body,
|
|
|
|
implicitToken: false,
|
|
|
|
defaultExpectedStatus: HttpStatusCode.OK_200
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
logout (options: OverrideCommandOptions & {
|
|
|
|
token: string
|
|
|
|
}) {
|
|
|
|
const path = '/api/v1/users/revoke-token'
|
|
|
|
|
|
|
|
return unwrapBody<{ redirectUrl: string }>(this.postBodyRequest({
|
|
|
|
...options,
|
|
|
|
|
|
|
|
path,
|
2021-07-16 10:42:24 +02:00
|
|
|
requestType: 'form',
|
2021-07-13 11:05:15 +02:00
|
|
|
implicitToken: false,
|
|
|
|
defaultExpectedStatus: HttpStatusCode.OK_200
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
|
|
|
refreshToken (options: OverrideCommandOptions & {
|
|
|
|
refreshToken: string
|
|
|
|
}) {
|
|
|
|
const path = '/api/v1/users/token'
|
|
|
|
|
|
|
|
const body = {
|
2021-07-16 09:04:35 +02:00
|
|
|
client_id: this.server.store.client.id,
|
|
|
|
client_secret: this.server.store.client.secret,
|
2021-07-13 11:05:15 +02:00
|
|
|
refresh_token: options.refreshToken,
|
|
|
|
response_type: 'code',
|
|
|
|
grant_type: 'refresh_token'
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.postBodyRequest({
|
|
|
|
...options,
|
|
|
|
|
|
|
|
path,
|
2021-07-16 10:42:24 +02:00
|
|
|
requestType: 'form',
|
2021-07-13 11:05:15 +02:00
|
|
|
fields: body,
|
|
|
|
implicitToken: false,
|
|
|
|
defaultExpectedStatus: HttpStatusCode.OK_200
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
getClient (options: OverrideCommandOptions = {}) {
|
|
|
|
const path = '/api/v1/oauth-clients/local'
|
|
|
|
|
|
|
|
return this.getRequestBody<{ client_id: string, client_secret: string }>({
|
|
|
|
...options,
|
|
|
|
|
|
|
|
path,
|
|
|
|
host: this.server.host,
|
|
|
|
implicitToken: false,
|
|
|
|
defaultExpectedStatus: HttpStatusCode.OK_200
|
|
|
|
})
|
|
|
|
}
|
2022-10-05 15:37:15 +02:00
|
|
|
|
|
|
|
private _login (options: LoginOptions) {
|
|
|
|
const { client = this.server.store.client, user = this.server.store.user, otpToken } = options
|
|
|
|
const path = '/api/v1/users/token'
|
|
|
|
|
|
|
|
const body = {
|
|
|
|
client_id: client.id,
|
|
|
|
client_secret: client.secret,
|
|
|
|
username: user.username,
|
|
|
|
password: user.password ?? 'password',
|
|
|
|
response_type: 'code',
|
|
|
|
grant_type: 'password',
|
|
|
|
scope: 'upload'
|
|
|
|
}
|
|
|
|
|
|
|
|
const headers = otpToken
|
|
|
|
? { 'x-peertube-otp': otpToken }
|
|
|
|
: {}
|
|
|
|
|
|
|
|
return this.postBodyRequest({
|
|
|
|
...options,
|
|
|
|
|
|
|
|
path,
|
|
|
|
headers,
|
|
|
|
requestType: 'form',
|
|
|
|
fields: body,
|
|
|
|
implicitToken: false,
|
|
|
|
defaultExpectedStatus: HttpStatusCode.OK_200
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
private unwrapLoginBody (body: any) {
|
|
|
|
return body as { access_token: string, refresh_token: string } & PeerTubeProblemDocument
|
|
|
|
}
|
2021-07-13 11:05:15 +02:00
|
|
|
}
|