mirror of https://github.com/Chocobozzz/PeerTube
Merge branch 'release/2.2.0' into develop
commit
745437e3ab
|
@ -23,7 +23,7 @@
|
||||||
<th style="width: 100px;" i18n pSortableColumn="state">State <p-sortIcon field="state"></p-sortIcon></th>
|
<th style="width: 100px;" i18n pSortableColumn="state">State <p-sortIcon field="state"></p-sortIcon></th>
|
||||||
<th style="width: 100px;" i18n pSortableColumn="score">Score <p-sortIcon field="score"></p-sortIcon></th>
|
<th style="width: 100px;" i18n pSortableColumn="score">Score <p-sortIcon field="score"></p-sortIcon></th>
|
||||||
<th style="width: 150px;" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
<th style="width: 150px;" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||||
<th style="width: 100px;"></th>
|
<th style="width: 150px;"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<th style="width: 160px;" i18n *ngIf="isDisplayingRemoteVideos()">Strategy</th>
|
<th style="width: 160px;" i18n *ngIf="isDisplayingRemoteVideos()">Strategy</th>
|
||||||
<th i18n pSortableColumn="name">Video <p-sortIcon field="name"></p-sortIcon></th >
|
<th i18n pSortableColumn="name">Video <p-sortIcon field="name"></p-sortIcon></th >
|
||||||
<th style="width: 100px;" i18n *ngIf="isDisplayingRemoteVideos()">Total size</th>
|
<th style="width: 100px;" i18n *ngIf="isDisplayingRemoteVideos()">Total size</th>
|
||||||
<th style="width: 80px;"></th>
|
<th style="width: 150px;"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width: 100%;" i18n>Account</th>
|
<th style="width: 100%;" i18n>Account</th>
|
||||||
<th style="width: 150px;" i18n pSortableColumn="createdAt">Muted at <p-sortIcon field="createdAt"></p-sortIcon></th>
|
<th style="width: 150px;" i18n pSortableColumn="createdAt">Muted at <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||||
<th style="width: 100px;"></th> <!-- column for action buttons -->
|
<th style="width: 150px;"></th> <!-- column for action buttons -->
|
||||||
</tr>
|
</tr>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width: 100%;" i18n>Instance</th>
|
<th style="width: 100%;" i18n>Instance</th>
|
||||||
<th style="width: 150px;" i18n pSortableColumn="createdAt">Muted at <p-sortIcon field="createdAt"></p-sortIcon></th>
|
<th style="width: 150px;" i18n pSortableColumn="createdAt">Muted at <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||||
<th style="width: 100px;"></th> <!-- column for action buttons -->
|
<th style="width: 150px;"></th> <!-- column for action buttons -->
|
||||||
</tr>
|
</tr>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
<th i18n>Video</th>
|
<th i18n>Video</th>
|
||||||
<th style="width: 150px;" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
<th style="width: 150px;" i18n pSortableColumn="createdAt">Created <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||||
<th i18n pSortableColumn="state" style="width: 80px;">State <p-sortIcon field="state"></p-sortIcon></th>
|
<th i18n pSortableColumn="state" style="width: 80px;">State <p-sortIcon field="state"></p-sortIcon></th>
|
||||||
<th style="width: 120px;"></th>
|
<th style="width: 150px;"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
<th style="width: 100px;" i18n>Sensitive</th>
|
<th style="width: 100px;" i18n>Sensitive</th>
|
||||||
<th style="width: 120px;" i18n>Unfederated</th>
|
<th style="width: 120px;" i18n>Unfederated</th>
|
||||||
<th style="width: 150px;" i18n pSortableColumn="createdAt">Date <p-sortIcon field="createdAt"></p-sortIcon></th>
|
<th style="width: 150px;" i18n pSortableColumn="createdAt">Date <p-sortIcon field="createdAt"></p-sortIcon></th>
|
||||||
<th style="width: 120px;"></th>
|
<th style="width: 150px;"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<span class="email">{{ user.pendingEmail }}</span> is awaiting email verification
|
<span class="email">{{ user.pendingEmail }}</span> is awaiting email verification
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form role="form" class="change-email" (ngSubmit)="changeEmail()" [formGroup]="form">
|
<form role="form" class="change-email" (ngSubmit)="changeEmail()" [formGroup]="form" *ngIf="user.pluginAuth === null">
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label i18n for="new-email">New email</label>
|
<label i18n for="new-email">New email</label>
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
<label i18n for="new-email">Your current password</label>
|
||||||
<input
|
<input
|
||||||
type="password" id="password" i18n-placeholder placeholder="Your password" autocomplete="off"
|
type="password" id="password" i18n-placeholder placeholder="Your password" autocomplete="off"
|
||||||
formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" class="form-control"
|
formControlName="password" [ngClass]="{ 'input-error': formErrors['password'] }" class="form-control"
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-row mt-5"> <!-- password grid -->
|
<div class="form-row mt-5" *ngIf="user.pluginAuth === null"> <!-- password grid -->
|
||||||
<div class="form-group col-12 col-lg-4 col-xl-3">
|
<div class="form-group col-12 col-lg-4 col-xl-3">
|
||||||
<div i18n class="account-title">PASSWORD</div>
|
<div i18n class="account-title">PASSWORD</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,7 +10,6 @@ my-search-typeahead {
|
||||||
@include orange-button;
|
@include orange-button;
|
||||||
@include button-with-icon(22px, 3px, -1px);
|
@include button-with-icon(22px, 3px, -1px);
|
||||||
|
|
||||||
color: var(--mainBackgroundColor) !important;
|
|
||||||
margin-right: 25px;
|
margin-right: 25px;
|
||||||
|
|
||||||
@media screen and (max-width: 600px) {
|
@media screen and (max-width: 600px) {
|
||||||
|
|
|
@ -14,7 +14,8 @@ $input-border-radius: 3px;
|
||||||
textarea {
|
textarea {
|
||||||
@include peertube-textarea(100%, 150px);
|
@include peertube-textarea(100%, 150px);
|
||||||
|
|
||||||
background-color: var(--textareaBackgroundColor);
|
background-color: var(--markdownTextareaBackgroundColor);
|
||||||
|
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
|
|
|
@ -47,26 +47,32 @@ try {
|
||||||
peertubeLocalStorage = localStorage
|
peertubeLocalStorage = localStorage
|
||||||
peertubeSessionStorage = sessionStorage
|
peertubeSessionStorage = sessionStorage
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const instance = new MemoryStorage()
|
const instanceLocalStorage = new MemoryStorage()
|
||||||
|
const instanceSessionStorage = new MemoryStorage()
|
||||||
|
|
||||||
peertubeLocalStorage = sessionStorage = new Proxy(instance, {
|
function proxify (instance: MemoryStorage) {
|
||||||
set: function (obj, prop: string | number, value) {
|
return new Proxy(instance, {
|
||||||
if (MemoryStorage.prototype.hasOwnProperty(prop)) {
|
set: function (obj, prop: string | number, value) {
|
||||||
instance[prop] = value
|
if (MemoryStorage.prototype.hasOwnProperty(prop)) {
|
||||||
} else {
|
instance[prop] = value
|
||||||
instance.setItem(prop, value)
|
} else {
|
||||||
|
instance.setItem(prop, value)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
get: function (target, name: string | number) {
|
||||||
|
if (MemoryStorage.prototype.hasOwnProperty(name)) {
|
||||||
|
return instance[name]
|
||||||
|
}
|
||||||
|
if (valuesMap.has(name)) {
|
||||||
|
return instance.getItem(name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true
|
})
|
||||||
},
|
}
|
||||||
get: function (target, name: string | number) {
|
|
||||||
if (MemoryStorage.prototype.hasOwnProperty(name)) {
|
peertubeLocalStorage = proxify(instanceLocalStorage)
|
||||||
return instance[name]
|
peertubeSessionStorage = proxify(instanceSessionStorage)
|
||||||
}
|
|
||||||
if (valuesMap.has(name)) {
|
|
||||||
return instance.getItem(name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
<my-feed [syndicationItems]="syndicationItems"></my-feed>
|
<my-feed [syndicationItems]="syndicationItems"></my-feed>
|
||||||
|
|
||||||
<div ngbDropdown class="d-inline-block ml-4">
|
<div ngbDropdown class="d-inline-block ml-4">
|
||||||
<button class="btn btn-sm btn-outline-secondary" id="dropdownSortComments" ngbDropdownToggle i18n>
|
<button class="btn btn-sm btn-outline-secondary" id="dropdown-sort-comments" ngbDropdownToggle i18n>
|
||||||
SORT BY
|
SORT BY
|
||||||
</button>
|
</button>
|
||||||
<div ngbDropdownMenu aria-labelledby="dropdownSortComments">
|
<div ngbDropdownMenu aria-labelledby="dropdown-sort-comments">
|
||||||
<button (click)="handleSortChange('-createdAt')" ngbDropdownItem i18n>Most recent first (default)</button>
|
<button (click)="handleSortChange('-createdAt')" ngbDropdownItem i18n>Most recent first (default)</button>
|
||||||
<button (click)="handleSortChange('-totalReplies')" ngbDropdownItem i18n>Most replies first</button>
|
<button (click)="handleSortChange('-totalReplies')" ngbDropdownItem i18n>Most replies first</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#dropdownSortComments {
|
#dropdown-sort-comments {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
|
@ -35,10 +35,13 @@ body {
|
||||||
--menuForegroundColor: #{$menu-color};
|
--menuForegroundColor: #{$menu-color};
|
||||||
--submenuColor: #{$sub-menu-color};
|
--submenuColor: #{$sub-menu-color};
|
||||||
|
|
||||||
|
--inputForegroundColor: #{$input-foreground-color};
|
||||||
--inputBackgroundColor: #{$input-background-color};
|
--inputBackgroundColor: #{$input-background-color};
|
||||||
--inputPlaceholderColor: #{$input-placeholder-color};
|
--inputPlaceholderColor: #{$input-placeholder-color};
|
||||||
|
|
||||||
|
--textareaForegroundColor: #{$textarea-foreground-color};
|
||||||
--textareaBackgroundColor: #{$textarea-background-color};
|
--textareaBackgroundColor: #{$textarea-background-color};
|
||||||
|
--markdownTextareaBackgroundColor: #{$markdown-textarea-background-color};
|
||||||
|
|
||||||
--actionButtonColor: #{$grey-foreground-color};
|
--actionButtonColor: #{$grey-foreground-color};
|
||||||
--supportButtonBackgroundColor: #{transparent};
|
--supportButtonBackgroundColor: #{transparent};
|
||||||
|
|
|
@ -37,6 +37,8 @@ $icon-font-path: '~@neos21/bootstrap3-glyphicons/assets/fonts/';
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu {
|
.dropdown-menu {
|
||||||
|
z-index: z(dropdown) + 1 !important;
|
||||||
|
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
|
|
@ -90,7 +90,8 @@
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: $button-height;
|
height: $button-height;
|
||||||
width: $width;
|
width: $width;
|
||||||
background: var(--inputBackgroundColor);
|
color: var(--inputForegroundColor);
|
||||||
|
background-color: var(--inputBackgroundColor);
|
||||||
border: 1px solid #C6C6C6;
|
border: 1px solid #C6C6C6;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding-left: 15px;
|
padding-left: 15px;
|
||||||
|
@ -121,6 +122,8 @@
|
||||||
@mixin peertube-textarea ($width, $height) {
|
@mixin peertube-textarea ($width, $height) {
|
||||||
@include peertube-input-text($width);
|
@include peertube-input-text($width);
|
||||||
|
|
||||||
|
color: var(--textareaForegroundColor);
|
||||||
|
background-color: var(--textareaBackgroundColor);
|
||||||
height: $height;
|
height: $height;
|
||||||
padding: 5px 15px;
|
padding: 5px 15px;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
@ -280,6 +283,7 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
width: $width;
|
width: $width;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
color: var(--inputForegroundColor);
|
||||||
background: var(--inputBackgroundColor);
|
background: var(--inputBackgroundColor);
|
||||||
position: relative;
|
position: relative;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
|
|
@ -63,10 +63,13 @@ $video-thumbnail-ratio: $video-thumbnail-width / $video-thumbnail-height;
|
||||||
|
|
||||||
$theater-bottom-space: 115px;
|
$theater-bottom-space: 115px;
|
||||||
|
|
||||||
|
$input-foreground-color: $fg-color;
|
||||||
$input-background-color: $bg-color;
|
$input-background-color: $bg-color;
|
||||||
$input-placeholder-color: #898989;
|
$input-placeholder-color: #898989;
|
||||||
|
|
||||||
$textarea-background-color: $grey-background-hover-color;
|
$textarea-foreground-color: $fg-color;
|
||||||
|
$textarea-background-color: $bg-color;
|
||||||
|
$markdown-textarea-background-color: $grey-background-hover-color;
|
||||||
|
|
||||||
$sub-menu-margin-bottom: 30px;
|
$sub-menu-margin-bottom: 30px;
|
||||||
$sub-menu-margin-bottom-small-view: 10px;
|
$sub-menu-margin-bottom-small-view: 10px;
|
||||||
|
@ -92,10 +95,13 @@ $variables: (
|
||||||
--menuForegroundColor: var(--menuForegroundColor),
|
--menuForegroundColor: var(--menuForegroundColor),
|
||||||
--submenuColor: var(--submenuColor),
|
--submenuColor: var(--submenuColor),
|
||||||
|
|
||||||
|
--inputForegroundColor: var(--inputForegroundColor),
|
||||||
--inputBackgroundColor: var(--inputBackgroundColor),
|
--inputBackgroundColor: var(--inputBackgroundColor),
|
||||||
--inputPlaceholderColor: var(--inputPlaceholderColor),
|
--inputPlaceholderColor: var(--inputPlaceholderColor),
|
||||||
|
|
||||||
|
--textareaForegroundColor: var(--textareaForegroundColor),
|
||||||
--textareaBackgroundColor: var(--textareaBackgroundColor),
|
--textareaBackgroundColor: var(--textareaBackgroundColor),
|
||||||
|
--markdownTextareaBackgroundColor: var(--markdownTextareaBackgroundColor),
|
||||||
|
|
||||||
--actionButtonColor: var(--actionButtonColor),
|
--actionButtonColor: var(--actionButtonColor),
|
||||||
--supportButtonColor: var(--supportButtonColor),
|
--supportButtonColor: var(--supportButtonColor),
|
||||||
|
|
|
@ -140,13 +140,13 @@ p-table {
|
||||||
font-size: 11px !important;
|
font-size: 11px !important;
|
||||||
top: 0 !important;
|
top: 0 !important;
|
||||||
|
|
||||||
&.pi-sort-up {
|
&.pi-sort-amount-up-alt {
|
||||||
@extend .glyphicon-triangle-top;
|
@extend .glyphicon-triangle-top;
|
||||||
|
|
||||||
color: var(--mainForegroundColor) !important;
|
color: var(--mainForegroundColor) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.pi-sort-down {
|
&.pi-sort-amount-down {
|
||||||
@extend .glyphicon-triangle-bottom;
|
@extend .glyphicon-triangle-bottom;
|
||||||
|
|
||||||
color: var(--mainForegroundColor) !important;
|
color: var(--mainForegroundColor) !important;
|
||||||
|
@ -345,7 +345,7 @@ p-multiselect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.pi.pi-chevron-down{
|
.pi.pi-chevron-down {
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
|
|
|
@ -14,6 +14,7 @@ import { UserAdminFlag } from '@shared/models/users/user-flag.model'
|
||||||
import { createUserAccountAndChannelAndPlaylist } from './user'
|
import { createUserAccountAndChannelAndPlaylist } from './user'
|
||||||
import { UserRole } from '@shared/models/users/user-role'
|
import { UserRole } from '@shared/models/users/user-role'
|
||||||
import { PluginManager } from '@server/lib/plugins/plugin-manager'
|
import { PluginManager } from '@server/lib/plugins/plugin-manager'
|
||||||
|
import { ActorModel } from '@server/models/activitypub/actor'
|
||||||
|
|
||||||
type TokenInfo = { accessToken: string, refreshToken: string, accessTokenExpiresAt: Date, refreshTokenExpiresAt: Date }
|
type TokenInfo = { accessToken: string, refreshToken: string, accessTokenExpiresAt: Date, refreshTokenExpiresAt: Date }
|
||||||
|
|
||||||
|
@ -109,6 +110,9 @@ async function getUser (usernameOrEmail?: string, password?: string) {
|
||||||
let user = await UserModel.loadByEmail(obj.user.email)
|
let user = await UserModel.loadByEmail(obj.user.email)
|
||||||
if (!user) user = await createUserFromExternal(obj.pluginName, obj.user)
|
if (!user) user = await createUserFromExternal(obj.pluginName, obj.user)
|
||||||
|
|
||||||
|
// Cannot create a user
|
||||||
|
if (!user) throw new AccessDeniedError('Cannot create such user: an actor with that name already exists.')
|
||||||
|
|
||||||
// If the user does not belongs to a plugin, it was created before its installation
|
// If the user does not belongs to a plugin, it was created before its installation
|
||||||
// Then we just go through a regular login process
|
// Then we just go through a regular login process
|
||||||
if (user.pluginAuth !== null) {
|
if (user.pluginAuth !== null) {
|
||||||
|
@ -208,6 +212,10 @@ async function createUserFromExternal (pluginAuth: string, options: {
|
||||||
role: UserRole
|
role: UserRole
|
||||||
displayName: string
|
displayName: string
|
||||||
}) {
|
}) {
|
||||||
|
// Check an actor does not already exists with that name (removed user)
|
||||||
|
const actor = await ActorModel.loadLocalByName(options.username)
|
||||||
|
if (actor) return null
|
||||||
|
|
||||||
const userToCreate = new UserModel({
|
const userToCreate = new UserModel({
|
||||||
username: options.username,
|
username: options.username,
|
||||||
password: null,
|
password: null,
|
||||||
|
|
|
@ -234,14 +234,19 @@ const usersUpdateMeValidator = [
|
||||||
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||||
logger.debug('Checking usersUpdateMe parameters', { parameters: omit(req.body, 'password') })
|
logger.debug('Checking usersUpdateMe parameters', { parameters: omit(req.body, 'password') })
|
||||||
|
|
||||||
|
const user = res.locals.oauth.token.User
|
||||||
|
|
||||||
if (req.body.password || req.body.email) {
|
if (req.body.password || req.body.email) {
|
||||||
|
if (user.pluginAuth !== null) {
|
||||||
|
return res.status(400)
|
||||||
|
.json({ error: 'You cannot update your email or password that is associated with an external auth system.' })
|
||||||
|
}
|
||||||
|
|
||||||
if (!req.body.currentPassword) {
|
if (!req.body.currentPassword) {
|
||||||
return res.status(400)
|
return res.status(400)
|
||||||
.json({ error: 'currentPassword parameter is missing.' })
|
.json({ error: 'currentPassword parameter is missing.' })
|
||||||
.end()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = res.locals.oauth.token.User
|
|
||||||
if (await user.isPasswordMatch(req.body.currentPassword) !== true) {
|
if (await user.isPasswordMatch(req.body.currentPassword) !== true) {
|
||||||
return res.status(401)
|
return res.status(401)
|
||||||
.json({ error: 'currentPassword is invalid.' })
|
.json({ error: 'currentPassword is invalid.' })
|
||||||
|
|
|
@ -1044,7 +1044,7 @@ describe('Test users API validators', function () {
|
||||||
}
|
}
|
||||||
await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { targetUrl: getYoutubeVideoUrl() }))
|
await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { targetUrl: getYoutubeVideoUrl() }))
|
||||||
await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { magnetUri: getMagnetURI() }))
|
await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { magnetUri: getMagnetURI() }))
|
||||||
await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { torrentfile: 'video-720p.torrent' }))
|
await importVideo(server.url, server.accessToken, immutableAssign(baseAttributes, { torrentfile: 'video-720p.torrent' as any }))
|
||||||
|
|
||||||
await waitJobs([ server ])
|
await waitJobs([ server ])
|
||||||
|
|
||||||
|
|
|
@ -175,7 +175,7 @@ Ajouter un sous-titre est vraiment facile`)
|
||||||
|
|
||||||
{
|
{
|
||||||
const attributes = immutableAssign(baseAttributes, {
|
const attributes = immutableAssign(baseAttributes, {
|
||||||
torrentfile: 'video-720p.torrent',
|
torrentfile: 'video-720p.torrent' as any,
|
||||||
description: 'this is a super torrent description',
|
description: 'this is a super torrent description',
|
||||||
tags: [ 'tag_torrent1', 'tag_torrent2' ]
|
tags: [ 'tag_torrent1', 'tag_torrent2' ]
|
||||||
})
|
})
|
||||||
|
|
|
@ -255,6 +255,16 @@ describe('Test external auth plugins', function () {
|
||||||
expect(body.role).to.equal(UserRole.USER)
|
expect(body.role).to.equal(UserRole.USER)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('Should not update an external auth email', async function () {
|
||||||
|
await updateMyUser({
|
||||||
|
url: server.url,
|
||||||
|
accessToken: cyanAccessToken,
|
||||||
|
email: 'toto@example.com',
|
||||||
|
currentPassword: 'toto',
|
||||||
|
statusCodeExpected: 400
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('Should reject token of Kefka by the plugin hook', async function () {
|
it('Should reject token of Kefka by the plugin hook', async function () {
|
||||||
this.timeout(10000)
|
this.timeout(10000)
|
||||||
|
|
||||||
|
|
|
@ -216,7 +216,7 @@ function unblockUser (url: string, userId: number | string, accessToken: string,
|
||||||
.expect(expectedStatus)
|
.expect(expectedStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateMyUser (options: { url: string, accessToken: string } & UserUpdateMe) {
|
function updateMyUser (options: { url: string, accessToken: string, statusCodeExpected?: number } & UserUpdateMe) {
|
||||||
const path = '/api/v1/users/me'
|
const path = '/api/v1/users/me'
|
||||||
|
|
||||||
const toSend: UserUpdateMe = omit(options, 'url', 'accessToken')
|
const toSend: UserUpdateMe = omit(options, 'url', 'accessToken')
|
||||||
|
@ -226,7 +226,7 @@ function updateMyUser (options: { url: string, accessToken: string } & UserUpdat
|
||||||
path,
|
path,
|
||||||
token: options.accessToken,
|
token: options.accessToken,
|
||||||
fields: toSend,
|
fields: toSend,
|
||||||
statusCodeExpected: 204
|
statusCodeExpected: options.statusCodeExpected || 204
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue