123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- import { HttpStatusCode, OAuth2ErrorCode, UserRefreshToken } from '../../../../../shared/models'
- import { OAuthUserTokens, objectToUrlEncoded } from '../../../root-helpers'
- import { peertubeLocalStorage } from '../../../root-helpers/peertube-web-storage'
- export class AuthHTTP {
- private readonly LOCAL_STORAGE_OAUTH_CLIENT_KEYS = {
- CLIENT_ID: 'client_id',
- CLIENT_SECRET: 'client_secret'
- }
- private userOAuthTokens: OAuthUserTokens
- private headers = new Headers()
- constructor () {
- this.userOAuthTokens = OAuthUserTokens.getUserTokens(peertubeLocalStorage)
- if (this.userOAuthTokens) this.setHeadersFromTokens()
- }
- fetch (url: string, { optionalAuth, method }: { optionalAuth: boolean, method?: string }) {
- const refreshFetchOptions = optionalAuth
- ? { headers: this.headers }
- : {}
- return this.refreshFetch(url.toString(), { ...refreshFetchOptions, method })
- }
- getHeaderTokenValue () {
- return `${this.userOAuthTokens.tokenType} ${this.userOAuthTokens.accessToken}`
- }
- isLoggedIn () {
- return !!this.userOAuthTokens
- }
- private refreshFetch (url: string, options?: RequestInit) {
- return fetch(url, options)
- .then((res: Response) => {
- if (res.status !== HttpStatusCode.UNAUTHORIZED_401) return res
- const refreshingTokenPromise = new Promise<void>((resolve, reject) => {
- const clientId: string = peertubeLocalStorage.getItem(this.LOCAL_STORAGE_OAUTH_CLIENT_KEYS.CLIENT_ID)
- const clientSecret: string = peertubeLocalStorage.getItem(this.LOCAL_STORAGE_OAUTH_CLIENT_KEYS.CLIENT_SECRET)
- const headers = new Headers()
- headers.set('Content-Type', 'application/x-www-form-urlencoded')
- const data = {
- refresh_token: this.userOAuthTokens.refreshToken,
- client_id: clientId,
- client_secret: clientSecret,
- response_type: 'code',
- grant_type: 'refresh_token'
- }
- fetch('/api/v1/users/token', {
- headers,
- method: 'POST',
- body: objectToUrlEncoded(data)
- }).then(res => {
- if (res.status === HttpStatusCode.UNAUTHORIZED_401) return undefined
- return res.json()
- }).then((obj: UserRefreshToken & { code?: OAuth2ErrorCode }) => {
- if (!obj || obj.code === OAuth2ErrorCode.INVALID_GRANT) {
- OAuthUserTokens.flushLocalStorage(peertubeLocalStorage)
- this.removeTokensFromHeaders()
- return resolve()
- }
- this.userOAuthTokens.accessToken = obj.access_token
- this.userOAuthTokens.refreshToken = obj.refresh_token
- OAuthUserTokens.saveToLocalStorage(peertubeLocalStorage, this.userOAuthTokens)
- this.setHeadersFromTokens()
- resolve()
- }).catch((refreshTokenError: any) => {
- reject(refreshTokenError)
- })
- })
- return refreshingTokenPromise
- .catch(() => {
- OAuthUserTokens.flushLocalStorage(peertubeLocalStorage)
- this.removeTokensFromHeaders()
- }).then(() => fetch(url, {
- ...options,
- headers: this.headers
- }))
- })
- }
- private setHeadersFromTokens () {
- this.headers.set('Authorization', this.getHeaderTokenValue())
- }
- private removeTokensFromHeaders () {
- this.headers.delete('Authorization')
- }
- }
|