1
0
Fork 0

Only use account name in routes

This commit is contained in:
Chocobozzz 2018-05-25 09:57:16 +02:00
parent 06be7ed0b2
commit ad9e39fb81
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
28 changed files with 333 additions and 110 deletions

View File

@ -26,7 +26,7 @@ export class AccountVideoChannelsComponent implements OnInit {
this.accountService.accountLoaded this.accountService.accountLoaded
.pipe( .pipe(
tap(account => this.account = account), tap(account => this.account = account),
flatMap(account => this.videoChannelService.listAccountVideoChannels(account.id)), flatMap(account => this.videoChannelService.listAccountVideoChannels(account)),
map(res => res.data) map(res => res.data)
) )
.subscribe(videoChannels => this.videoChannels = videoChannels) .subscribe(videoChannels => this.videoChannels = videoChannels)

View File

@ -52,7 +52,7 @@ export class MyAccountVideoChannelsComponent implements OnInit {
private loadVideoChannels () { private loadVideoChannels () {
this.authService.userInformationLoaded this.authService.userInformationLoaded
.pipe(flatMap(() => this.videoChannelService.listAccountVideoChannels(this.user.account.id))) .pipe(flatMap(() => this.videoChannelService.listAccountVideoChannels(this.user.account)))
.subscribe(res => this.videoChannels = res.data) .subscribe(res => this.videoChannels = res.data)
} }
} }

View File

@ -10,7 +10,7 @@
</div> </div>
<div class="actor-followers">{{ videoChannel.followersCount }} subscribers</div> <div class="actor-followers">{{ videoChannel.followersCount }} subscribers</div>
<a [routerLink]="[ '/accounts', videoChannel.ownerAccount.id ]" title="Go the owner account page" class="actor-owner"> <a [routerLink]="[ '/accounts', videoChannel.ownerBy ]" title="Go the owner account page" class="actor-owner">
<span>Created by {{ videoChannel.ownerBy }}</span> <span>Created by {{ videoChannel.ownerBy }}</span>
<img [src]="videoChannel.ownerAvatarUrl" alt="Owner account avatar" /> <img [src]="videoChannel.ownerAvatarUrl" alt="Owner account avatar" />
</a> </a>

View File

@ -14,7 +14,7 @@
<ul *dropdownMenu class="dropdown-menu"> <ul *dropdownMenu class="dropdown-menu">
<li> <li>
<a i18n [routerLink]="[ '/accounts', user.account?.id ]" class="dropdown-item" title="My public profile"> <a i18n [routerLink]="[ '/accounts', user.account?.nameWithHost ]" class="dropdown-item" title="My public profile">
My public profile My public profile
</a> </a>

View File

@ -4,11 +4,13 @@ import { Actor } from '../actor/actor.model'
export class Account extends Actor implements ServerAccount { export class Account extends Actor implements ServerAccount {
displayName: string displayName: string
description: string description: string
nameWithHost: string
constructor (hash: ServerAccount) { constructor (hash: ServerAccount) {
super(hash) super(hash)
this.displayName = hash.displayName this.displayName = hash.displayName
this.description = hash.description this.description = hash.description
this.nameWithHost = Actor.CREATE_BY_STRING(this.name, this.host)
} }
} }

View File

@ -1,6 +1,14 @@
import { Account, hasUserRight, User as UserServerModel, UserRight, UserRole, VideoChannel } from '../../../../../shared' import {
Account as AccountServerModel,
hasUserRight,
User as UserServerModel,
UserRight,
UserRole,
VideoChannel
} from '../../../../../shared'
import { NSFWPolicyType } from '../../../../../shared/models/videos/nsfw-policy.type' import { NSFWPolicyType } from '../../../../../shared/models/videos/nsfw-policy.type'
import { Actor } from '@app/shared/actor/actor.model' import { Actor } from '@app/shared/actor/actor.model'
import { Account } from '@app/shared/account/account.model'
export type UserConstructorHash = { export type UserConstructorHash = {
id: number, id: number,
@ -11,7 +19,7 @@ export type UserConstructorHash = {
nsfwPolicy?: NSFWPolicyType, nsfwPolicy?: NSFWPolicyType,
autoPlayVideo?: boolean, autoPlayVideo?: boolean,
createdAt?: Date, createdAt?: Date,
account?: Account, account?: AccountServerModel,
videoChannels?: VideoChannel[] videoChannels?: VideoChannel[]
} }
export class User implements UserServerModel { export class User implements UserServerModel {
@ -32,7 +40,10 @@ export class User implements UserServerModel {
this.username = hash.username this.username = hash.username
this.email = hash.email this.email = hash.email
this.role = hash.role this.role = hash.role
this.account = hash.account
if (hash.account !== undefined) {
this.account = new Account(hash.account)
}
if (hash.videoChannels !== undefined) { if (hash.videoChannels !== undefined) {
this.videoChannels = hash.videoChannels this.videoChannels = hash.videoChannels
@ -66,6 +77,10 @@ export class User implements UserServerModel {
this[key] = obj[key] this[key] = obj[key]
} }
if (obj.account !== undefined) {
this.account = new Account(obj.account)
}
this.updateComputedAttributes() this.updateComputedAttributes()
} }

View File

@ -8,6 +8,7 @@ import { AccountService } from '../account/account.service'
import { ResultList } from '../../../../../shared' import { ResultList } from '../../../../../shared'
import { VideoChannel } from './video-channel.model' import { VideoChannel } from './video-channel.model'
import { environment } from '../../../environments/environment' import { environment } from '../../../environments/environment'
import { Account } from '@app/shared/account/account.model'
@Injectable() @Injectable()
export class VideoChannelService { export class VideoChannelService {
@ -29,8 +30,8 @@ export class VideoChannelService {
) )
} }
listAccountVideoChannels (accountId: number): Observable<ResultList<VideoChannel>> { listAccountVideoChannels (account: Account): Observable<ResultList<VideoChannel>> {
return this.authHttp.get<ResultList<VideoChannelServer>>(AccountService.BASE_ACCOUNT_URL + accountId + '/video-channels') return this.authHttp.get<ResultList<VideoChannelServer>>(AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/video-channels')
.pipe( .pipe(
map(res => this.extractVideoChannels(res)), map(res => this.extractVideoChannels(res)),
catchError((res) => this.restExtractor.handleError(res)) catchError((res) => this.restExtractor.handleError(res))

View File

@ -1,7 +1,7 @@
import { UserRight, VideoChannel, VideoDetails as VideoDetailsServerModel, VideoFile } from '../../../../../shared' import { UserRight, VideoChannel, VideoDetails as VideoDetailsServerModel, VideoFile } from '../../../../../shared'
import { Account } from '../../../../../shared/models/actors'
import { AuthUser } from '../../core' import { AuthUser } from '../../core'
import { Video } from '../../shared/video/video.model' import { Video } from '../../shared/video/video.model'
import { Account } from '@app/shared/account/account.model'
export class VideoDetails extends Video implements VideoDetailsServerModel { export class VideoDetails extends Video implements VideoDetailsServerModel {
descriptionPath: string descriptionPath: string
@ -21,7 +21,7 @@ export class VideoDetails extends Video implements VideoDetailsServerModel {
this.descriptionPath = hash.descriptionPath this.descriptionPath = hash.descriptionPath
this.files = hash.files this.files = hash.files
this.channel = hash.channel this.channel = hash.channel
this.account = hash.account this.account = new Account(hash.account)
this.tags = hash.tags this.tags = hash.tags
this.support = hash.support this.support = hash.support
this.commentsEnabled = hash.commentsEnabled this.commentsEnabled = hash.commentsEnabled

View File

@ -10,6 +10,6 @@
</a> </a>
<span class="video-miniature-created-at-views">{{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span> <span class="video-miniature-created-at-views">{{ video.publishedAt | myFromNow }} - {{ video.views | myNumberFormatter }} views</span>
<a class="video-miniature-account" [routerLink]="[ '/accounts', video.account.id ]">{{ video.by }}</a> <a class="video-miniature-account" [routerLink]="[ '/accounts', video.by ]">{{ video.by }}</a>
</div> </div>
</div> </div>

View File

@ -120,7 +120,7 @@ export class VideoService {
params = this.restService.addRestGetParams(params, pagination, sort) params = this.restService.addRestGetParams(params, pagination, sort)
return this.authHttp return this.authHttp
.get(AccountService.BASE_ACCOUNT_URL + account.id + '/videos', { params }) .get(AccountService.BASE_ACCOUNT_URL + account.nameWithHost + '/videos', { params })
.pipe( .pipe(
map(this.extractVideos), map(this.extractVideos),
catchError(res => this.restExtractor.handleError(res)) catchError(res => this.restExtractor.handleError(res))

View File

@ -63,7 +63,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
}), }),
switchMap(video => { switchMap(video => {
return this.videoChannelService return this.videoChannelService
.listAccountVideoChannels(video.account.id) .listAccountVideoChannels(video.account)
.pipe( .pipe(
map(result => result.data), map(result => result.data),
map(videoChannels => videoChannels.map(c => ({ id: c.id, label: c.displayName }))), map(videoChannels => videoChannels.map(c => ({ id: c.id, label: c.displayName }))),

View File

@ -25,7 +25,7 @@
</div> </div>
<div class="video-info-by"> <div class="video-info-by">
<a [routerLink]="[ '/accounts', video.account.id ]" title="Go the account page"> <a [routerLink]="[ '/accounts', video.by ]" title="Go the account page">
<span>By {{ video.by }}</span> <span>By {{ video.by }}</span>
<img [src]="video.accountAvatarUrl" alt="Account avatar" /> <img [src]="video.accountAvatarUrl" alt="Account avatar" />
</a> </a>

View File

@ -8,7 +8,7 @@ import {
setDefaultPagination, setDefaultPagination,
setDefaultSort setDefaultSort
} from '../../middlewares' } from '../../middlewares'
import { accountsGetValidator, accountsSortValidator, videosSortValidator } from '../../middlewares/validators' import { accountsNameWithHostGetValidator, accountsSortValidator, videosSortValidator } from '../../middlewares/validators'
import { AccountModel } from '../../models/account/account' import { AccountModel } from '../../models/account/account'
import { VideoModel } from '../../models/video/video' import { VideoModel } from '../../models/video/video'
import { isNSFWHidden } from '../../helpers/express-utils' import { isNSFWHidden } from '../../helpers/express-utils'
@ -24,13 +24,13 @@ accountsRouter.get('/',
asyncMiddleware(listAccounts) asyncMiddleware(listAccounts)
) )
accountsRouter.get('/:id', accountsRouter.get('/:accountName',
asyncMiddleware(accountsGetValidator), asyncMiddleware(accountsNameWithHostGetValidator),
getAccount getAccount
) )
accountsRouter.get('/:id/videos', accountsRouter.get('/:accountName/videos',
asyncMiddleware(accountsGetValidator), asyncMiddleware(accountsNameWithHostGetValidator),
paginationValidator, paginationValidator,
videosSortValidator, videosSortValidator,
setDefaultSort, setDefaultSort,
@ -39,7 +39,7 @@ accountsRouter.get('/:id/videos',
asyncMiddleware(listAccountVideos) asyncMiddleware(listAccountVideos)
) )
accountsRouter.get('/:accountId/video-channels', accountsRouter.get('/:accountName/video-channels',
asyncMiddleware(listVideoAccountChannelsValidator), asyncMiddleware(listVideoAccountChannelsValidator),
asyncMiddleware(listVideoAccountChannels) asyncMiddleware(listVideoAccountChannels)
) )

View File

@ -10,7 +10,7 @@ servicesRouter.use('/oembed',
asyncMiddleware(oembedValidator), asyncMiddleware(oembedValidator),
generateOEmbed generateOEmbed
) )
servicesRouter.use('/redirect/accounts/:nameWithHost', servicesRouter.use('/redirect/accounts/:accountName',
asyncMiddleware(accountsNameWithHostGetValidator), asyncMiddleware(accountsNameWithHostGetValidator),
redirectToAccountUrl redirectToAccountUrl
) )

View File

@ -5,6 +5,7 @@ import * as validator from 'validator'
import { AccountModel } from '../../models/account/account' import { AccountModel } from '../../models/account/account'
import { isUserDescriptionValid, isUserUsernameValid } from './users' import { isUserDescriptionValid, isUserUsernameValid } from './users'
import { exists } from './misc' import { exists } from './misc'
import { CONFIG } from '../../initializers'
function isAccountNameValid (value: string) { function isAccountNameValid (value: string) {
return isUserUsernameValid(value) return isUserUsernameValid(value)
@ -40,7 +41,7 @@ function isAccountNameWithHostExist (nameWithDomain: string, res: Response, send
const [ accountName, host ] = nameWithDomain.split('@') const [ accountName, host ] = nameWithDomain.split('@')
let promise: Bluebird<AccountModel> let promise: Bluebird<AccountModel>
if (!host) promise = AccountModel.loadLocalByName(accountName) if (!host || host === CONFIG.WEBSERVER.HOST) promise = AccountModel.loadLocalByName(accountName)
else promise = AccountModel.loadLocalByNameAndHost(accountName, host) else promise = AccountModel.loadLocalByNameAndHost(accountName, host)
return isAccountExist(promise, res, sendNotFound) return isAccountExist(promise, res, sendNotFound)

View File

@ -1,15 +1,8 @@
import * as express from 'express' import * as express from 'express'
import { param } from 'express-validator/check' import { param } from 'express-validator/check'
import { import { isAccountNameValid, isAccountNameWithHostExist, isLocalAccountNameExist } from '../../helpers/custom-validators/accounts'
isAccountIdExist,
isAccountIdValid,
isAccountNameValid,
isAccountNameWithHostExist,
isLocalAccountNameExist
} from '../../helpers/custom-validators/accounts'
import { logger } from '../../helpers/logger' import { logger } from '../../helpers/logger'
import { areValidationErrors } from './utils' import { areValidationErrors } from './utils'
import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
const localAccountValidator = [ const localAccountValidator = [
param('name').custom(isAccountNameValid).withMessage('Should have a valid account name'), param('name').custom(isAccountNameValid).withMessage('Should have a valid account name'),
@ -24,32 +17,14 @@ const localAccountValidator = [
} }
] ]
const accountsGetValidator = [
param('id').custom(isAccountIdValid).withMessage('Should have a valid id/uuid/name/name with host'),
async (req: express.Request, res: express.Response, next: express.NextFunction) => {
logger.debug('Checking accountsGetValidator parameters', { parameters: req.params })
if (areValidationErrors(req, res)) return
let accountFetched = false
if (isIdOrUUIDValid(req.params.id)) accountFetched = await isAccountIdExist(req.params.id, res, false)
if (!accountFetched) accountFetched = await isAccountNameWithHostExist(req.params.id, res, true)
if (!accountFetched) return
return next()
}
]
const accountsNameWithHostGetValidator = [ const accountsNameWithHostGetValidator = [
param('nameWithHost').exists().withMessage('Should have an account name with host'), param('accountName').exists().withMessage('Should have an account name with host'),
async (req: express.Request, res: express.Response, next: express.NextFunction) => { async (req: express.Request, res: express.Response, next: express.NextFunction) => {
logger.debug('Checking accountsNameWithHostGetValidator parameters', { parameters: req.params }) logger.debug('Checking accountsNameWithHostGetValidator parameters', { parameters: req.params })
if (areValidationErrors(req, res)) return if (areValidationErrors(req, res)) return
if (!await isAccountNameWithHostExist(req.params.nameWithHost, res)) return if (!await isAccountNameWithHostExist(req.params.accountName, res)) return
return next() return next()
} }
@ -59,6 +34,5 @@ const accountsNameWithHostGetValidator = [
export { export {
localAccountValidator, localAccountValidator,
accountsGetValidator,
accountsNameWithHostGetValidator accountsNameWithHostGetValidator
} }

View File

@ -1,7 +1,7 @@
import * as express from 'express' import * as express from 'express'
import { body, param } from 'express-validator/check' import { body, param } from 'express-validator/check'
import { UserRight } from '../../../shared' import { UserRight } from '../../../shared'
import { isAccountIdExist } from '../../helpers/custom-validators/accounts' import { isAccountIdExist, isAccountNameWithHostExist } from '../../helpers/custom-validators/accounts'
import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
import { import {
isVideoChannelDescriptionValid, isVideoChannelDescriptionValid,
@ -15,13 +15,13 @@ import { VideoChannelModel } from '../../models/video/video-channel'
import { areValidationErrors } from './utils' import { areValidationErrors } from './utils'
const listVideoAccountChannelsValidator = [ const listVideoAccountChannelsValidator = [
param('accountId').custom(isIdOrUUIDValid).withMessage('Should have a valid account id'), param('accountName').exists().withMessage('Should have a valid account name'),
async (req: express.Request, res: express.Response, next: express.NextFunction) => { async (req: express.Request, res: express.Response, next: express.NextFunction) => {
logger.debug('Checking listVideoAccountChannelsValidator parameters', { parameters: req.body }) logger.debug('Checking listVideoAccountChannelsValidator parameters', { parameters: req.body })
if (areValidationErrors(req, res)) return if (areValidationErrors(req, res)) return
if (!await isAccountIdExist(req.params.accountId, res)) return if (!await isAccountNameWithHostExist(req.params.accountName, res)) return
return next() return next()
} }

View File

@ -35,8 +35,8 @@ describe('Test users API validators', function () {
}) })
describe('When getting an account', function () { describe('When getting an account', function () {
it('Should return 404 with a non existing id', async function () { it('Should return 404 with a non existing name', async function () {
await getAccount(server.url, 4545454, 404) await getAccount(server.url, 'arfaze', 404)
}) })
}) })

View File

@ -7,7 +7,8 @@ import {
createUser, createUser,
deleteVideoChannel, deleteVideoChannel,
flushTests, flushTests,
getAccountVideoChannelsList, getMyUserInformation, getAccountVideoChannelsList,
getMyUserInformation,
getVideoChannelsList, getVideoChannelsList,
immutableAssign, immutableAssign,
killallServers, killallServers,
@ -20,7 +21,6 @@ import {
userLogin userLogin
} from '../../utils' } from '../../utils'
import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params' import { checkBadCountPagination, checkBadSortPagination, checkBadStartPagination } from '../../utils/requests/check-api-params'
import { getAccountsList } from '../../utils/users/accounts'
import { User } from '../../../../shared/models/users' import { User } from '../../../../shared/models/users'
const expect = chai.expect const expect = chai.expect
@ -74,12 +74,8 @@ describe('Test video channels API validator', function () {
}) })
describe('When listing account video channels', function () { describe('When listing account video channels', function () {
it('Should fail with bad account', async function () {
await getAccountVideoChannelsList(server.url, 'hello', 400)
})
it('Should fail with a unknown account', async function () { it('Should fail with a unknown account', async function () {
await getAccountVideoChannelsList(server.url, 154, 404) await getAccountVideoChannelsList(server.url, 'unknown', 404)
}) })
}) })

View File

@ -18,7 +18,7 @@ describe('Test videos API validator', function () {
const path = '/api/v1/videos/' const path = '/api/v1/videos/'
let server: ServerInfo let server: ServerInfo
let userAccessToken = '' let userAccessToken = ''
let accountUUID: string let accountName: string
let channelId: number let channelId: number
let channelUUID: string let channelUUID: string
let videoId let videoId
@ -43,7 +43,7 @@ describe('Test videos API validator', function () {
const res = await getMyUserInformation(server.url, server.accessToken) const res = await getMyUserInformation(server.url, server.accessToken)
channelId = res.body.videoChannels[ 0 ].id channelId = res.body.videoChannels[ 0 ].id
channelUUID = res.body.videoChannels[ 0 ].uuid channelUUID = res.body.videoChannels[ 0 ].uuid
accountUUID = res.body.account.uuid accountName = res.body.account.name + '@' + res.body.account.host
} }
}) })
@ -116,7 +116,7 @@ describe('Test videos API validator', function () {
let path: string let path: string
before(async function () { before(async function () {
path = '/api/v1/accounts/' + accountUUID + '/videos' path = '/api/v1/accounts/' + accountName + '/videos'
}) })
it('Should fail with a bad start pagination', async function () { it('Should fail with a bad start pagination', async function () {

View File

@ -26,7 +26,7 @@ const expect = chai.expect
describe('Test users with multiple servers', function () { describe('Test users with multiple servers', function () {
let servers: ServerInfo[] = [] let servers: ServerInfo[] = []
let user: User let user: User
let userAccountUUID: string let userAccountName: string
let userVideoChannelUUID: string let userVideoChannelUUID: string
let userId: number let userId: number
let videoUUID: string let videoUUID: string
@ -56,12 +56,15 @@ describe('Test users with multiple servers', function () {
password: 'password' password: 'password'
} }
const res = await createUser(servers[ 0 ].url, servers[ 0 ].accessToken, user.username, user.password) const res = await createUser(servers[ 0 ].url, servers[ 0 ].accessToken, user.username, user.password)
userAccountUUID = res.body.user.account.uuid
userId = res.body.user.id userId = res.body.user.id
userAccessToken = await userLogin(servers[ 0 ], user) userAccessToken = await userLogin(servers[ 0 ], user)
} }
{
const res = await getMyUserInformation(servers[0].url, userAccessToken)
userAccountName = res.body.account.name + '@' + res.body.account.host
}
{ {
const res = await getMyUserInformation(servers[ 0 ].url, servers[ 0 ].accessToken) const res = await getMyUserInformation(servers[ 0 ].url, servers[ 0 ].accessToken)
const user: User = res.body const user: User = res.body
@ -135,7 +138,7 @@ describe('Test users with multiple servers', function () {
const rootServer1List = resAccounts.body.data.find(a => a.name === 'root' && a.host === 'localhost:9001') as Account const rootServer1List = resAccounts.body.data.find(a => a.name === 'root' && a.host === 'localhost:9001') as Account
expect(rootServer1List).not.to.be.undefined expect(rootServer1List).not.to.be.undefined
const resAccount = await getAccount(server.url, rootServer1List.id) const resAccount = await getAccount(server.url, rootServer1List.name + '@' + rootServer1List.host)
const rootServer1Get = resAccount.body as Account const rootServer1Get = resAccount.body as Account
expect(rootServer1Get.name).to.equal('root') expect(rootServer1Get.name).to.equal('root')
expect(rootServer1Get.host).to.equal('localhost:9001') expect(rootServer1Get.host).to.equal('localhost:9001')
@ -148,7 +151,7 @@ describe('Test users with multiple servers', function () {
it('Should list account videos', async function () { it('Should list account videos', async function () {
for (const server of servers) { for (const server of servers) {
const res = await getAccountVideos(server.url, server.accessToken, userAccountUUID, 0, 5) const res = await getAccountVideos(server.url, server.accessToken, userAccountName, 0, 5)
expect(res.body.total).to.equal(1) expect(res.body.total).to.equal(1)
expect(res.body.data).to.be.an('array') expect(res.body.data).to.be.an('array')
@ -193,7 +196,7 @@ describe('Test users with multiple servers', function () {
it('Should not have actor files', async () => { it('Should not have actor files', async () => {
for (const server of servers) { for (const server of servers) {
await checkActorFilesWereRemoved(userAccountUUID, server.serverNumber) await checkActorFilesWereRemoved(userAccountName, server.serverNumber)
await checkActorFilesWereRemoved(userVideoChannelUUID, server.serverNumber) await checkActorFilesWereRemoved(userVideoChannelUUID, server.serverNumber)
} }
}) })

View File

@ -17,7 +17,6 @@ import {
setAccessTokensToServers, setAccessTokensToServers,
updateVideoChannel updateVideoChannel
} from '../../utils/index' } from '../../utils/index'
import { getAccountsList } from '../../utils/users/accounts'
const expect = chai.expect const expect = chai.expect
@ -99,7 +98,7 @@ describe('Test video channels', function () {
}) })
it('Should have two video channels when getting account channels on server 1', async function () { it('Should have two video channels when getting account channels on server 1', async function () {
const res = await getAccountVideoChannelsList(servers[0].url, userInfo.account.uuid) const res = await getAccountVideoChannelsList(servers[0].url, userInfo.account.name + '@' + userInfo.account.host)
expect(res.body.total).to.equal(2) expect(res.body.total).to.equal(2)
expect(res.body.data).to.be.an('array') expect(res.body.data).to.be.an('array')
expect(res.body.data).to.have.lengthOf(2) expect(res.body.data).to.have.lengthOf(2)
@ -112,7 +111,7 @@ describe('Test video channels', function () {
}) })
it('Should have one video channel when getting account channels on server 2', async function () { it('Should have one video channel when getting account channels on server 2', async function () {
const res = await getAccountVideoChannelsList(servers[1].url, userInfo.account.uuid) const res = await getAccountVideoChannelsList(servers[1].url, userInfo.account.name + '@' + userInfo.account.host)
expect(res.body.total).to.equal(1) expect(res.body.total).to.equal(1)
expect(res.body.data).to.be.an('array') expect(res.body.data).to.be.an('array')
expect(res.body.data).to.have.lengthOf(1) expect(res.body.data).to.have.lengthOf(1)

View File

@ -32,13 +32,13 @@ describe('Test video NSFW policy', function () {
.then(res => { .then(res => {
const user: User = res.body const user: User = res.body
const videoChannelUUID = user.videoChannels[0].uuid const videoChannelUUID = user.videoChannels[0].uuid
const accountUUID = user.account.uuid const accountName = user.account.name + '@' + user.account.host
if (token) { if (token) {
return Promise.all([ return Promise.all([
getVideosListWithToken(server.url, token), getVideosListWithToken(server.url, token),
searchVideoWithToken(server.url, 'n', token), searchVideoWithToken(server.url, 'n', token),
getAccountVideos(server.url, token, accountUUID, 0, 5), getAccountVideos(server.url, token, accountName, 0, 5),
getVideoChannelVideos(server.url, token, videoChannelUUID, 0, 5) getVideoChannelVideos(server.url, token, videoChannelUUID, 0, 5)
]) ])
} }
@ -46,7 +46,7 @@ describe('Test video NSFW policy', function () {
return Promise.all([ return Promise.all([
getVideosList(server.url), getVideosList(server.url),
searchVideo(server.url, 'n'), searchVideo(server.url, 'n'),
getAccountVideos(server.url, undefined, accountUUID, 0, 5), getAccountVideos(server.url, undefined, accountName, 0, 5),
getVideoChannelVideos(server.url, undefined, videoChannelUUID, 0, 5) getVideoChannelVideos(server.url, undefined, videoChannelUUID, 0, 5)
]) ])
}) })

View File

@ -19,8 +19,8 @@ function getAccountsList (url: string, sort = '-createdAt', statusCodeExpected =
}) })
} }
function getAccount (url: string, accountId: number | string, statusCodeExpected = 200) { function getAccount (url: string, accountName: string, statusCodeExpected = 200) {
const path = '/api/v1/accounts/' + accountId const path = '/api/v1/accounts/' + accountName
return makeGetRequest({ return makeGetRequest({
url, url,

View File

@ -16,8 +16,8 @@ function getVideoChannelsList (url: string, start: number, count: number, sort?:
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
} }
function getAccountVideoChannelsList (url: string, accountId: number | string, specialStatus = 200) { function getAccountVideoChannelsList (url: string, accountName: string, specialStatus = 200) {
const path = '/api/v1/accounts/' + accountId + '/video-channels' const path = '/api/v1/accounts/' + accountName + '/video-channels'
return request(url) return request(url)
.get(path) .get(path)

View File

@ -167,8 +167,8 @@ function getMyVideos (url: string, accessToken: string, start: number, count: nu
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
} }
function getAccountVideos (url: string, accessToken: string, accountId: number | string, start: number, count: number, sort?: string) { function getAccountVideos (url: string, accessToken: string, accountName: string, start: number, count: number, sort?: string) {
const path = '/api/v1/accounts/' + accountId + '/videos' const path = '/api/v1/accounts/' + accountName + '/videos'
return makeGetRequest({ return makeGetRequest({
url, url,

View File

@ -25,10 +25,10 @@
<a href="#tag-Accounts">Accounts</a> <a href="#tag-Accounts">Accounts</a>
<ul> <ul>
<li> <li>
<a href="#operation--accounts--id--get"> GET /accounts/{id} </a> <a href="#operation--accounts--name--get"> GET /accounts/{name} </a>
</li> </li>
<li> <li>
<a href="#operation--accounts--id--videos-get"> GET /accounts/{id}/videos </a> <a href="#operation--accounts--name--videos-get"> GET /accounts/{name}/videos </a>
</li> </li>
<li> <li>
<a href="#operation--accounts-get"> GET /accounts </a> <a href="#operation--accounts-get"> GET /accounts </a>
@ -205,7 +205,7 @@
<a href="#operation--video-channels--id--videos-get"> GET /video-channels/{id}/videos </a> <a href="#operation--video-channels--id--videos-get"> GET /video-channels/{id}/videos </a>
</li> </li>
<li> <li>
<a href="#operation--accounts--accountId--video-channels-get"> GET /accounts/{accountId}/video-channels </a> <a href="#operation--accounts--name--video-channels-get"> GET /accounts/{name}/video-channels </a>
</li> </li>
</ul> </ul>
</section> </section>
@ -333,7 +333,7 @@
</div> </div>
</div> </div>
<h1 id="tag-Accounts" class="swagger-summary-tag" data-traverse-target="tag-Accounts">Accounts</h1> <h1 id="tag-Accounts" class="swagger-summary-tag" data-traverse-target="tag-Accounts">Accounts</h1>
<div id="operation--accounts--id--get" class="operation panel" data-traverse-target="operation--accounts--id--get"> <div id="operation--accounts--name--get" class="operation panel" data-traverse-target="operation--accounts--name--get">
<!-- <section class="operation-tags row"> --> <!-- <section class="operation-tags row"> -->
<!-- <div class="doc-copy"> --> <!-- <div class="doc-copy"> -->
<div class="operation-tags"> <div class="operation-tags">
@ -345,7 +345,7 @@
<h2 class="operation-title"> <h2 class="operation-title">
<span class="operation-name"> <span class="operation-name">
<span class="operation-name">GET</span> <span class="operation-name">GET</span>
<span class="operation-path">/accounts/{id}</span> <span class="operation-path">/accounts/{name}</span>
</span> </span>
</h2> </h2>
<div class="doc-row"> <div class="doc-row">
@ -353,7 +353,7 @@
<section class="swagger-request-params"> <section class="swagger-request-params">
<div class="prop-row prop-group"> <div class="prop-row prop-group">
<div class="prop-name"> <div class="prop-name">
<div class="prop-title">id</div> <div class="prop-title">name</div>
<span class="json-property-required"></span> <span class="json-property-required"></span>
<div class="prop-subtitle"> in path </div> <div class="prop-subtitle"> in path </div>
<div class="prop-subtitle"> <div class="prop-subtitle">
@ -362,7 +362,8 @@
</div> </div>
</div> </div>
<div class="prop-value"> <div class="prop-value">
<p>The id of the account</p> <p>The name of the account (chocobozzz or
<a href="mailto:chocobozzz@peertube.cpy.re">chocobozzz@peertube.cpy.re</a> for example)</p>
</div> </div>
</div> </div>
<div class="prop-row prop-group"> <div class="prop-row prop-group">
@ -458,7 +459,7 @@
</div> </div>
</div> </div>
</div> </div>
<div id="operation--accounts--id--videos-get" class="operation panel" data-traverse-target="operation--accounts--id--videos-get"> <div id="operation--accounts--name--videos-get" class="operation panel" data-traverse-target="operation--accounts--name--videos-get">
<!-- <section class="operation-tags row"> --> <!-- <section class="operation-tags row"> -->
<!-- <div class="doc-copy"> --> <!-- <div class="doc-copy"> -->
<div class="operation-tags"> <div class="operation-tags">
@ -470,7 +471,7 @@
<h2 class="operation-title"> <h2 class="operation-title">
<span class="operation-name"> <span class="operation-name">
<span class="operation-name">GET</span> <span class="operation-name">GET</span>
<span class="operation-path">/accounts/{id}/videos</span> <span class="operation-path">/accounts/{name}/videos</span>
</span> </span>
</h2> </h2>
<div class="doc-row"> <div class="doc-row">
@ -478,7 +479,7 @@
<section class="swagger-request-params"> <section class="swagger-request-params">
<div class="prop-row prop-group"> <div class="prop-row prop-group">
<div class="prop-name"> <div class="prop-name">
<div class="prop-title">id</div> <div class="prop-title">name</div>
<span class="json-property-required"></span> <span class="json-property-required"></span>
<div class="prop-subtitle"> in path </div> <div class="prop-subtitle"> in path </div>
<div class="prop-subtitle"> <div class="prop-subtitle">
@ -487,7 +488,8 @@
</div> </div>
</div> </div>
<div class="prop-value"> <div class="prop-value">
<p>The id of the account</p> <p>The name of the account (chocobozzz or
<a href="mailto:chocobozzz@peertube.cpy.re">chocobozzz@peertube.cpy.re</a> for example)</p>
</div> </div>
</div> </div>
</section> </section>
@ -5329,7 +5331,7 @@
</div> </div>
</div> </div>
</div> </div>
<div id="operation--accounts--accountId--video-channels-get" class="operation panel" data-traverse-target="operation--accounts--accountId--video-channels-get"> <div id="operation--accounts--name--video-channels-get" class="operation panel" data-traverse-target="operation--accounts--name--video-channels-get">
<!-- <section class="operation-tags row"> --> <!-- <section class="operation-tags row"> -->
<!-- <div class="doc-copy"> --> <!-- <div class="doc-copy"> -->
<div class="operation-tags"> <div class="operation-tags">
@ -5341,7 +5343,7 @@
<h2 class="operation-title"> <h2 class="operation-title">
<span class="operation-name"> <span class="operation-name">
<span class="operation-name">GET</span> <span class="operation-name">GET</span>
<span class="operation-path">/accounts/{accountId}/video-channels</span> <span class="operation-path">/accounts/{name}/video-channels</span>
</span> </span>
</h2> </h2>
<div class="doc-row"> <div class="doc-row">
@ -5349,7 +5351,7 @@
<section class="swagger-request-params"> <section class="swagger-request-params">
<div class="prop-row prop-group"> <div class="prop-row prop-group">
<div class="prop-name"> <div class="prop-name">
<div class="prop-title">accountId</div> <div class="prop-title">name</div>
<span class="json-property-required"></span> <span class="json-property-required"></span>
<div class="prop-subtitle"> in path </div> <div class="prop-subtitle"> in path </div>
<div class="prop-subtitle"> <div class="prop-subtitle">
@ -5358,7 +5360,8 @@
</div> </div>
</div> </div>
<div class="prop-value"> <div class="prop-value">
<p>The account id </p> <p>The name of the account (chocobozzz or
<a href="mailto:chocobozzz@peertube.cpy.re">chocobozzz@peertube.cpy.re</a> for example)</p>
</div> </div>
</div> </div>
</section> </section>
@ -6403,6 +6406,41 @@
<span class="json-property-type">object</span> <span class="json-property-type">object</span>
<span class="json-property-range" title="Value limits"></span> <span class="json-property-range" title="Value limits"></span>
</dt> </dt>
<dt class="json-inner-schema">
<section class="json-schema-properties">
<dl>
<dt data-property-name="name">
<span class="json-property-name">name:</span>
<span class="json-property-type">string</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
<dt data-property-name="displayName">
<span class="json-property-name">displayName:</span>
<span class="json-property-type">string</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
<dt data-property-name="url">
<span class="json-property-name">url:</span>
<span class="json-property-type">string</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
<dt data-property-name="host">
<span class="json-property-name">host:</span>
<span class="json-property-type">string</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
<dt data-property-name="avatar">
<span class="json-property-name">avatar:</span>
<span class="json-property-type">
<span class="">
<a class="json-schema-ref" href="#/definitions/Avatar">Avatar</a>
</span>
</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
</dl>
</section>
</dt>
</dl> </dl>
</section> </section>
</div> </div>
@ -6494,6 +6532,32 @@
<span class="json-property-type">object</span> <span class="json-property-type">object</span>
<span class="json-property-range" title="Value limits"></span> <span class="json-property-range" title="Value limits"></span>
</dt> </dt>
<dt class="json-inner-schema">
<section class="json-schema-properties">
<dl>
<dt data-property-name="id">
<span class="json-property-name">id:</span>
<span class="json-property-type">number</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
<dt data-property-name="name">
<span class="json-property-name">name:</span>
<span class="json-property-type">string</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
<dt data-property-name="uuid">
<span class="json-property-name">uuid:</span>
<span class="json-property-type">string</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
<dt data-property-name="url">
<span class="json-property-name">url:</span>
<span class="json-property-type">string</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
</dl>
</section>
</dt>
<dt data-property-name="createdAt"> <dt data-property-name="createdAt">
<span class="json-property-name">createdAt:</span> <span class="json-property-name">createdAt:</span>
<span class="json-property-type">string</span> <span class="json-property-type">string</span>
@ -6671,6 +6735,22 @@
<span class="json-property-type">object</span> <span class="json-property-type">object</span>
<span class="json-property-range" title="Value limits"></span> <span class="json-property-range" title="Value limits"></span>
</dt> </dt>
<dt class="json-inner-schema">
<section class="json-schema-properties">
<dl>
<dt data-property-name="id">
<span class="json-property-name">id:</span>
<span class="json-property-type">number</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
<dt data-property-name="uuid">
<span class="json-property-name">uuid:</span>
<span class="json-property-type">string</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
</dl>
</section>
</dt>
</dl> </dl>
</section> </section>
</div> </div>
@ -6830,6 +6910,17 @@
</span> </span>
<span class="json-property-range" title="Value limits"></span> <span class="json-property-range" title="Value limits"></span>
</dt> </dt>
<dt class="json-inner-schema">
<section class="json-schema-array-items">
<span class="json-property-type">
<span class="">
<a class="json-schema-ref" href="#/definitions/VideoCommentThreadTree">VideoCommentThreadTree</a>
</span>
</span>
<span class="json-property-range" title="Value limits"></span>
<div class="json-inner-schema"> </div>
</section>
</dt>
</dl> </dl>
</section> </section>
</div> </div>
@ -7210,6 +7301,17 @@
</span> </span>
<span class="json-property-range" title="Value limits"></span> <span class="json-property-range" title="Value limits"></span>
</dt> </dt>
<dt class="json-inner-schema">
<section class="json-schema-array-items">
<span class="json-property-type">
<span class="">
<a class="json-schema-ref" href="#/definitions/VideoChannel">VideoChannel</a>
</span>
</span>
<span class="json-property-range" title="Value limits"></span>
<div class="json-inner-schema"> </div>
</section>
</dt>
</dl> </dl>
</section> </section>
</div> </div>
@ -7278,21 +7380,124 @@
<span class="json-property-type">object</span> <span class="json-property-type">object</span>
<span class="json-property-range" title="Value limits"></span> <span class="json-property-range" title="Value limits"></span>
</dt> </dt>
<dt class="json-inner-schema">
<section class="json-schema-properties">
<dl>
<dt data-property-name="allowed">
<span class="json-property-name">allowed:</span>
<span class="json-property-type">boolean</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
</dl>
</section>
</dt>
<dt data-property-name="transcoding"> <dt data-property-name="transcoding">
<span class="json-property-name">transcoding:</span> <span class="json-property-name">transcoding:</span>
<span class="json-property-type">object</span> <span class="json-property-type">object</span>
<span class="json-property-range" title="Value limits"></span> <span class="json-property-range" title="Value limits"></span>
</dt> </dt>
<dt class="json-inner-schema">
<section class="json-schema-properties">
<dl>
<dt data-property-name="enabledResolutions">
<span class="json-property-name">enabledResolutions:</span>
<span class="json-property-type">number[]</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
<dt class="json-inner-schema">
<section class="json-schema-array-items">
<span class="json-property-type">number</span>
<span class="json-property-range" title="Value limits"></span>
<div class="json-inner-schema"> </div>
</section>
</dt>
</dl>
</section>
</dt>
<dt data-property-name="avatar"> <dt data-property-name="avatar">
<span class="json-property-name">avatar:</span> <span class="json-property-name">avatar:</span>
<span class="json-property-type">object</span> <span class="json-property-type">object</span>
<span class="json-property-range" title="Value limits"></span> <span class="json-property-range" title="Value limits"></span>
</dt> </dt>
<dt class="json-inner-schema">
<section class="json-schema-properties">
<dl>
<dt data-property-name="file">
<span class="json-property-name">file:</span>
<span class="json-property-type">object</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
<dt class="json-inner-schema">
<section class="json-schema-properties">
<dl>
<dt data-property-name="size">
<span class="json-property-name">size:</span>
<span class="json-property-type">object</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
<dt class="json-inner-schema">
<section class="json-schema-properties">
<dl>
<dt data-property-name="max">
<span class="json-property-name">max:</span>
<span class="json-property-type">number</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
</dl>
</section>
</dt>
</dl>
</section>
</dt>
<dt data-property-name="extensions">
<span class="json-property-name">extensions:</span>
<span class="json-property-type">string[]</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
<dt class="json-inner-schema">
<section class="json-schema-array-items">
<span class="json-property-type">string</span>
<span class="json-property-range" title="Value limits"></span>
<div class="json-inner-schema"> </div>
</section>
</dt>
</dl>
</section>
</dt>
<dt data-property-name="video"> <dt data-property-name="video">
<span class="json-property-name">video:</span> <span class="json-property-name">video:</span>
<span class="json-property-type">object</span> <span class="json-property-type">object</span>
<span class="json-property-range" title="Value limits"></span> <span class="json-property-range" title="Value limits"></span>
</dt> </dt>
<dt class="json-inner-schema">
<section class="json-schema-properties">
<dl>
<dt data-property-name="file">
<span class="json-property-name">file:</span>
<span class="json-property-type">object</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
<dt class="json-inner-schema">
<section class="json-schema-properties">
<dl>
<dt data-property-name="extensions">
<span class="json-property-name">extensions:</span>
<span class="json-property-type">string[]</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
<dt class="json-inner-schema">
<section class="json-schema-array-items">
<span class="json-property-type">string</span>
<span class="json-property-range" title="Value limits"></span>
<div class="json-inner-schema"> </div>
</section>
</dt>
</dl>
</section>
</dt>
</dl>
</section>
</dt>
</dl> </dl>
</section> </section>
</div> </div>
@ -7579,6 +7784,22 @@
<span class="json-property-type">object</span> <span class="json-property-type">object</span>
<span class="json-property-range" title="Value limits"></span> <span class="json-property-range" title="Value limits"></span>
</dt> </dt>
<dt class="json-inner-schema">
<section class="json-schema-properties">
<dl>
<dt data-property-name="id">
<span class="json-property-name">id:</span>
<span class="json-property-type">number</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
<dt data-property-name="uuid">
<span class="json-property-name">uuid:</span>
<span class="json-property-type">string</span>
<span class="json-property-range" title="Value limits"></span>
</dt>
</dl>
</section>
</dt>
</dl> </dl>
</section> </section>
</div> </div>
@ -7624,6 +7845,17 @@
</span> </span>
<span class="json-property-range" title="Value limits"></span> <span class="json-property-range" title="Value limits"></span>
</dt> </dt>
<dt class="json-inner-schema">
<section class="json-schema-array-items">
<span class="json-property-type">
<span class="">
<a class="json-schema-ref" href="#/definitions/VideoComment">VideoComment</a>
</span>
</span>
<span class="json-property-range" title="Value limits"></span>
<div class="json-inner-schema"> </div>
</section>
</dt>
</dl> </dl>
</section> </section>
</div> </div>

View File

@ -16,7 +16,7 @@ basePath: '/api/v1'
schemes: schemes:
- https - https
paths: paths:
'/accounts/{id}': '/accounts/{name}':
get: get:
tags: tags:
- Accounts - Accounts
@ -25,11 +25,11 @@ paths:
produces: produces:
- application/json - application/json
parameters: parameters:
- name: id - name: name
in: path in: path
required: true required: true
type: string type: string
description: 'The id of the account' description: 'The name of the account (chocobozzz or chocobozzz@peertube.cpy.re for example)'
- name: start - name: start
in: query in: query
required: false required: false
@ -50,7 +50,7 @@ paths:
description: successful operation description: successful operation
schema: schema:
$ref: '#/definitions/Account' $ref: '#/definitions/Account'
'/accounts/{id}/videos': '/accounts/{name}/videos':
get: get:
tags: tags:
- Accounts - Accounts
@ -59,11 +59,11 @@ paths:
produces: produces:
- application/json - application/json
parameters: parameters:
- name: id - name: name
in: path in: path
required: true required: true
type: string type: string
description: 'The id of the account' description: 'The name of the account (chocobozzz or chocobozzz@peertube.cpy.re for example)'
responses: responses:
'200': '200':
description: successful operation description: successful operation
@ -1112,7 +1112,7 @@ paths:
description: successful operation description: successful operation
schema: schema:
$ref: '#/definitions/Video' $ref: '#/definitions/Video'
/accounts/{accountId}/video-channels: /accounts/{name}/video-channels:
get: get:
tags: tags:
- VideoChannel - VideoChannel
@ -1121,11 +1121,11 @@ paths:
produces: produces:
- application/json - application/json
parameters: parameters:
- name: accountId - name: name
in: path in: path
required: true required: true
type: string type: string
description: 'The account id ' description: 'The name of the account (chocobozzz or chocobozzz@peertube.cpy.re for example)'
responses: responses:
'200': '200':
description: successful operation description: successful operation