import { tokensRouter } from '@server/controllers/api/users/token'
import { Hooks } from '@server/lib/plugins/hooks'
import { OAuthTokenModel } from '@server/models/oauth/oauth-token'
-import { MUser, MUserAccountDefault } from '@server/types/models'
-import { HttpStatusCode, UserAdminFlag, UserCreate, UserCreateResult, UserRegister, UserRight, UserRole, UserUpdate } from '@shared/models'
+import { MUserAccountDefault } from '@server/types/models'
+import { pick } from '@shared/core-utils'
+import { HttpStatusCode, UserCreate, UserCreateResult, UserRegister, UserRight, UserUpdate } from '@shared/models'
import { auditLoggerFactory, getAuditIdFromRes, UserAuditView } from '../../../helpers/audit-logger'
import { logger } from '../../../helpers/logger'
import { generateRandomString, getFormattedObjects } from '../../../helpers/utils'
import { Emailer } from '../../../lib/emailer'
import { Notifier } from '../../../lib/notifier'
import { Redis } from '../../../lib/redis'
-import { createUserAccountAndChannelAndPlaylist, sendVerifyUserEmail } from '../../../lib/user'
+import { buildUser, createUserAccountAndChannelAndPlaylist, sendVerifyUserEmail } from '../../../lib/user'
import {
asyncMiddleware,
asyncRetryTransactionMiddleware,
async function createUser (req: express.Request, res: express.Response) {
const body: UserCreate = req.body
- const userToCreate = new UserModel({
- username: body.username,
- password: body.password,
- email: body.email,
- nsfwPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY,
- p2pEnabled: CONFIG.DEFAULTS.P2P.WEBAPP.ENABLED,
- autoPlayVideo: true,
- role: body.role,
- videoQuota: body.videoQuota,
- videoQuotaDaily: body.videoQuotaDaily,
- adminFlags: body.adminFlags || UserAdminFlag.NONE
- }) as MUser
+ const userToCreate = buildUser({
+ ...pick(body, [ 'username', 'password', 'email', 'role', 'videoQuota', 'videoQuotaDaily', 'adminFlags' ]),
+
+ emailVerified: null
+ })
// NB: due to the validator usersAddValidator, password==='' can only be true if we can send the mail.
const createPassword = userToCreate.password === ''
async function registerUser (req: express.Request, res: express.Response) {
const body: UserRegister = req.body
- const userToCreate = new UserModel({
- username: body.username,
- password: body.password,
- email: body.email,
- nsfwPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY,
- p2pEnabled: CONFIG.DEFAULTS.P2P.WEBAPP.ENABLED,
- autoPlayVideo: true,
- role: UserRole.USER,
- videoQuota: CONFIG.USER.VIDEO_QUOTA,
- videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY,
+ const userToCreate = buildUser({
+ ...pick(body, [ 'username', 'password', 'email' ]),
+
emailVerified: CONFIG.SIGNUP.REQUIRES_EMAIL_VERIFICATION ? false : null
})
const auditLogger = auditLoggerFactory('users')
-const reqAvatarFile = createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.TMP_DIR })
+const reqAvatarFile = createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT)
const meRouter = express.Router()
import { buildNSFWFilter, createReqFiles, getCountVideos, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils'
import { logger } from '../../helpers/logger'
import { getFormattedObjects } from '../../helpers/utils'
-import { CONFIG } from '../../initializers/config'
import { MIMETYPES } from '../../initializers/constants'
import { sequelizeTypescript } from '../../initializers/database'
import { sendUpdateActor } from '../../lib/activitypub/send'
import { VideoPlaylistModel } from '../../models/video/video-playlist'
const auditLogger = auditLoggerFactory('channels')
-const reqAvatarFile = createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { avatarfile: CONFIG.STORAGE.TMP_DIR })
-const reqBannerFile = createReqFiles([ 'bannerfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { bannerfile: CONFIG.STORAGE.TMP_DIR })
+const reqAvatarFile = createReqFiles([ 'avatarfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT)
+const reqBannerFile = createReqFiles([ 'bannerfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT)
const videoChannelRouter = express.Router()
import { VideoPlaylistModel } from '../../models/video/video-playlist'
import { VideoPlaylistElementModel } from '../../models/video/video-playlist-element'
-const reqThumbnailFile = createReqFiles([ 'thumbnailfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT, { thumbnailfile: CONFIG.STORAGE.TMP_DIR })
+const reqThumbnailFile = createReqFiles([ 'thumbnailfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT)
const videoPlaylistRouter = express.Router()
import express from 'express'
+import { Hooks } from '@server/lib/plugins/hooks'
import { MVideoCaption } from '@server/types/models'
import { HttpStatusCode } from '../../../../shared/models/http/http-error-codes'
import { moveAndProcessCaptionFile } from '../../../helpers/captions-utils'
import { createReqFiles } from '../../../helpers/express-utils'
import { logger } from '../../../helpers/logger'
import { getFormattedObjects } from '../../../helpers/utils'
-import { CONFIG } from '../../../initializers/config'
import { MIMETYPES } from '../../../initializers/constants'
import { sequelizeTypescript } from '../../../initializers/database'
import { federateVideoIfNeeded } from '../../../lib/activitypub/videos'
import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate } from '../../../middlewares'
import { addVideoCaptionValidator, deleteVideoCaptionValidator, listVideoCaptionsValidator } from '../../../middlewares/validators'
import { VideoCaptionModel } from '../../../models/video/video-caption'
-import { Hooks } from '@server/lib/plugins/hooks'
-const reqVideoCaptionAdd = createReqFiles(
- [ 'captionfile' ],
- MIMETYPES.VIDEO_CAPTIONS.MIMETYPE_EXT,
- {
- captionfile: CONFIG.STORAGE.CAPTIONS_DIR
- }
-)
+const reqVideoCaptionAdd = createReqFiles([ 'captionfile' ], MIMETYPES.VIDEO_CAPTIONS.MIMETYPE_EXT)
const videoCaptionsRouter = express.Router()
import express from 'express'
import { createAnyReqFiles } from '@server/helpers/express-utils'
-import { CONFIG } from '@server/initializers/config'
import { MIMETYPES } from '@server/initializers/constants'
import { JobQueue } from '@server/lib/job-queue'
import { buildTaskFileFieldname, getTaskFile } from '@server/lib/video-editor'
const tasksFiles = createAnyReqFiles(
MIMETYPES.VIDEO.MIMETYPE_EXT,
- CONFIG.STORAGE.TMP_DIR,
(req: express.Request, file: Express.Multer.File, cb: (err: Error, result?: boolean) => void) => {
const body = req.body as VideoEditorCreateEdition
const reqVideoFileImport = createReqFiles(
[ 'thumbnailfile', 'previewfile', 'torrentfile' ],
- Object.assign({}, MIMETYPES.TORRENT.MIMETYPE_EXT, MIMETYPES.IMAGE.MIMETYPE_EXT),
- {
- thumbnailfile: CONFIG.STORAGE.TMP_DIR,
- previewfile: CONFIG.STORAGE.TMP_DIR,
- torrentfile: CONFIG.STORAGE.TMP_DIR
- }
+ { ...MIMETYPES.TORRENT.MIMETYPE_EXT, ...MIMETYPES.IMAGE.MIMETYPE_EXT }
)
videoImportsRouter.post('/imports',
import express from 'express'
import { createReqFiles } from '@server/helpers/express-utils'
-import { CONFIG } from '@server/initializers/config'
import { ASSETS_PATH, MIMETYPES } from '@server/initializers/constants'
import { getLocalVideoActivityPubUrl } from '@server/lib/activitypub/url'
import { federateVideoIfNeeded } from '@server/lib/activitypub/videos'
const liveRouter = express.Router()
-const reqVideoFileLive = createReqFiles(
- [ 'thumbnailfile', 'previewfile' ],
- MIMETYPES.IMAGE.MIMETYPE_EXT,
- {
- thumbnailfile: CONFIG.STORAGE.TMP_DIR,
- previewfile: CONFIG.STORAGE.TMP_DIR
- }
-)
+const reqVideoFileLive = createReqFiles([ 'thumbnailfile', 'previewfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT)
liveRouter.post('/live',
authenticate,
import { resetSequelizeInstance } from '../../../helpers/database-utils'
import { createReqFiles } from '../../../helpers/express-utils'
import { logger, loggerTagsFactory } from '../../../helpers/logger'
-import { CONFIG } from '../../../initializers/config'
import { MIMETYPES } from '../../../initializers/constants'
import { sequelizeTypescript } from '../../../initializers/database'
import { federateVideoIfNeeded } from '../../../lib/activitypub/videos'
const auditLogger = auditLoggerFactory('videos')
const updateRouter = express.Router()
-const reqVideoFileUpdate = createReqFiles(
- [ 'thumbnailfile', 'previewfile' ],
- MIMETYPES.IMAGE.MIMETYPE_EXT,
- {
- thumbnailfile: CONFIG.STORAGE.TMP_DIR,
- previewfile: CONFIG.STORAGE.TMP_DIR
- }
-)
+const reqVideoFileUpdate = createReqFiles([ 'thumbnailfile', 'previewfile' ], MIMETYPES.IMAGE.MIMETYPE_EXT)
updateRouter.put('/:id',
openapiOperationDoc({ operationId: 'putVideo' }),
import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger'
import { retryTransactionWrapper } from '../../../helpers/database-utils'
import { createReqFiles } from '../../../helpers/express-utils'
-import { ffprobePromise, buildFileMetadata, getVideoStreamFPS, getVideoStreamDimensionsInfo } from '../../../helpers/ffmpeg'
+import { buildFileMetadata, ffprobePromise, getVideoStreamDimensionsInfo, getVideoStreamFPS } from '../../../helpers/ffmpeg'
import { logger, loggerTagsFactory } from '../../../helpers/logger'
-import { CONFIG } from '../../../initializers/config'
import { MIMETYPES } from '../../../initializers/constants'
import { sequelizeTypescript } from '../../../initializers/database'
import { federateVideoIfNeeded } from '../../../lib/activitypub/videos'
const reqVideoFileAdd = createReqFiles(
[ 'videofile', 'thumbnailfile', 'previewfile' ],
- Object.assign({}, MIMETYPES.VIDEO.MIMETYPE_EXT, MIMETYPES.IMAGE.MIMETYPE_EXT),
- {
- videofile: CONFIG.STORAGE.TMP_DIR,
- thumbnailfile: CONFIG.STORAGE.TMP_DIR,
- previewfile: CONFIG.STORAGE.TMP_DIR
- }
+ { ...MIMETYPES.VIDEO.MIMETYPE_EXT, ...MIMETYPES.IMAGE.MIMETYPE_EXT }
)
const reqVideoFileAddResumable = createReqFiles(
[ 'thumbnailfile', 'previewfile' ],
MIMETYPES.IMAGE.MIMETYPE_EXT,
- {
- thumbnailfile: getResumableUploadPath(),
- previewfile: getResumableUploadPath()
- }
+ getResumableUploadPath()
)
uploadRouter.post('/upload',
function createReqFiles (
fieldNames: string[],
mimeTypes: { [id: string]: string | string[] },
- destinations: { [fieldName: string]: string }
+ destination = CONFIG.STORAGE.TMP_DIR
): RequestHandler {
const storage = diskStorage({
destination: (req, file, cb) => {
- cb(null, destinations[file.fieldname])
+ cb(null, destination)
},
filename: (req, file, cb) => {
function createAnyReqFiles (
mimeTypes: { [id: string]: string | string[] },
- destinationDirectory: string,
fileFilter: (req: express.Request, file: Express.Multer.File, cb: (err: Error, result: boolean) => void) => void
): RequestHandler {
const storage = diskStorage({
destination: (req, file, cb) => {
- cb(null, destinationDirectory)
+ cb(null, CONFIG.STORAGE.TMP_DIR)
},
filename: (req, file, cb) => {
import passwordGenerator from 'password-generator'
import { UserRole } from '@shared/models'
import { logger } from '../helpers/logger'
-import { createApplicationActor, createUserAccountAndChannelAndPlaylist } from '../lib/user'
+import { buildUser, createApplicationActor, createUserAccountAndChannelAndPlaylist } from '../lib/user'
import { ApplicationModel } from '../models/application/application'
import { OAuthClientModel } from '../models/oauth/oauth-client'
-import { UserModel } from '../models/user/user'
import { applicationExist, clientsExist, usersExist } from './checker-after-init'
import { CONFIG } from './config'
import { FILES_CACHE, HLS_STREAMING_PLAYLIST_DIRECTORY, LAST_MIGRATION_VERSION, RESUMABLE_UPLOAD_DIRECTORY } from './constants'
password = passwordGenerator(16, true)
}
- const userData = {
+ const user = buildUser({
username,
email,
password,
role,
- verified: true,
- nsfwPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY,
- p2pEnabled: CONFIG.DEFAULTS.P2P.WEBAPP.ENABLED,
+ emailVerified: true,
videoQuota: -1,
videoQuotaDaily: -1
- }
- const user = new UserModel(userData)
+ })
await createUserAccountAndChannelAndPlaylist({ userToCreate: user, channelNames: undefined, validateUser: validatePassword })
logger.info('Username: ' + username)
import { MOAuthClient } from '@server/types/models'
import { MOAuthTokenUser } from '@server/types/models/oauth/oauth-token'
import { MUser } from '@server/types/models/user/user'
-import { UserAdminFlag } from '@shared/models/users/user-flag.model'
+import { pick } from '@shared/core-utils'
import { UserRole } from '@shared/models/users/user-role'
import { logger } from '../../helpers/logger'
import { CONFIG } from '../../initializers/config'
import { OAuthClientModel } from '../../models/oauth/oauth-client'
import { OAuthTokenModel } from '../../models/oauth/oauth-token'
import { UserModel } from '../../models/user/user'
-import { createUserAccountAndChannelAndPlaylist } from '../user'
+import { buildUser, createUserAccountAndChannelAndPlaylist } from '../user'
import { TokensCache } from './tokens-cache'
type TokenInfo = {
const actor = await ActorModel.loadLocalByName(options.username)
if (actor) return null
- const userToCreate = new UserModel({
- username: options.username,
+ const userToCreate = buildUser({
+ ...pick(options, [ 'username', 'email', 'role' ]),
+
+ emailVerified: null,
password: null,
- email: options.email,
- nsfwPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY,
- p2pEnabled: CONFIG.DEFAULTS.P2P.WEBAPP.ENABLED,
- autoPlayVideo: true,
- role: options.role,
- videoQuota: CONFIG.USER.VIDEO_QUOTA,
- videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY,
- adminFlags: UserAdminFlag.NONE,
pluginAuth
- }) as MUser
+ })
const { user } = await createUserAccountAndChannelAndPlaylist({
userToCreate,
import { Transaction } from 'sequelize/types'
+import { logger } from '@server/helpers/logger'
+import { CONFIG } from '@server/initializers/config'
import { UserModel } from '@server/models/user/user'
import { MActorDefault } from '@server/types/models/actor'
import { buildUUID } from '@shared/extra-utils'
import { ActivityPubActorType } from '../../shared/models/activitypub'
-import { UserNotificationSetting, UserNotificationSettingValue } from '../../shared/models/users'
+import { UserAdminFlag, UserNotificationSetting, UserNotificationSettingValue, UserRole } from '../../shared/models/users'
import { SERVER_ACTOR_NAME, WEBSERVER } from '../initializers/constants'
import { sequelizeTypescript } from '../initializers/database'
import { AccountModel } from '../models/account/account'
import { Redis } from './redis'
import { createLocalVideoChannel } from './video-channel'
import { createWatchLaterPlaylist } from './video-playlist'
-import { logger } from '@server/helpers/logger'
type ChannelNames = { name: string, displayName: string }
+function buildUser (options: {
+ username: string
+ password: string
+ email: string
+
+ role?: UserRole // Default to UserRole.User
+ adminFlags?: UserAdminFlag // Default to UserAdminFlag.NONE
+
+ emailVerified: boolean | null
+
+ videoQuota?: number // Default to CONFIG.USER.VIDEO_QUOTA
+ videoQuotaDaily?: number // Default to CONFIG.USER.VIDEO_QUOTA_DAILY
+
+ pluginAuth?: string
+}): MUser {
+ const {
+ username,
+ password,
+ email,
+ role = UserRole.USER,
+ emailVerified,
+ videoQuota = CONFIG.USER.VIDEO_QUOTA,
+ videoQuotaDaily = CONFIG.USER.VIDEO_QUOTA_DAILY,
+ adminFlags = UserAdminFlag.NONE,
+ pluginAuth
+ } = options
+
+ return new UserModel({
+ username,
+ password,
+ email,
+
+ nsfwPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY,
+ p2pEnabled: CONFIG.DEFAULTS.P2P.WEBAPP.ENABLED,
+ autoPlayVideo: true,
+
+ role,
+ emailVerified,
+ adminFlags,
+
+ videoQuota: videoQuota,
+ videoQuotaDaily: videoQuotaDaily,
+
+ pluginAuth
+ })
+}
+
async function createUserAccountAndChannelAndPlaylist (parameters: {
userToCreate: MUser
userDisplayName?: string
const email = isPendingEmail ? user.pendingEmail : user.email
const username = user.username
- await Emailer.Instance.addVerifyEmailJob(username, email, url)
+ Emailer.Instance.addVerifyEmailJob(username, email, url)
}
async function getOriginalVideoFileTotalFromUser (user: MUserId) {
createUserAccountAndChannelAndPlaylist,
createLocalAccountWithoutKeys,
sendVerifyUserEmail,
- isAbleToUploadVideo
+ isAbleToUploadVideo,
+ buildUser
}
// ---------------------------------------------------------------------------