deal with refresh token in embed
This commit is contained in:
parent
71ab65d02f
commit
4504f09f6e
|
@ -2,7 +2,7 @@ import { BytesPipe } from 'ngx-pipes'
|
|||
import { SortMeta } from 'primeng/api'
|
||||
import { Component, OnInit } from '@angular/core'
|
||||
import { ConfirmService, Notifier, RestPagination, RestTable, ServerService } from '@app/core'
|
||||
import { peertubeLocalStorage } from '@app/helpers/peertube-web-storage'
|
||||
import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage'
|
||||
import { RedundancyService } from '@app/shared/shared-main'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
import { VideoRedundanciesTarget, VideoRedundancy } from '@shared/models'
|
||||
|
|
|
@ -14,7 +14,7 @@ import { DomSanitizer } from '@angular/platform-browser'
|
|||
@Component({
|
||||
selector: 'my-video-block-list',
|
||||
templateUrl: './video-block-list.component.html',
|
||||
styleUrls: [ '../../../shared/shared-moderation/moderation.scss', '../../../shared/shared-abuse-list/abuse-list-table.component.scss', './video-block-list.component.scss' ]
|
||||
styleUrls: [ '../../../shared/shared-moderation/moderation.scss', './video-block-list.component.scss' ]
|
||||
})
|
||||
export class VideoBlockListComponent extends RestTable implements OnInit, AfterViewInit {
|
||||
blocklist: (VideoBlacklist & { reasonHtml?: string, embedHtml?: string })[] = []
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { SortMeta } from 'primeng/api'
|
||||
import { Component, OnInit } from '@angular/core'
|
||||
import { Notifier, RestPagination, RestTable } from '@app/core'
|
||||
import { peertubeLocalStorage } from '@app/helpers/peertube-web-storage'
|
||||
import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
import { Job, JobState, JobType } from '@shared/models'
|
||||
import { JobStateClient } from '../../../../types/job-state-client.type'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Component, Input } from '@angular/core'
|
||||
import { Router } from '@angular/router'
|
||||
import { AuthService, ComponentPagination, LocalStorageService, Notifier, SessionStorageService, UserService } from '@app/core'
|
||||
import { peertubeLocalStorage, peertubeSessionStorage } from '@app/helpers/peertube-web-storage'
|
||||
import { peertubeLocalStorage, peertubeSessionStorage } from '@root-helpers/peertube-web-storage'
|
||||
import { VideoPlaylist, VideoPlaylistElement, VideoPlaylistService } from '@app/shared/shared-video-playlist'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
import { VideoDetails, VideoPlaylistPrivacy } from '@shared/models'
|
||||
|
|
|
@ -7,7 +7,8 @@ import { ActivatedRoute, Router } from '@angular/router'
|
|||
import { AuthService, AuthUser, ConfirmService, MarkdownService, Notifier, RestExtractor, ServerService, UserService } from '@app/core'
|
||||
import { HooksService } from '@app/core/plugins/hooks.service'
|
||||
import { RedirectService } from '@app/core/routing/redirect.service'
|
||||
import { isXPercentInViewport, peertubeLocalStorage, scrollToTop } from '@app/helpers'
|
||||
import { isXPercentInViewport, scrollToTop } from '@app/helpers'
|
||||
import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage'
|
||||
import { Video, VideoCaptionService, VideoDetails, VideoService } from '@app/shared/shared-main'
|
||||
import { SubscribeButtonComponent } from '@app/shared/shared-user-subscription'
|
||||
import { VideoPlaylist, VideoPlaylistService } from '@app/shared/shared-video-playlist'
|
||||
|
|
|
@ -15,7 +15,8 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
|||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
import { BroadcastMessageLevel, getShortLocale, is18nPath, ServerConfig, UserRole } from '@shared/models'
|
||||
import { MenuService } from './core/menu/menu.service'
|
||||
import { peertubeLocalStorage, POP_STATE_MODAL_DISMISS } from './helpers'
|
||||
import { POP_STATE_MODAL_DISMISS } from './helpers'
|
||||
import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage'
|
||||
import { InstanceService } from './shared/shared-instance'
|
||||
|
||||
@Component({
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Observable, of } from 'rxjs'
|
||||
import { map } from 'rxjs/operators'
|
||||
import { User } from '@app/core/users/user.model'
|
||||
import { peertubeLocalStorage } from '@app/helpers/peertube-web-storage'
|
||||
import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage'
|
||||
import {
|
||||
hasUserRight,
|
||||
MyUser as ServerMyUserModel,
|
||||
|
@ -12,66 +12,7 @@ import {
|
|||
UserRole,
|
||||
UserVideoQuota
|
||||
} from '@shared/models'
|
||||
|
||||
export type TokenOptions = {
|
||||
accessToken: string
|
||||
refreshToken: string
|
||||
tokenType: string
|
||||
}
|
||||
|
||||
// Private class only used by User
|
||||
class Tokens {
|
||||
private static KEYS = {
|
||||
ACCESS_TOKEN: 'access_token',
|
||||
REFRESH_TOKEN: 'refresh_token',
|
||||
TOKEN_TYPE: 'token_type'
|
||||
}
|
||||
|
||||
accessToken: string
|
||||
refreshToken: string
|
||||
tokenType: string
|
||||
|
||||
static load () {
|
||||
const accessTokenLocalStorage = peertubeLocalStorage.getItem(this.KEYS.ACCESS_TOKEN)
|
||||
const refreshTokenLocalStorage = peertubeLocalStorage.getItem(this.KEYS.REFRESH_TOKEN)
|
||||
const tokenTypeLocalStorage = peertubeLocalStorage.getItem(this.KEYS.TOKEN_TYPE)
|
||||
|
||||
if (accessTokenLocalStorage && refreshTokenLocalStorage && tokenTypeLocalStorage) {
|
||||
return new Tokens({
|
||||
accessToken: accessTokenLocalStorage,
|
||||
refreshToken: refreshTokenLocalStorage,
|
||||
tokenType: tokenTypeLocalStorage
|
||||
})
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
static flush () {
|
||||
peertubeLocalStorage.removeItem(this.KEYS.ACCESS_TOKEN)
|
||||
peertubeLocalStorage.removeItem(this.KEYS.REFRESH_TOKEN)
|
||||
peertubeLocalStorage.removeItem(this.KEYS.TOKEN_TYPE)
|
||||
}
|
||||
|
||||
constructor (hash?: TokenOptions) {
|
||||
if (hash) {
|
||||
this.accessToken = hash.accessToken
|
||||
this.refreshToken = hash.refreshToken
|
||||
|
||||
if (hash.tokenType === 'bearer') {
|
||||
this.tokenType = 'Bearer'
|
||||
} else {
|
||||
this.tokenType = hash.tokenType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
save () {
|
||||
peertubeLocalStorage.setItem(Tokens.KEYS.ACCESS_TOKEN, this.accessToken)
|
||||
peertubeLocalStorage.setItem(Tokens.KEYS.REFRESH_TOKEN, this.refreshToken)
|
||||
peertubeLocalStorage.setItem(Tokens.KEYS.TOKEN_TYPE, this.tokenType)
|
||||
}
|
||||
}
|
||||
import { TokenOptions, Tokens } from '../../../root-helpers/pure-auth-user.model'
|
||||
|
||||
export class AuthUser extends User implements ServerMyUserModel {
|
||||
tokens: Tokens
|
||||
|
|
|
@ -5,7 +5,7 @@ import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'
|
|||
import { Injectable } from '@angular/core'
|
||||
import { Router } from '@angular/router'
|
||||
import { Notifier } from '@app/core/notification/notifier.service'
|
||||
import { objectToUrlEncoded, peertubeLocalStorage } from '@app/helpers'
|
||||
import { objectToUrlEncoded, peertubeLocalStorage } from '@root-helpers/index'
|
||||
import { I18n } from '@ngx-translate/i18n-polyfill'
|
||||
import { MyUser as UserServerModel, OAuthClientLocal, User, UserLogin, UserRefreshToken } from '@shared/models'
|
||||
import { environment } from '../../../environments/environment'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { peertubeLocalStorage } from '@app/helpers/peertube-web-storage'
|
||||
import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage'
|
||||
import { LazyLoadEvent, SortMeta } from 'primeng/api'
|
||||
import { RestPagination } from './rest-pagination'
|
||||
import { Subject } from 'rxjs'
|
||||
|
|
|
@ -2,7 +2,8 @@ import { Observable, of, Subject } from 'rxjs'
|
|||
import { first, map, share, shareReplay, switchMap, tap } from 'rxjs/operators'
|
||||
import { HttpClient } from '@angular/common/http'
|
||||
import { Inject, Injectable, LOCALE_ID } from '@angular/core'
|
||||
import { getDevLocale, isOnDevLocale, peertubeLocalStorage, sortBy } from '@app/helpers'
|
||||
import { getDevLocale, isOnDevLocale, sortBy } from '@app/helpers'
|
||||
import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage'
|
||||
import {
|
||||
getCompleteLocale,
|
||||
isDefaultLocale,
|
||||
|
|
|
@ -10,23 +10,10 @@ import {
|
|||
UserRole,
|
||||
VideoChannel
|
||||
} from '@shared/models'
|
||||
import { UserKeys } from '@root-helpers/user-keys'
|
||||
|
||||
export class User implements UserServerModel {
|
||||
static KEYS = {
|
||||
ID: 'id',
|
||||
ROLE: 'role',
|
||||
EMAIL: 'email',
|
||||
VIDEOS_HISTORY_ENABLED: 'videos-history-enabled',
|
||||
USERNAME: 'username',
|
||||
NSFW_POLICY: 'nsfw_policy',
|
||||
WEBTORRENT_ENABLED: 'peertube-videojs-' + 'webtorrent_enabled',
|
||||
AUTO_PLAY_VIDEO: 'auto_play_video',
|
||||
SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO: 'auto_play_next_video',
|
||||
AUTO_PLAY_VIDEO_PLAYLIST: 'auto_play_video_playlist',
|
||||
THEME: 'theme',
|
||||
LAST_ACTIVE_THEME: 'last_active_theme',
|
||||
VIDEO_LANGUAGES: 'video_languages'
|
||||
}
|
||||
static KEYS = UserKeys
|
||||
|
||||
id: number
|
||||
username: string
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Observable, Subject } from 'rxjs'
|
||||
import { filter } from 'rxjs/operators'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { peertubeLocalStorage, peertubeSessionStorage } from '@app/helpers'
|
||||
import { peertubeLocalStorage, peertubeSessionStorage } from '@root-helpers/peertube-web-storage'
|
||||
|
||||
abstract class StorageService {
|
||||
protected instance: Storage
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
export * from './locales'
|
||||
export * from './constants'
|
||||
export * from './i18n-utils'
|
||||
export * from './peertube-web-storage'
|
||||
export * from './utils'
|
||||
export * from './zone'
|
||||
|
|
|
@ -81,15 +81,6 @@ function immutableAssign <A, B> (target: A, source: B) {
|
|||
return Object.assign({}, target, source)
|
||||
}
|
||||
|
||||
function objectToUrlEncoded (obj: any) {
|
||||
const str: string[] = []
|
||||
for (const key of Object.keys(obj)) {
|
||||
str.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]))
|
||||
}
|
||||
|
||||
return str.join('&')
|
||||
}
|
||||
|
||||
// Thanks: https://gist.github.com/ghinda/8442a57f22099bdb2e34
|
||||
function objectToFormData (obj: any, form?: FormData, namespace?: string) {
|
||||
const fd = form || new FormData()
|
||||
|
@ -207,7 +198,6 @@ export {
|
|||
sortBy,
|
||||
durationToString,
|
||||
lineFeedToHtml,
|
||||
objectToUrlEncoded,
|
||||
getParameterByName,
|
||||
populateAsyncUserVideoChannels,
|
||||
getAbsoluteAPIUrl,
|
||||
|
|
|
@ -1,98 +1,9 @@
|
|||
@import 'variables';
|
||||
@import 'mixins';
|
||||
@import 'miniature';
|
||||
|
||||
.table-video-link {
|
||||
@include disable-outline;
|
||||
|
||||
position: relative;
|
||||
top: 3px;
|
||||
}
|
||||
|
||||
.table-comment-link,
|
||||
.table-account-link {
|
||||
@include disable-outline;
|
||||
|
||||
color: var(--mainForegroundColor);
|
||||
|
||||
::ng-deep p:last-child {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.table-account-link {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.comment-flagged-account,
|
||||
.account-flagged-handle {
|
||||
font-size: 11px;
|
||||
color: var(--greyForegroundColor);
|
||||
}
|
||||
|
||||
.table-video {
|
||||
display: inline-flex;
|
||||
|
||||
.table-video-image {
|
||||
@include miniature-thumbnail;
|
||||
|
||||
$image-height: 45px;
|
||||
|
||||
height: $image-height;
|
||||
width: #{(16/9) * $image-height};
|
||||
margin-right: 0.5rem;
|
||||
border-radius: 2px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: pvar(--inputPlaceholderColor);
|
||||
}
|
||||
|
||||
.table-video-image-label {
|
||||
@include static-thumbnail-overlay;
|
||||
position: absolute;
|
||||
border-radius: 3px;
|
||||
font-size: 10px;
|
||||
padding: 0 3px;
|
||||
line-height: 1.3;
|
||||
bottom: 2px;
|
||||
right: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.table-video-text {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
font-size: 90%;
|
||||
color: pvar(--mainForegroundColor);
|
||||
line-height: 1rem;
|
||||
|
||||
div .glyphicon {
|
||||
font-size: 80%;
|
||||
color: gray;
|
||||
margin-left: 0.1rem;
|
||||
}
|
||||
|
||||
div + div {
|
||||
color: var(--greyForegroundColor);
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.abuse-states .glyphicon-comment {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
|
|
@ -65,3 +65,88 @@ my-action-dropdown.show {
|
|||
display: block !important;
|
||||
}
|
||||
}
|
||||
|
||||
.table-video-link {
|
||||
@include disable-outline;
|
||||
|
||||
position: relative;
|
||||
top: 3px;
|
||||
}
|
||||
|
||||
.table-comment-link,
|
||||
.table-account-link {
|
||||
@include disable-outline;
|
||||
|
||||
color: var(--mainForegroundColor);
|
||||
|
||||
::ng-deep p:last-child {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.table-account-link {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.table-video {
|
||||
display: inline-flex;
|
||||
|
||||
.table-video-image {
|
||||
@include miniature-thumbnail;
|
||||
|
||||
$image-height: 45px;
|
||||
|
||||
height: $image-height;
|
||||
width: #{(16/9) * $image-height};
|
||||
margin-right: 0.5rem;
|
||||
border-radius: 2px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: pvar(--inputPlaceholderColor);
|
||||
}
|
||||
|
||||
.table-video-image-label {
|
||||
@include static-thumbnail-overlay;
|
||||
position: absolute;
|
||||
border-radius: 3px;
|
||||
font-size: 10px;
|
||||
padding: 0 3px;
|
||||
line-height: 1.3;
|
||||
bottom: 2px;
|
||||
right: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.table-video-text {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
font-size: 90%;
|
||||
color: pvar(--mainForegroundColor);
|
||||
line-height: 1rem;
|
||||
|
||||
div .glyphicon {
|
||||
font-size: 80%;
|
||||
color: gray;
|
||||
margin-left: 0.1rem;
|
||||
}
|
||||
|
||||
div + div {
|
||||
color: var(--greyForegroundColor);
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import { catchError, map, switchMap } from 'rxjs/operators'
|
|||
import { HttpClient, HttpParams } from '@angular/common/http'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { ComponentPaginationLight, RestExtractor, RestPagination, RestService } from '@app/core'
|
||||
import { peertubeLocalStorage } from '@app/helpers'
|
||||
import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage'
|
||||
import { Video, VideoChannel, VideoChannelService, VideoService } from '@app/shared/shared-main'
|
||||
import { ResultList, SearchTargetType, Video as VideoServerModel, VideoChannel as VideoChannelServerModel } from '@shared/models'
|
||||
import { environment } from '../../../environments/environment'
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
export * from './peertube-web-storage'
|
||||
export * from './utils'
|
||||
export * from './user-keys'
|
||||
export * from './pure-auth-user.model'
|
|
@ -0,0 +1,123 @@
|
|||
// pure version of auth-user, that doesn't import app packages
|
||||
import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage'
|
||||
import {
|
||||
MyUser as ServerMyUserModel,
|
||||
MyUserSpecialPlaylist,
|
||||
NSFWPolicyType,
|
||||
UserRole
|
||||
} from '@shared/models'
|
||||
import { UserKeys } from '@root-helpers/user-keys'
|
||||
|
||||
export type TokenOptions = {
|
||||
accessToken: string
|
||||
refreshToken: string
|
||||
tokenType: string
|
||||
}
|
||||
|
||||
// Private class only used by User
|
||||
export class Tokens {
|
||||
private static KEYS = {
|
||||
ACCESS_TOKEN: 'access_token',
|
||||
REFRESH_TOKEN: 'refresh_token',
|
||||
TOKEN_TYPE: 'token_type'
|
||||
}
|
||||
|
||||
accessToken: string
|
||||
refreshToken: string
|
||||
tokenType: string
|
||||
|
||||
static load () {
|
||||
const accessTokenLocalStorage = peertubeLocalStorage.getItem(this.KEYS.ACCESS_TOKEN)
|
||||
const refreshTokenLocalStorage = peertubeLocalStorage.getItem(this.KEYS.REFRESH_TOKEN)
|
||||
const tokenTypeLocalStorage = peertubeLocalStorage.getItem(this.KEYS.TOKEN_TYPE)
|
||||
|
||||
if (accessTokenLocalStorage && refreshTokenLocalStorage && tokenTypeLocalStorage) {
|
||||
return new Tokens({
|
||||
accessToken: accessTokenLocalStorage,
|
||||
refreshToken: refreshTokenLocalStorage,
|
||||
tokenType: tokenTypeLocalStorage
|
||||
})
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
static flush () {
|
||||
peertubeLocalStorage.removeItem(this.KEYS.ACCESS_TOKEN)
|
||||
peertubeLocalStorage.removeItem(this.KEYS.REFRESH_TOKEN)
|
||||
peertubeLocalStorage.removeItem(this.KEYS.TOKEN_TYPE)
|
||||
}
|
||||
|
||||
constructor (hash?: TokenOptions) {
|
||||
if (hash) {
|
||||
this.accessToken = hash.accessToken
|
||||
this.refreshToken = hash.refreshToken
|
||||
|
||||
if (hash.tokenType === 'bearer') {
|
||||
this.tokenType = 'Bearer'
|
||||
} else {
|
||||
this.tokenType = hash.tokenType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
save () {
|
||||
peertubeLocalStorage.setItem(Tokens.KEYS.ACCESS_TOKEN, this.accessToken)
|
||||
peertubeLocalStorage.setItem(Tokens.KEYS.REFRESH_TOKEN, this.refreshToken)
|
||||
peertubeLocalStorage.setItem(Tokens.KEYS.TOKEN_TYPE, this.tokenType)
|
||||
}
|
||||
}
|
||||
|
||||
export class PureAuthUser {
|
||||
tokens: Tokens
|
||||
specialPlaylists: MyUserSpecialPlaylist[]
|
||||
|
||||
canSeeVideosLink = true
|
||||
|
||||
static load () {
|
||||
const usernameLocalStorage = peertubeLocalStorage.getItem(UserKeys.USERNAME)
|
||||
if (usernameLocalStorage) {
|
||||
return new PureAuthUser(
|
||||
{
|
||||
id: parseInt(peertubeLocalStorage.getItem(UserKeys.ID), 10),
|
||||
username: peertubeLocalStorage.getItem(UserKeys.USERNAME),
|
||||
email: peertubeLocalStorage.getItem(UserKeys.EMAIL),
|
||||
role: parseInt(peertubeLocalStorage.getItem(UserKeys.ROLE), 10) as UserRole,
|
||||
nsfwPolicy: peertubeLocalStorage.getItem(UserKeys.NSFW_POLICY) as NSFWPolicyType,
|
||||
webTorrentEnabled: peertubeLocalStorage.getItem(UserKeys.WEBTORRENT_ENABLED) === 'true',
|
||||
autoPlayVideo: peertubeLocalStorage.getItem(UserKeys.AUTO_PLAY_VIDEO) === 'true',
|
||||
videosHistoryEnabled: peertubeLocalStorage.getItem(UserKeys.VIDEOS_HISTORY_ENABLED) === 'true'
|
||||
},
|
||||
Tokens.load()
|
||||
)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
constructor (userHash: Partial<ServerMyUserModel>, hashTokens: TokenOptions) {
|
||||
this.tokens = new Tokens(hashTokens)
|
||||
this.specialPlaylists = userHash.specialPlaylists
|
||||
}
|
||||
|
||||
getAccessToken () {
|
||||
return this.tokens.accessToken
|
||||
}
|
||||
|
||||
getRefreshToken () {
|
||||
return this.tokens.refreshToken
|
||||
}
|
||||
|
||||
getTokenType () {
|
||||
return this.tokens.tokenType
|
||||
}
|
||||
|
||||
refreshTokens (accessToken: string, refreshToken: string) {
|
||||
this.tokens.accessToken = accessToken
|
||||
this.tokens.refreshToken = refreshToken
|
||||
}
|
||||
|
||||
save () {
|
||||
this.tokens.save()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
export const UserKeys = {
|
||||
ID: 'id',
|
||||
ROLE: 'role',
|
||||
EMAIL: 'email',
|
||||
VIDEOS_HISTORY_ENABLED: 'videos-history-enabled',
|
||||
USERNAME: 'username',
|
||||
NSFW_POLICY: 'nsfw_policy',
|
||||
WEBTORRENT_ENABLED: 'peertube-videojs-' + 'webtorrent_enabled',
|
||||
AUTO_PLAY_VIDEO: 'auto_play_video',
|
||||
SESSION_STORAGE_AUTO_PLAY_NEXT_VIDEO: 'auto_play_next_video',
|
||||
AUTO_PLAY_VIDEO_PLAYLIST: 'auto_play_video_playlist',
|
||||
THEME: 'theme',
|
||||
LAST_ACTIVE_THEME: 'last_active_theme',
|
||||
VIDEO_LANGUAGES: 'video_languages'
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
function objectToUrlEncoded (obj: any) {
|
||||
const str: string[] = []
|
||||
for (const key of Object.keys(obj)) {
|
||||
str.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]))
|
||||
}
|
||||
|
||||
return str.join('&')
|
||||
}
|
||||
|
||||
export {
|
||||
objectToUrlEncoded
|
||||
}
|
|
@ -4,7 +4,8 @@ import {
|
|||
peertubeTranslate,
|
||||
ResultList,
|
||||
ServerConfig,
|
||||
VideoDetails
|
||||
VideoDetails,
|
||||
UserRefreshToken
|
||||
} from '../../../../shared'
|
||||
import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model'
|
||||
import {
|
||||
|
@ -17,7 +18,7 @@ import { PeerTubeEmbedApi } from './embed-api'
|
|||
import { TranslationsManager } from '../../assets/player/translations-manager'
|
||||
import videojs from 'video.js'
|
||||
import { VideoJSCaption } from '../../assets/player/peertube-videojs-typings'
|
||||
import { AuthUser } from '@app/core/auth/auth-user.model'
|
||||
import { PureAuthUser, objectToUrlEncoded, peertubeLocalStorage } from '@root-helpers/index'
|
||||
|
||||
type Translations = { [ id: string ]: string }
|
||||
|
||||
|
@ -43,8 +44,12 @@ export class PeerTubeEmbed {
|
|||
mode: PlayerMode
|
||||
scope = 'peertube'
|
||||
|
||||
user: AuthUser
|
||||
user: PureAuthUser
|
||||
headers = new Headers()
|
||||
LOCAL_STORAGE_OAUTH_CLIENT_KEYS = {
|
||||
CLIENT_ID: 'client_id',
|
||||
CLIENT_SECRET: 'client_secret'
|
||||
}
|
||||
|
||||
static async main () {
|
||||
const videoContainerId = 'video-container'
|
||||
|
@ -60,12 +65,62 @@ export class PeerTubeEmbed {
|
|||
return window.location.origin + '/api/v1/videos/' + id
|
||||
}
|
||||
|
||||
refreshFetch (url: string, options?: Object) {
|
||||
return fetch(url, options)
|
||||
.then((res: Response) => {
|
||||
if (res.status !== 401) return res
|
||||
|
||||
// 401 unauthorized is not catch-ed, but then-ed
|
||||
const error = res
|
||||
|
||||
const refreshingTokenPromise = new Promise((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.user.getRefreshToken(),
|
||||
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 => res.json())
|
||||
.then((obj: UserRefreshToken) => {
|
||||
this.user.refreshTokens(obj.access_token, obj.refresh_token)
|
||||
this.user.save()
|
||||
this.headers.set('Authorization', `${this.user.getTokenType()} ${this.user.getAccessToken()}`)
|
||||
resolve()
|
||||
})
|
||||
.catch((refreshTokenError: any) => {
|
||||
reject(refreshTokenError)
|
||||
})
|
||||
})
|
||||
|
||||
return refreshingTokenPromise
|
||||
.catch(() => {
|
||||
// If refreshing fails, continue with original error
|
||||
throw error
|
||||
})
|
||||
.then(() => fetch(url, {
|
||||
...options,
|
||||
headers: this.headers
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
loadVideoInfo (videoId: string): Promise<Response> {
|
||||
return fetch(this.getVideoUrl(videoId), { headers: this.headers })
|
||||
return this.refreshFetch(this.getVideoUrl(videoId), { headers: this.headers })
|
||||
}
|
||||
|
||||
loadVideoCaptions (videoId: string): Promise<Response> {
|
||||
return fetch(this.getVideoUrl(videoId) + '/captions', { headers: this.headers })
|
||||
return fetch(this.getVideoUrl(videoId) + '/captions')
|
||||
}
|
||||
|
||||
loadConfig (): Promise<Response> {
|
||||
|
@ -115,7 +170,7 @@ export class PeerTubeEmbed {
|
|||
|
||||
async init () {
|
||||
try {
|
||||
this.user = AuthUser.load()
|
||||
this.user = PureAuthUser.load()
|
||||
await this.initCore()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
"video.js": [ "node_modules/video.js/core" ],
|
||||
"@app/*": [ "src/app/*" ],
|
||||
"@shared/*": [ "../shared/*" ],
|
||||
"@root-helpers/*": [ "src/root-helpers/*" ],
|
||||
"fs": [ "src/shims/noop.ts" ],
|
||||
"http": [ "src/shims/http.ts" ],
|
||||
"https": [ "src/shims/https.ts" ],
|
||||
|
|
|
@ -28,7 +28,7 @@ module.exports = function () {
|
|||
|
||||
alias: {
|
||||
'video.js$': path.resolve('node_modules/video.js/core.js'),
|
||||
'@app': path.resolve('src/app'),
|
||||
'@root-helpers': path.resolve('src/root-helpers'),
|
||||
'@shared': path.resolve('../shared')
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue