expliciting type checks and predicates (server only)
This commit is contained in:
parent
5f7021c33d
commit
c1e791bad0
|
@ -67,8 +67,8 @@ async function activityPubCollectionPagination (url: string, handler: ActivityPu
|
|||
const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE)
|
||||
const result = await handler(start, count)
|
||||
|
||||
let next: string
|
||||
let prev: string
|
||||
let next: string | undefined
|
||||
let prev: string | undefined
|
||||
|
||||
// Assert page is a number
|
||||
page = parseInt(page, 10)
|
||||
|
|
|
@ -42,7 +42,7 @@ function root () {
|
|||
const paths = [ __dirname, '..', '..' ]
|
||||
|
||||
// We are under /dist directory
|
||||
if (process.mainModule.filename.endsWith('.ts') === false) {
|
||||
if (process.mainModule && process.mainModule.filename.endsWith('.ts') === false) {
|
||||
paths.push('..')
|
||||
}
|
||||
|
||||
|
@ -143,6 +143,7 @@ const renamePromise = promisify2WithVoid<string, string>(rename)
|
|||
const writeFilePromise = promisify2WithVoid<string, any>(writeFile)
|
||||
const readdirPromise = promisify1<string, string[]>(readdir)
|
||||
const mkdirpPromise = promisify1<string, string>(mkdirp)
|
||||
// we cannot modify the Promise types, so we should make the promisify instance check mkdirp
|
||||
const pseudoRandomBytesPromise = promisify1<number, Buffer>(pseudoRandomBytes)
|
||||
const createPrivateKey = promisify1<number, { key: string }>(pem.createPrivateKey)
|
||||
const getPublicKey = promisify1<string, { publicKey: string }>(pem.getPublicKey)
|
||||
|
|
|
@ -51,7 +51,7 @@ function isFileValid (
|
|||
files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[],
|
||||
mimeTypeRegex: string,
|
||||
field: string,
|
||||
maxSize: number,
|
||||
maxSize: number | null,
|
||||
optional = false
|
||||
) {
|
||||
// Should have files
|
||||
|
@ -69,7 +69,7 @@ function isFileValid (
|
|||
if (!file || !file.originalname) return false
|
||||
|
||||
// Check size
|
||||
if (maxSize && file.size > maxSize) return false
|
||||
if ((maxSize !== null) && file.size > maxSize) return false
|
||||
|
||||
return new RegExp(`^${mimeTypeRegex}$`, 'i').test(file.mimetype)
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ function checkUserCanManageVideo (user: UserModel, video: VideoModel, right: Use
|
|||
}
|
||||
|
||||
async function isVideoExist (id: string, res: Response) {
|
||||
let video: VideoModel
|
||||
let video: VideoModel | null
|
||||
|
||||
if (validator.isInt(id)) {
|
||||
video = await VideoModel.loadAndPopulateAccountAndServerAndTags(+id)
|
||||
|
@ -158,7 +158,7 @@ async function isVideoExist (id: string, res: Response) {
|
|||
video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(id)
|
||||
}
|
||||
|
||||
if (!video) {
|
||||
if (video && video !== null) {
|
||||
res.status(404)
|
||||
.json({ error: 'Video not found' })
|
||||
.end()
|
||||
|
@ -173,7 +173,7 @@ async function isVideoExist (id: string, res: Response) {
|
|||
async function isVideoChannelOfAccountExist (channelId: number, user: UserModel, res: Response) {
|
||||
if (user.hasRight(UserRight.UPDATE_ANY_VIDEO) === true) {
|
||||
const videoChannel = await VideoChannelModel.loadAndPopulateAccount(channelId)
|
||||
if (!videoChannel) {
|
||||
if (videoChannel && videoChannel !== null) {
|
||||
res.status(400)
|
||||
.json({ error: 'Unknown video video channel on this instance.' })
|
||||
.end()
|
||||
|
@ -186,7 +186,7 @@ async function isVideoChannelOfAccountExist (channelId: number, user: UserModel,
|
|||
}
|
||||
|
||||
const videoChannel = await VideoChannelModel.loadByIdAndAccount(channelId, user.Account.id)
|
||||
if (!videoChannel) {
|
||||
if (videoChannel && videoChannel !== null) {
|
||||
res.status(400)
|
||||
.json({ error: 'Unknown video video channel for this account.' })
|
||||
.end()
|
||||
|
|
|
@ -64,7 +64,7 @@ function createReqFiles (
|
|||
}
|
||||
})
|
||||
|
||||
const fields = []
|
||||
let fields: { name: string, maxCount: number }[] = []
|
||||
for (const fieldName of fieldNames) {
|
||||
fields.push({
|
||||
name: fieldName,
|
||||
|
|
|
@ -80,7 +80,8 @@ const logger = winston.createLogger({
|
|||
function bunyanLogFactory (level: string) {
|
||||
return function () {
|
||||
let meta = null
|
||||
let args = [].concat(arguments)
|
||||
let args: any[] = []
|
||||
args.concat(arguments)
|
||||
|
||||
if (arguments[ 0 ] instanceof Error) {
|
||||
meta = arguments[ 0 ].toString()
|
||||
|
|
|
@ -52,7 +52,7 @@ async function isSignupAllowed () {
|
|||
function isSignupAllowedForCurrentIP (ip: string) {
|
||||
const addr = ipaddr.parse(ip)
|
||||
let excludeList = [ 'blacklist' ]
|
||||
let matched: string
|
||||
let matched = ''
|
||||
|
||||
// if there is a valid, non-empty whitelist, we exclude all unknown adresses too
|
||||
if (CONFIG.SIGNUP.FILTERS.CIDR.WHITELIST.filter(cidr => isCidr(cidr)).length > 0) {
|
||||
|
@ -144,6 +144,7 @@ let serverActor: ActorModel
|
|||
async function getServerActor () {
|
||||
if (serverActor === undefined) {
|
||||
const application = await ApplicationModel.load()
|
||||
if (!application) throw Error('Could not application.')
|
||||
serverActor = application.Account.Actor
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ function createDirectoriesIfNotExist () {
|
|||
const cacheDirectories = Object.keys(CACHE)
|
||||
.map(k => CACHE[k].DIRECTORY)
|
||||
|
||||
const tasks = []
|
||||
const tasks: Promise<string>[] = []
|
||||
for (const key of Object.keys(storage)) {
|
||||
const dir = storage[key]
|
||||
tasks.push(mkdirpPromise(dir))
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
import * as Promise from 'bluebird'
|
||||
import { Migration } from '../../models/migrations'
|
||||
|
||||
function up (utils: {
|
||||
transaction: Sequelize.Transaction,
|
||||
|
@ -12,7 +13,7 @@ function up (utils: {
|
|||
type: Sequelize.STRING(400),
|
||||
allowNull: false,
|
||||
defaultValue: ''
|
||||
}
|
||||
} as Migration.String
|
||||
|
||||
return q.addColumn('Pods', 'email', data)
|
||||
.then(() => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
import * as Promise from 'bluebird'
|
||||
import { Migration } from '../../models/migrations'
|
||||
|
||||
function up (utils: {
|
||||
transaction: Sequelize.Transaction,
|
||||
|
@ -12,7 +13,7 @@ function up (utils: {
|
|||
type: Sequelize.STRING(400),
|
||||
allowNull: false,
|
||||
defaultValue: ''
|
||||
}
|
||||
} as Migration.String
|
||||
return q.addColumn('Users', 'email', data)
|
||||
.then(() => {
|
||||
const query = 'UPDATE "Users" SET "email" = CONCAT("username", \'@example.com\')'
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
import * as Promise from 'bluebird'
|
||||
import { Migration } from '../../models/migrations'
|
||||
|
||||
function up (utils: {
|
||||
transaction: Sequelize.Transaction,
|
||||
|
@ -12,7 +13,7 @@ function up (utils: {
|
|||
type: Sequelize.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 0
|
||||
}
|
||||
} as Migration.Integer
|
||||
|
||||
return q.addColumn('Videos', 'category', data)
|
||||
.then(() => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
import * as Promise from 'bluebird'
|
||||
import { Migration } from '../../models/migrations'
|
||||
|
||||
function up (utils: {
|
||||
transaction: Sequelize.Transaction,
|
||||
|
@ -12,7 +13,7 @@ function up (utils: {
|
|||
type: Sequelize.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 0
|
||||
}
|
||||
} as Migration.Integer
|
||||
|
||||
return q.addColumn('Videos', 'licence', data)
|
||||
.then(() => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
import * as Promise from 'bluebird'
|
||||
import { Migration } from '../../models/migrations'
|
||||
|
||||
function up (utils: {
|
||||
transaction: Sequelize.Transaction,
|
||||
|
@ -12,7 +13,7 @@ function up (utils: {
|
|||
type: Sequelize.BOOLEAN,
|
||||
allowNull: false,
|
||||
defaultValue: false
|
||||
}
|
||||
} as Migration.Boolean
|
||||
|
||||
return q.addColumn('Videos', 'nsfw', data)
|
||||
.then(() => {
|
||||
|
|
|
@ -24,7 +24,7 @@ function up (utils: {
|
|||
return utils.sequelize.query(query)
|
||||
})
|
||||
.then(() => {
|
||||
dataUUID.defaultValue = null
|
||||
dataUUID.defaultValue = null // FIXME:default value cannot be null if string
|
||||
|
||||
return q.changeColumn('Videos', 'uuid', dataUUID)
|
||||
})
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
import * as Promise from 'bluebird'
|
||||
import { Migration } from '../../models/migrations'
|
||||
|
||||
function up (utils: {
|
||||
transaction: Sequelize.Transaction,
|
||||
|
@ -13,7 +14,7 @@ function up (utils: {
|
|||
type: Sequelize.BIGINT,
|
||||
allowNull: false,
|
||||
defaultValue: -1
|
||||
}
|
||||
} as Migration.BigInteger
|
||||
|
||||
return q.addColumn('Users', 'videoQuota', data)
|
||||
.then(() => {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
import { Migration } from '../../models/migrations'
|
||||
|
||||
async function up (utils: {
|
||||
transaction: Sequelize.Transaction,
|
||||
|
@ -9,7 +10,7 @@ async function up (utils: {
|
|||
type: Sequelize.BOOLEAN,
|
||||
allowNull: false,
|
||||
defaultValue: true
|
||||
}
|
||||
} as Migration.Boolean
|
||||
await utils.queryInterface.addColumn('video', 'commentsEnabled', data)
|
||||
|
||||
data.defaultValue = null
|
||||
|
|
|
@ -2,6 +2,7 @@ import * as Sequelize from 'sequelize'
|
|||
import { createClient } from 'redis'
|
||||
import { CONFIG } from '../constants'
|
||||
import { JobQueue } from '../../lib/job-queue'
|
||||
import { Redis } from '../../lib/redis'
|
||||
import { initDatabaseModels } from '../database'
|
||||
|
||||
async function up (utils: {
|
||||
|
@ -12,11 +13,7 @@ async function up (utils: {
|
|||
await initDatabaseModels(false)
|
||||
|
||||
return new Promise((res, rej) => {
|
||||
const client = createClient({
|
||||
host: CONFIG.REDIS.HOSTNAME,
|
||||
port: CONFIG.REDIS.PORT,
|
||||
db: CONFIG.REDIS.DB
|
||||
})
|
||||
const client = createClient(Redis.getRedisClient())
|
||||
|
||||
const jobsPrefix = 'q-' + CONFIG.WEBSERVER.HOST
|
||||
|
||||
|
@ -36,7 +33,7 @@ async function up (utils: {
|
|||
return res({ type: job.type, payload: parsedData })
|
||||
} catch (err) {
|
||||
console.error('Cannot parse data %s.', job.data)
|
||||
return res(null)
|
||||
return res(undefined)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
@ -11,7 +11,7 @@ async function migrate () {
|
|||
// The installer will do that
|
||||
if (tables.length === 0) return
|
||||
|
||||
let actualVersion: number = null
|
||||
let actualVersion: number | null = null
|
||||
|
||||
const [ rows ] = await sequelizeTypescript.query('SELECT "migrationVersion" FROM "application"')
|
||||
if (rows && rows[0] && rows[0].migrationVersion) {
|
||||
|
|
|
@ -20,7 +20,7 @@ function getVideoCommentAudience (
|
|||
isOrigin = false
|
||||
) {
|
||||
const to = [ ACTIVITY_PUB.PUBLIC ]
|
||||
const cc = []
|
||||
const cc: string[] = []
|
||||
|
||||
// Owner of the video we comment
|
||||
if (isOrigin === false) {
|
||||
|
@ -60,8 +60,8 @@ function getAudience (actorSender: ActorModel, isPublic = true) {
|
|||
}
|
||||
|
||||
function buildAudience (followerUrls: string[], isPublic = true) {
|
||||
let to = []
|
||||
let cc = []
|
||||
let to: string[] = []
|
||||
let cc: string[] = []
|
||||
|
||||
if (isPublic) {
|
||||
to = [ ACTIVITY_PUB.PUBLIC ]
|
||||
|
|
|
@ -88,17 +88,17 @@ async function videoActivityObjectToDBAttributes (
|
|||
const privacy = to.indexOf(ACTIVITY_PUB.PUBLIC) !== -1 ? VideoPrivacy.PUBLIC : VideoPrivacy.UNLISTED
|
||||
const duration = videoObject.duration.replace(/[^\d]+/, '')
|
||||
|
||||
let language: string = null
|
||||
let language: string | undefined
|
||||
if (videoObject.language) {
|
||||
language = videoObject.language.identifier
|
||||
}
|
||||
|
||||
let category: number = null
|
||||
let category: number | undefined
|
||||
if (videoObject.category) {
|
||||
category = parseInt(videoObject.category.identifier, 10)
|
||||
}
|
||||
|
||||
let licence: number = null
|
||||
let licence: number | undefined
|
||||
if (videoObject.licence) {
|
||||
licence = parseInt(videoObject.licence.identifier, 10)
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ function videoFileActivityUrlToDBAttributes (videoCreated: VideoModel, videoObje
|
|||
throw new Error('Cannot find video files for ' + videoCreated.url)
|
||||
}
|
||||
|
||||
const attributes = []
|
||||
const attributes: VideoFileModel[] = []
|
||||
for (const fileUrl of fileUrls) {
|
||||
// Fetch associated magnet uri
|
||||
const magnet = videoObject.url.find(u => {
|
||||
|
@ -153,7 +153,11 @@ function videoFileActivityUrlToDBAttributes (videoCreated: VideoModel, videoObje
|
|||
if (!magnet) throw new Error('Cannot find associated magnet uri for file ' + fileUrl.href)
|
||||
|
||||
const parsed = magnetUtil.decode(magnet.href)
|
||||
if (!parsed || isVideoFileInfoHashValid(parsed.infoHash) === false) throw new Error('Cannot parse magnet URI ' + magnet.href)
|
||||
if (!parsed ||
|
||||
(parsed.infoHash &&
|
||||
(isVideoFileInfoHashValid(parsed.infoHash) === false))) {
|
||||
throw new Error('Cannot parse magnet URI ' + magnet.href)
|
||||
}
|
||||
|
||||
const attribute = {
|
||||
extname: VIDEO_MIMETYPE_EXT[ fileUrl.mimeType ],
|
||||
|
@ -161,7 +165,7 @@ function videoFileActivityUrlToDBAttributes (videoCreated: VideoModel, videoObje
|
|||
resolution: fileUrl.width,
|
||||
size: fileUrl.size,
|
||||
videoId: videoCreated.id
|
||||
}
|
||||
} as VideoFileModel
|
||||
attributes.push(attribute)
|
||||
}
|
||||
|
||||
|
|
|
@ -91,9 +91,10 @@ class Emailer {
|
|||
|
||||
async addVideoAbuseReport (videoId: number) {
|
||||
const video = await VideoModel.load(videoId)
|
||||
if (!video) throw new Error('Unknown Video id during Abuse report.')
|
||||
|
||||
const text = `Hi,\n\n` +
|
||||
`Your instance received an abuse for video the following video ${video.url}\n\n` +
|
||||
`Your instance received an abuse for the following video ${video.url}\n\n` +
|
||||
`Cheers,\n` +
|
||||
`PeerTube.`
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ async function computeBody (payload: { body: any, signatureActorId?: number }) {
|
|||
}
|
||||
|
||||
async function buildSignedRequestOptions (payload: { signatureActorId?: number }) {
|
||||
let actor: ActorModel
|
||||
let actor: ActorModel | null
|
||||
if (payload.signatureActorId) {
|
||||
actor = await ActorModel.load(payload.signatureActorId)
|
||||
if (!actor) throw new Error('Unknown signature actor id.')
|
||||
|
|
|
@ -28,7 +28,7 @@ async function processVideoFileImport (job: Bull.Job) {
|
|||
const video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(payload.videoUUID)
|
||||
// No video, maybe deleted?
|
||||
if (!video) {
|
||||
logger.info('Do not process job %d, video does not exist.', job.id, { videoUUID: video.uuid })
|
||||
logger.info('Do not process job %d, video does not exist.', job.id)
|
||||
return undefined
|
||||
}
|
||||
|
||||
|
@ -45,13 +45,13 @@ async function processVideoFile (job: Bull.Job) {
|
|||
const video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(payload.videoUUID)
|
||||
// No video, maybe deleted?
|
||||
if (!video) {
|
||||
logger.info('Do not process job %d, video does not exist.', job.id, { videoUUID: video.uuid })
|
||||
logger.info('Do not process job %d, video does not exist.', job.id)
|
||||
return undefined
|
||||
}
|
||||
|
||||
// Transcoding in other resolution
|
||||
if (payload.resolution) {
|
||||
await video.transcodeOriginalVideofile(payload.resolution, payload.isPortraitMode)
|
||||
await video.transcodeOriginalVideofile(payload.resolution, payload.isPortraitMode || false)
|
||||
|
||||
await retryTransactionWrapper(onVideoFileTranscoderOrImportSuccess, video)
|
||||
} else {
|
||||
|
|
|
@ -87,7 +87,7 @@ class JobQueue {
|
|||
const queue = this.queues[obj.type]
|
||||
if (queue === undefined) {
|
||||
logger.error('Unknown queue %s: cannot create job.', obj.type)
|
||||
return
|
||||
throw Error('Unknown queue, cannot create job')
|
||||
}
|
||||
|
||||
const jobArgs: Bull.JobOptions = {
|
||||
|
|
|
@ -6,8 +6,8 @@ import { CONFIG, USER_PASSWORD_RESET_LIFETIME, VIDEO_VIEW_LIFETIME } from '../in
|
|||
|
||||
type CachedRoute = {
|
||||
body: string,
|
||||
contentType?: string
|
||||
statusCode?: string
|
||||
contentType: string
|
||||
statusCode: string
|
||||
}
|
||||
|
||||
class Redis {
|
||||
|
@ -75,11 +75,12 @@ class Redis {
|
|||
}
|
||||
|
||||
setCachedRoute (req: express.Request, body: any, lifetime: number, contentType?: string, statusCode?: number) {
|
||||
const cached: CachedRoute = {
|
||||
body: body.toString(),
|
||||
contentType,
|
||||
statusCode: statusCode.toString()
|
||||
}
|
||||
const cached: CachedRoute = Object.assign({}, {
|
||||
body: body.toString()
|
||||
},
|
||||
(contentType) ? { contentType } : null,
|
||||
(statusCode) ? { statusCode: statusCode.toString() } : null
|
||||
)
|
||||
|
||||
return this.setObject(this.buildCachedRouteKey(req), cached, lifetime)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import { UserModel } from '../models/account/user'
|
|||
import { buildActorInstance, getAccountActivityPubUrl, setAsyncActorKeys } from './activitypub'
|
||||
import { createVideoChannel } from './video-channel'
|
||||
import { VideoChannelModel } from '../models/video/video-channel'
|
||||
import { FilteredModelAttributes } from 'sequelize-typescript/lib/models/Model'
|
||||
|
||||
async function createUserAccountAndChannel (userToCreate: UserModel, validateUser = true) {
|
||||
const { user, account, videoChannel } = await sequelizeTypescript.transaction(async t => {
|
||||
|
@ -34,9 +35,9 @@ async function createUserAccountAndChannel (userToCreate: UserModel, validateUse
|
|||
|
||||
async function createLocalAccountWithoutKeys (
|
||||
name: string,
|
||||
userId: number,
|
||||
applicationId: number,
|
||||
t: Sequelize.Transaction,
|
||||
userId: number | null,
|
||||
applicationId: number | null,
|
||||
t: Sequelize.Transaction | undefined,
|
||||
type: ActivityPubActorType= 'Person'
|
||||
) {
|
||||
const url = getAccountActivityPubUrl(name)
|
||||
|
@ -49,7 +50,7 @@ async function createLocalAccountWithoutKeys (
|
|||
userId,
|
||||
applicationId,
|
||||
actorId: actorInstanceCreated.id
|
||||
})
|
||||
} as FilteredModelAttributes<AccountModel>)
|
||||
|
||||
const accountInstanceCreated = await accountInstance.save({ transaction: t })
|
||||
accountInstanceCreated.Actor = actorInstanceCreated
|
||||
|
|
|
@ -9,14 +9,14 @@ import { sendCreateVideoComment } from './activitypub/send'
|
|||
|
||||
async function createVideoComment (obj: {
|
||||
text: string,
|
||||
inReplyToComment: VideoCommentModel,
|
||||
inReplyToComment: VideoCommentModel | null,
|
||||
video: VideoModel
|
||||
account: AccountModel
|
||||
}, t: Sequelize.Transaction) {
|
||||
let originCommentId: number = null
|
||||
let inReplyToCommentId: number = null
|
||||
let originCommentId: number | null = null
|
||||
let inReplyToCommentId: number | null = null
|
||||
|
||||
if (obj.inReplyToComment) {
|
||||
if (obj.inReplyToComment && obj.inReplyToComment !== null) {
|
||||
originCommentId = obj.inReplyToComment.originCommentId || obj.inReplyToComment.id
|
||||
inReplyToCommentId = obj.inReplyToComment.id
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ function setDefaultSearchSort (req: express.Request, res: express.Response, next
|
|||
}
|
||||
|
||||
function setBlacklistSort (req: express.Request, res: express.Response, next: express.NextFunction) {
|
||||
let newSort: SortType = { sortModel: undefined, sortValue: undefined }
|
||||
let newSort: SortType = { sortModel: undefined, sortValue: '' }
|
||||
|
||||
if (!req.query.sort) req.query.sort = '-createdAt'
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
|
|||
if (numberOfActorFollowsRemoved) logger.info('Removed bad %d actor follows.', numberOfActorFollowsRemoved)
|
||||
}
|
||||
|
||||
static updateActorFollowsScore (goodInboxes: string[], badInboxes: string[], t: Sequelize.Transaction) {
|
||||
static updateActorFollowsScore (goodInboxes: string[], badInboxes: string[], t: Sequelize.Transaction | undefined) {
|
||||
if (goodInboxes.length === 0 && badInboxes.length === 0) return
|
||||
|
||||
logger.info('Updating %d good actor follows and %d bad actor follows scores.', goodInboxes.length, badInboxes.length)
|
||||
|
@ -344,7 +344,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
|
|||
}
|
||||
}
|
||||
|
||||
private static incrementScores (inboxUrls: string[], value: number, t: Sequelize.Transaction) {
|
||||
private static incrementScores (inboxUrls: string[], value: number, t: Sequelize.Transaction | undefined) {
|
||||
const inboxUrlsString = inboxUrls.map(url => `'${url}'`).join(',')
|
||||
|
||||
const query = `UPDATE "actorFollow" SET "score" = LEAST("score" + ${value}, ${ACTOR_FOLLOW_SCORE.MAX}) ` +
|
||||
|
@ -354,10 +354,10 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
|
|||
'WHERE "actor"."inboxUrl" IN (' + inboxUrlsString + ') OR "actor"."sharedInboxUrl" IN (' + inboxUrlsString + ')' +
|
||||
')'
|
||||
|
||||
const options = {
|
||||
const options = t ? {
|
||||
type: Sequelize.QueryTypes.BULKUPDATE,
|
||||
transaction: t
|
||||
}
|
||||
} : undefined
|
||||
|
||||
return ActorFollowModel.sequelize.query(query, options)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import * as Sequelize from 'sequelize'
|
||||
|
||||
declare namespace Migration {
|
||||
interface Boolean extends Sequelize.DefineAttributeColumnOptions {
|
||||
defaultValue: boolean | null
|
||||
}
|
||||
|
||||
interface String extends Sequelize.DefineAttributeColumnOptions {
|
||||
defaultValue: string | null
|
||||
}
|
||||
|
||||
interface Integer extends Sequelize.DefineAttributeColumnOptions {
|
||||
defaultValue: number | null
|
||||
}
|
||||
|
||||
interface BigInteger extends Sequelize.DefineAttributeColumnOptions {
|
||||
defaultValue: Sequelize.DataTypeBigInt | number | null
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
Migration
|
||||
}
|
|
@ -154,9 +154,12 @@ export class OAuthTokenModel extends Model<OAuthTokenModel> {
|
|||
return OAuthTokenModel.scope(ScopeNames.WITH_ACCOUNT)
|
||||
.findOne(query)
|
||||
.then(token => {
|
||||
if (token) {
|
||||
token['user'] = token.User
|
||||
|
||||
return token
|
||||
} else {
|
||||
return new OAuthTokenModel()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
|
|||
as: 'InReplyToVideoComment',
|
||||
onDelete: 'CASCADE'
|
||||
})
|
||||
InReplyToVideoComment: VideoCommentModel
|
||||
InReplyToVideoComment: VideoCommentModel | null
|
||||
|
||||
@ForeignKey(() => VideoModel)
|
||||
@Column
|
||||
|
@ -417,7 +417,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
|
|||
toActivityPubObject (threadParentComments: VideoCommentModel[]): VideoCommentObject {
|
||||
let inReplyTo: string
|
||||
// New thread, so in AS we reply to the video
|
||||
if (this.inReplyToCommentId === null) {
|
||||
if ((this.inReplyToCommentId !== null) || (this.InReplyToVideoComment !== null)) {
|
||||
inReplyTo = this.Video.url
|
||||
} else {
|
||||
inReplyTo = this.InReplyToVideoComment.url
|
||||
|
|
|
@ -55,5 +55,8 @@ export {
|
|||
login,
|
||||
serverLogin,
|
||||
userLogin,
|
||||
setAccessTokensToServers
|
||||
setAccessTokensToServers,
|
||||
Server,
|
||||
Client,
|
||||
User
|
||||
}
|
||||
|
|
|
@ -2,7 +2,10 @@ import * as program from 'commander'
|
|||
|
||||
import {
|
||||
getClient,
|
||||
serverLogin
|
||||
serverLogin,
|
||||
Server,
|
||||
Client,
|
||||
User
|
||||
} from '../tests/utils/index'
|
||||
|
||||
program
|
||||
|
@ -19,22 +22,19 @@ if (
|
|||
throw new Error('All arguments are required.')
|
||||
}
|
||||
|
||||
const server = {
|
||||
getClient(program.url)
|
||||
.then(res => {
|
||||
const server = {
|
||||
url: program['url'],
|
||||
user: {
|
||||
username: program['username'],
|
||||
password: program['password']
|
||||
},
|
||||
} as User,
|
||||
client: {
|
||||
id: null,
|
||||
secret: null
|
||||
}
|
||||
}
|
||||
|
||||
getClient(program.url)
|
||||
.then(res => {
|
||||
server.client.id = res.body.client_id
|
||||
server.client.secret = res.body.client_secret
|
||||
id: res.body.client_id as string,
|
||||
secret: res.body.client_secret as string
|
||||
} as Client
|
||||
} as Server
|
||||
|
||||
return serverLogin(server)
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue