aboutsummaryrefslogtreecommitdiffhomepage
path: root/server
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2017-11-16 18:40:50 +0100
committerChocobozzz <florian.bigard@gmail.com>2017-11-27 19:40:52 +0100
commit47e0652b4a98916d4a1d012fbec61afd73a30565 (patch)
tree8d400cce95b50d18921b30fea1d5d2d89b5da740 /server
parent41dbdb8acff3ac56187e8149eab0ff82e2377597 (diff)
downloadPeerTube-47e0652b4a98916d4a1d012fbec61afd73a30565.tar.gz
PeerTube-47e0652b4a98916d4a1d012fbec61afd73a30565.tar.zst
PeerTube-47e0652b4a98916d4a1d012fbec61afd73a30565.zip
Optimize account creation
Diffstat (limited to 'server')
-rw-r--r--server/controllers/api/users.ts22
-rw-r--r--server/initializers/installer.ts6
-rw-r--r--server/lib/user.ts22
-rw-r--r--server/lib/video-channel.ts4
-rw-r--r--server/models/account/account.ts2
-rw-r--r--server/tests/api/config.ts10
-rw-r--r--server/tests/utils/index.ts2
7 files changed, 43 insertions, 25 deletions
diff --git a/server/controllers/api/users.ts b/server/controllers/api/users.ts
index 41ffb64cb..ac7c87517 100644
--- a/server/controllers/api/users.ts
+++ b/server/controllers/api/users.ts
@@ -70,7 +70,7 @@ usersRouter.post('/',
70usersRouter.post('/register', 70usersRouter.post('/register',
71 ensureUserRegistrationAllowed, 71 ensureUserRegistrationAllowed,
72 usersRegisterValidator, 72 usersRegisterValidator,
73 asyncMiddleware(registerUser) 73 asyncMiddleware(registerUserRetryWrapper)
74) 74)
75 75
76usersRouter.put('/me', 76usersRouter.put('/me',
@@ -113,7 +113,7 @@ async function getUserVideos (req: express.Request, res: express.Response, next:
113 113
114async function createUserRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) { 114async function createUserRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
115 const options = { 115 const options = {
116 arguments: [ req, res ], 116 arguments: [ req ],
117 errorMessage: 'Cannot insert the user with many retries.' 117 errorMessage: 'Cannot insert the user with many retries.'
118 } 118 }
119 119
@@ -123,7 +123,7 @@ async function createUserRetryWrapper (req: express.Request, res: express.Respon
123 return res.type('json').status(204).end() 123 return res.type('json').status(204).end()
124} 124}
125 125
126async function createUser (req: express.Request, res: express.Response, next: express.NextFunction) { 126async function createUser (req: express.Request) {
127 const body: UserCreate = req.body 127 const body: UserCreate = req.body
128 const user = db.User.build({ 128 const user = db.User.build({
129 username: body.username, 129 username: body.username,
@@ -139,7 +139,18 @@ async function createUser (req: express.Request, res: express.Response, next: ex
139 logger.info('User %s with its channel and account created.', body.username) 139 logger.info('User %s with its channel and account created.', body.username)
140} 140}
141 141
142async function registerUser (req: express.Request, res: express.Response, next: express.NextFunction) { 142async function registerUserRetryWrapper (req: express.Request, res: express.Response, next: express.NextFunction) {
143 const options = {
144 arguments: [ req ],
145 errorMessage: 'Cannot insert the user with many retries.'
146 }
147
148 await retryTransactionWrapper(registerUser, options)
149
150 return res.type('json').status(204).end()
151}
152
153async function registerUser (req: express.Request) {
143 const body: UserCreate = req.body 154 const body: UserCreate = req.body
144 155
145 const user = db.User.build({ 156 const user = db.User.build({
@@ -152,7 +163,8 @@ async function registerUser (req: express.Request, res: express.Response, next:
152 }) 163 })
153 164
154 await createUserAccountAndChannel(user) 165 await createUserAccountAndChannel(user)
155 return res.type('json').status(204).end() 166
167 logger.info('User %s with its channel and account registered.', body.username)
156} 168}
157 169
158async function getUserInformation (req: express.Request, res: express.Response, next: express.NextFunction) { 170async function getUserInformation (req: express.Request, res: express.Response, next: express.NextFunction) {
diff --git a/server/initializers/installer.ts b/server/initializers/installer.ts
index 3f4c4dfbb..865495722 100644
--- a/server/initializers/installer.ts
+++ b/server/initializers/installer.ts
@@ -2,10 +2,9 @@ import * as passwordGenerator from 'password-generator'
2import { UserRole } from '../../shared' 2import { UserRole } from '../../shared'
3import { logger, mkdirpPromise, rimrafPromise } from '../helpers' 3import { logger, mkdirpPromise, rimrafPromise } from '../helpers'
4import { createUserAccountAndChannel } from '../lib' 4import { createUserAccountAndChannel } from '../lib'
5import { createLocalAccount } from '../lib/user' 5import { createLocalAccountWithoutKeys } from '../lib/user'
6import { applicationExist, clientsExist, usersExist } from './checker' 6import { applicationExist, clientsExist, usersExist } from './checker'
7import { CACHE, CONFIG, LAST_MIGRATION_VERSION, SERVER_ACCOUNT_NAME } from './constants' 7import { CACHE, CONFIG, LAST_MIGRATION_VERSION, SERVER_ACCOUNT_NAME } from './constants'
8
9import { database as db } from './database' 8import { database as db } from './database'
10 9
11async function installApplication () { 10async function installApplication () {
@@ -136,5 +135,6 @@ async function createApplicationIfNotExist () {
136 const applicationInstance = await db.Application.create({ migrationVersion: LAST_MIGRATION_VERSION }) 135 const applicationInstance = await db.Application.create({ migrationVersion: LAST_MIGRATION_VERSION })
137 136
138 logger.info('Creating application account.') 137 logger.info('Creating application account.')
139 return createLocalAccount(SERVER_ACCOUNT_NAME, null, applicationInstance.id, undefined) 138
139 return createLocalAccountWithoutKeys(SERVER_ACCOUNT_NAME, null, applicationInstance.id, undefined)
140} 140}
diff --git a/server/lib/user.ts b/server/lib/user.ts
index 9884e566f..2d7b36b4f 100644
--- a/server/lib/user.ts
+++ b/server/lib/user.ts
@@ -5,16 +5,17 @@ import { database as db } from '../initializers'
5import { CONFIG } from '../initializers/constants' 5import { CONFIG } from '../initializers/constants'
6import { UserInstance } from '../models' 6import { UserInstance } from '../models'
7import { createVideoChannel } from './video-channel' 7import { createVideoChannel } from './video-channel'
8import { logger } from '../helpers/logger'
8 9
9async function createUserAccountAndChannel (user: UserInstance, validateUser = true) { 10async function createUserAccountAndChannel (user: UserInstance, validateUser = true) {
10 const res = await db.sequelize.transaction(async t => { 11 const { account, videoChannel } = await db.sequelize.transaction(async t => {
11 const userOptions = { 12 const userOptions = {
12 transaction: t, 13 transaction: t,
13 validate: validateUser 14 validate: validateUser
14 } 15 }
15 16
16 const userCreated = await user.save(userOptions) 17 const userCreated = await user.save(userOptions)
17 const accountCreated = await createLocalAccount(user.username, user.id, null, t) 18 const accountCreated = await createLocalAccountWithoutKeys(user.username, user.id, null, t)
18 19
19 const videoChannelName = `Default ${userCreated.username} channel` 20 const videoChannelName = `Default ${userCreated.username} channel`
20 const videoChannelInfo = { 21 const videoChannelInfo = {
@@ -25,18 +26,23 @@ async function createUserAccountAndChannel (user: UserInstance, validateUser = t
25 return { account: accountCreated, videoChannel } 26 return { account: accountCreated, videoChannel }
26 }) 27 })
27 28
28 return res 29 // Set account keys, this could be long so process after the account creation and do not block the client
30 const { publicKey, privateKey } = await createPrivateAndPublicKeys()
31 account.set('publicKey', publicKey)
32 account.set('privateKey', privateKey)
33 account.save().catch(err => logger.error('Cannot set public/private keys of local account %d.', account.id, err))
34
35 return { account, videoChannel }
29} 36}
30 37
31async function createLocalAccount (name: string, userId: number, applicationId: number, t: Sequelize.Transaction) { 38async function createLocalAccountWithoutKeys (name: string, userId: number, applicationId: number, t: Sequelize.Transaction) {
32 const { publicKey, privateKey } = await createPrivateAndPublicKeys()
33 const url = getActivityPubUrl('account', name) 39 const url = getActivityPubUrl('account', name)
34 40
35 const accountInstance = db.Account.build({ 41 const accountInstance = db.Account.build({
36 name, 42 name,
37 url, 43 url,
38 publicKey, 44 publicKey: null,
39 privateKey, 45 privateKey: null,
40 followersCount: 0, 46 followersCount: 0,
41 followingCount: 0, 47 followingCount: 0,
42 inboxUrl: url + '/inbox', 48 inboxUrl: url + '/inbox',
@@ -56,5 +62,5 @@ async function createLocalAccount (name: string, userId: number, applicationId:
56 62
57export { 63export {
58 createUserAccountAndChannel, 64 createUserAccountAndChannel,
59 createLocalAccount 65 createLocalAccountWithoutKeys
60} 66}
diff --git a/server/lib/video-channel.ts b/server/lib/video-channel.ts
index e69ec062f..6f9ae2d95 100644
--- a/server/lib/video-channel.ts
+++ b/server/lib/video-channel.ts
@@ -25,9 +25,7 @@ async function createVideoChannel (videoChannelInfo: VideoChannelCreate, account
25 // Do not forget to add Account information to the created video channel 25 // Do not forget to add Account information to the created video channel
26 videoChannelCreated.Account = account 26 videoChannelCreated.Account = account
27 27
28 await sendCreateVideoChannel(videoChannelCreated, t) 28 // No need to seed this empty video channel to followers
29 await shareVideoChannelByServer(videoChannelCreated, t)
30
31 return videoChannelCreated 29 return videoChannelCreated
32} 30}
33 31
diff --git a/server/models/account/account.ts b/server/models/account/account.ts
index 84461a2eb..c370e1709 100644
--- a/server/models/account/account.ts
+++ b/server/models/account/account.ts
@@ -75,7 +75,7 @@ export default function defineAccount (sequelize: Sequelize.Sequelize, DataTypes
75 }, 75 },
76 publicKey: { 76 publicKey: {
77 type: DataTypes.STRING(CONSTRAINTS_FIELDS.ACCOUNTS.PUBLIC_KEY.max), 77 type: DataTypes.STRING(CONSTRAINTS_FIELDS.ACCOUNTS.PUBLIC_KEY.max),
78 allowNull: false, 78 allowNull: true,
79 validate: { 79 validate: {
80 publicKeyValid: value => { 80 publicKeyValid: value => {
81 const res = isAccountPublicKeyValid(value) 81 const res = isAccountPublicKeyValid(value)
diff --git a/server/tests/api/config.ts b/server/tests/api/config.ts
index 3dda3b4d7..72a9e5679 100644
--- a/server/tests/api/config.ts
+++ b/server/tests/api/config.ts
@@ -15,7 +15,7 @@ describe('Test config', function () {
15 let server = null 15 let server = null
16 16
17 before(async function () { 17 before(async function () {
18 this.timeout(120000) 18 this.timeout(10000)
19 19
20 await flushTests() 20 await flushTests()
21 server = await runServer(1) 21 server = await runServer(1)
@@ -29,9 +29,11 @@ describe('Test config', function () {
29 }) 29 })
30 30
31 it('Should have a correct config on a server with registration enabled and a users limit', async function () { 31 it('Should have a correct config on a server with registration enabled and a users limit', async function () {
32 await registerUser(server.url, 'user1', 'super password') 32 await Promise.all([
33 await registerUser(server.url, 'user2', 'super password') 33 registerUser(server.url, 'user1', 'super password'),
34 await registerUser(server.url, 'user3', 'super password') 34 registerUser(server.url, 'user2', 'super password'),
35 registerUser(server.url, 'user3', 'super password')
36 ])
35 37
36 const res = await getConfig(server.url) 38 const res = await getConfig(server.url)
37 const data = res.body 39 const data = res.body
diff --git a/server/tests/utils/index.ts b/server/tests/utils/index.ts
index 4325e4c94..fe6d3b041 100644
--- a/server/tests/utils/index.ts
+++ b/server/tests/utils/index.ts
@@ -3,7 +3,7 @@ export * from './clients'
3export * from './config' 3export * from './config'
4export * from './login' 4export * from './login'
5export * from './miscs' 5export * from './miscs'
6export * from './pods' 6export * from './follows'
7export * from './request-schedulers' 7export * from './request-schedulers'
8export * from './requests' 8export * from './requests'
9export * from './servers' 9export * from './servers'