]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - client/src/standalone/videos/shared/auth-http.ts
Merge branch 'release/4.3.0' into develop
[github/Chocobozzz/PeerTube.git] / client / src / standalone / videos / shared / auth-http.ts
CommitLineData
f1a0f3b7 1import { HttpStatusCode, OAuth2ErrorCode, UserRefreshToken } from '../../../../../shared/models'
3545e72c 2import { OAuthUserTokens, objectToUrlEncoded } from '../../../root-helpers'
f1a0f3b7
C
3import { peertubeLocalStorage } from '../../../root-helpers/peertube-web-storage'
4
5export class AuthHTTP {
6 private readonly LOCAL_STORAGE_OAUTH_CLIENT_KEYS = {
7 CLIENT_ID: 'client_id',
8 CLIENT_SECRET: 'client_secret'
9 }
10
3545e72c 11 private userOAuthTokens: OAuthUserTokens
f1a0f3b7
C
12
13 private headers = new Headers()
14
15 constructor () {
3545e72c 16 this.userOAuthTokens = OAuthUserTokens.getUserTokens(peertubeLocalStorage)
f1a0f3b7 17
3545e72c 18 if (this.userOAuthTokens) this.setHeadersFromTokens()
f1a0f3b7
C
19 }
20
3545e72c 21 fetch (url: string, { optionalAuth, method }: { optionalAuth: boolean, method?: string }) {
f1a0f3b7
C
22 const refreshFetchOptions = optionalAuth
23 ? { headers: this.headers }
24 : {}
25
3545e72c 26 return this.refreshFetch(url.toString(), { ...refreshFetchOptions, method })
f1a0f3b7
C
27 }
28
29 getHeaderTokenValue () {
49e7e4d9
C
30 if (!this.userOAuthTokens) return null
31
3545e72c 32 return `${this.userOAuthTokens.tokenType} ${this.userOAuthTokens.accessToken}`
f1a0f3b7
C
33 }
34
35 isLoggedIn () {
3545e72c 36 return !!this.userOAuthTokens
f1a0f3b7
C
37 }
38
39 private refreshFetch (url: string, options?: RequestInit) {
40 return fetch(url, options)
41 .then((res: Response) => {
42 if (res.status !== HttpStatusCode.UNAUTHORIZED_401) return res
43
44 const refreshingTokenPromise = new Promise<void>((resolve, reject) => {
45 const clientId: string = peertubeLocalStorage.getItem(this.LOCAL_STORAGE_OAUTH_CLIENT_KEYS.CLIENT_ID)
46 const clientSecret: string = peertubeLocalStorage.getItem(this.LOCAL_STORAGE_OAUTH_CLIENT_KEYS.CLIENT_SECRET)
47
48 const headers = new Headers()
49 headers.set('Content-Type', 'application/x-www-form-urlencoded')
50
51 const data = {
3545e72c 52 refresh_token: this.userOAuthTokens.refreshToken,
f1a0f3b7
C
53 client_id: clientId,
54 client_secret: clientSecret,
55 response_type: 'code',
56 grant_type: 'refresh_token'
57 }
58
59 fetch('/api/v1/users/token', {
60 headers,
61 method: 'POST',
62 body: objectToUrlEncoded(data)
63 }).then(res => {
64 if (res.status === HttpStatusCode.UNAUTHORIZED_401) return undefined
65
66 return res.json()
67 }).then((obj: UserRefreshToken & { code?: OAuth2ErrorCode }) => {
68 if (!obj || obj.code === OAuth2ErrorCode.INVALID_GRANT) {
3545e72c 69 OAuthUserTokens.flushLocalStorage(peertubeLocalStorage)
f1a0f3b7
C
70 this.removeTokensFromHeaders()
71
72 return resolve()
73 }
74
3545e72c
C
75 this.userOAuthTokens.accessToken = obj.access_token
76 this.userOAuthTokens.refreshToken = obj.refresh_token
77 OAuthUserTokens.saveToLocalStorage(peertubeLocalStorage, this.userOAuthTokens)
f1a0f3b7
C
78
79 this.setHeadersFromTokens()
80
81 resolve()
82 }).catch((refreshTokenError: any) => {
83 reject(refreshTokenError)
84 })
85 })
86
87 return refreshingTokenPromise
88 .catch(() => {
3545e72c 89 OAuthUserTokens.flushLocalStorage(peertubeLocalStorage)
f1a0f3b7
C
90
91 this.removeTokensFromHeaders()
92 }).then(() => fetch(url, {
93 ...options,
94
95 headers: this.headers
96 }))
97 })
98 }
99
100 private setHeadersFromTokens () {
101 this.headers.set('Authorization', this.getHeaderTokenValue())
102 }
103
104 private removeTokensFromHeaders () {
105 this.headers.delete('Authorization')
106 }
107}