]>
Commit | Line | Data |
---|---|---|
4c7e60bc | 1 | import { HttpStatusCode, PeerTubeProblemDocument } from '@shared/models' |
41d1d075 C |
2 | import { unwrapBody } from '../requests' |
3 | import { AbstractCommand, OverrideCommandOptions } from '../shared' | |
4 | ||
56f47830 C |
5 | type LoginOptions = OverrideCommandOptions & { |
6 | client?: { id?: string, secret?: string } | |
7 | user?: { username: string, password?: string } | |
8 | otpToken?: string | |
9 | } | |
10 | ||
41d1d075 C |
11 | export class LoginCommand extends AbstractCommand { |
12 | ||
56f47830 C |
13 | async login (options: LoginOptions = {}) { |
14 | const res = await this._login(options) | |
41d1d075 | 15 | |
56f47830 C |
16 | return this.unwrapLoginBody(res.body) |
17 | } | |
41d1d075 | 18 | |
56f47830 C |
19 | async loginAndGetResponse (options: LoginOptions = {}) { |
20 | const res = await this._login(options) | |
41d1d075 | 21 | |
56f47830 C |
22 | return { |
23 | res, | |
24 | body: this.unwrapLoginBody(res.body) | |
25 | } | |
41d1d075 C |
26 | } |
27 | ||
7926c5f9 C |
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 } | |
41d1d075 | 32 | |
89d241a7 | 33 | if (!arg1) user = this.server.store.user |
41d1d075 C |
34 | else if (typeof arg1 === 'object') user = arg1 |
35 | else user = { username: arg1, password } | |
36 | ||
37 | try { | |
38 | const body = await this.login({ user }) | |
39 | ||
40 | return body.access_token | |
41 | } catch (err) { | |
d0a0fa42 | 42 | throw new Error(`Cannot authenticate. Please check your username/password. (${err})`) |
41d1d075 C |
43 | } |
44 | } | |
45 | ||
46 | loginUsingExternalToken (options: OverrideCommandOptions & { | |
47 | username: string | |
48 | externalAuthToken: string | |
49 | }) { | |
50 | const { username, externalAuthToken } = options | |
51 | const path = '/api/v1/users/token' | |
52 | ||
53 | const body = { | |
89d241a7 C |
54 | client_id: this.server.store.client.id, |
55 | client_secret: this.server.store.client.secret, | |
ba2684ce | 56 | username, |
41d1d075 C |
57 | response_type: 'code', |
58 | grant_type: 'password', | |
59 | scope: 'upload', | |
60 | externalAuthToken | |
61 | } | |
62 | ||
63 | return this.postBodyRequest({ | |
64 | ...options, | |
65 | ||
66 | path, | |
c0e8b12e | 67 | requestType: 'form', |
41d1d075 C |
68 | fields: body, |
69 | implicitToken: false, | |
70 | defaultExpectedStatus: HttpStatusCode.OK_200 | |
71 | }) | |
72 | } | |
73 | ||
74 | logout (options: OverrideCommandOptions & { | |
75 | token: string | |
76 | }) { | |
77 | const path = '/api/v1/users/revoke-token' | |
78 | ||
79 | return unwrapBody<{ redirectUrl: string }>(this.postBodyRequest({ | |
80 | ...options, | |
81 | ||
82 | path, | |
c0e8b12e | 83 | requestType: 'form', |
41d1d075 C |
84 | implicitToken: false, |
85 | defaultExpectedStatus: HttpStatusCode.OK_200 | |
86 | })) | |
87 | } | |
88 | ||
89 | refreshToken (options: OverrideCommandOptions & { | |
90 | refreshToken: string | |
91 | }) { | |
92 | const path = '/api/v1/users/token' | |
93 | ||
94 | const body = { | |
89d241a7 C |
95 | client_id: this.server.store.client.id, |
96 | client_secret: this.server.store.client.secret, | |
41d1d075 C |
97 | refresh_token: options.refreshToken, |
98 | response_type: 'code', | |
99 | grant_type: 'refresh_token' | |
100 | } | |
101 | ||
102 | return this.postBodyRequest({ | |
103 | ...options, | |
104 | ||
105 | path, | |
c0e8b12e | 106 | requestType: 'form', |
41d1d075 C |
107 | fields: body, |
108 | implicitToken: false, | |
109 | defaultExpectedStatus: HttpStatusCode.OK_200 | |
110 | }) | |
111 | } | |
112 | ||
113 | getClient (options: OverrideCommandOptions = {}) { | |
114 | const path = '/api/v1/oauth-clients/local' | |
115 | ||
116 | return this.getRequestBody<{ client_id: string, client_secret: string }>({ | |
117 | ...options, | |
118 | ||
119 | path, | |
120 | host: this.server.host, | |
121 | implicitToken: false, | |
122 | defaultExpectedStatus: HttpStatusCode.OK_200 | |
123 | }) | |
124 | } | |
56f47830 C |
125 | |
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' | |
129 | ||
130 | const body = { | |
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', | |
137 | scope: 'upload' | |
138 | } | |
139 | ||
140 | const headers = otpToken | |
141 | ? { 'x-peertube-otp': otpToken } | |
142 | : {} | |
143 | ||
144 | return this.postBodyRequest({ | |
145 | ...options, | |
146 | ||
147 | path, | |
148 | headers, | |
149 | requestType: 'form', | |
150 | fields: body, | |
151 | implicitToken: false, | |
152 | defaultExpectedStatus: HttpStatusCode.OK_200 | |
153 | }) | |
154 | } | |
155 | ||
156 | private unwrapLoginBody (body: any) { | |
157 | return body as { access_token: string, refresh_token: string } & PeerTubeProblemDocument | |
158 | } | |
41d1d075 | 159 | } |