diff options
Diffstat (limited to 'pkgs/webapps/peertube/ldap.patch')
-rw-r--r-- | pkgs/webapps/peertube/ldap.patch | 542 |
1 files changed, 542 insertions, 0 deletions
diff --git a/pkgs/webapps/peertube/ldap.patch b/pkgs/webapps/peertube/ldap.patch new file mode 100644 index 00000000..7ad5cc57 --- /dev/null +++ b/pkgs/webapps/peertube/ldap.patch | |||
@@ -0,0 +1,542 @@ | |||
1 | commit 45a9e4a7b1badbea15d74bd8b3990303a424dfa6 | ||
2 | Author: Ismaƫl Bouya <ismael.bouya@normalesup.org> | ||
3 | Date: Tue Feb 12 18:47:53 2019 +0100 | ||
4 | |||
5 | Add LDAP authentication | ||
6 | |||
7 | diff --git a/config/default.yaml b/config/default.yaml | ||
8 | index e16b8c35..eac0dd3f 100644 | ||
9 | --- a/config/default.yaml | ||
10 | +++ b/config/default.yaml | ||
11 | @@ -33,6 +33,9 @@ redis: | ||
12 | auth: null | ||
13 | db: 0 | ||
14 | |||
15 | +ldap: | ||
16 | + enable: false | ||
17 | + | ||
18 | smtp: | ||
19 | hostname: null | ||
20 | port: 465 | ||
21 | diff --git a/config/production.yaml.example b/config/production.yaml.example | ||
22 | index 661eac0d..bb5ac251 100644 | ||
23 | --- a/config/production.yaml.example | ||
24 | +++ b/config/production.yaml.example | ||
25 | @@ -33,6 +33,17 @@ redis: | ||
26 | auth: null | ||
27 | db: 0 | ||
28 | |||
29 | +ldap: | ||
30 | + enable: true | ||
31 | + # Disallow non-ldap users (it also disables root!) | ||
32 | + ldap_only: true | ||
33 | + url: ldap://localhost:389/dc=example,dc=com | ||
34 | + bind_dn: cn=admin,dc=example,dc=com | ||
35 | + bind_password: adminPass | ||
36 | + base: dc=example,dc=com | ||
37 | + mail_entry: "mail" | ||
38 | + user_filter: "(|(email=%username%)(uid=%username%))" | ||
39 | + | ||
40 | # SMTP server to send emails | ||
41 | smtp: | ||
42 | hostname: null | ||
43 | diff --git a/package.json b/package.json | ||
44 | index 0cf39c7e..fd1ce3ea 100644 | ||
45 | --- a/package.json | ||
46 | +++ b/package.json | ||
47 | @@ -125,6 +125,7 @@ | ||
48 | "js-yaml": "^3.5.4", | ||
49 | "jsonld": "^1.0.1", | ||
50 | "jsonld-signatures": "https://github.com/Chocobozzz/jsonld-signatures#rsa2017", | ||
51 | + "ldapjs": "^1.0.2", | ||
52 | "lodash": "^4.17.10", | ||
53 | "magnet-uri": "^5.1.4", | ||
54 | "memoizee": "^0.4.14", | ||
55 | diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts | ||
56 | index 6f3ebb9a..fb21df37 100644 | ||
57 | --- a/server/initializers/constants.ts | ||
58 | +++ b/server/initializers/constants.ts | ||
59 | @@ -16,7 +16,7 @@ let config: IConfig = require('config') | ||
60 | |||
61 | // --------------------------------------------------------------------------- | ||
62 | |||
63 | -const LAST_MIGRATION_VERSION = 325 | ||
64 | +const LAST_MIGRATION_VERSION = 326 | ||
65 | |||
66 | // --------------------------------------------------------------------------- | ||
67 | |||
68 | @@ -177,6 +177,16 @@ const CONFIG = { | ||
69 | AUTH: config.has('redis.auth') ? config.get<string>('redis.auth') : null, | ||
70 | DB: config.has('redis.db') ? config.get<number>('redis.db') : null | ||
71 | }, | ||
72 | + LDAP: { | ||
73 | + ENABLE: config.has('ldap.enable') ? config.get<boolean>('ldap.enable') : false, | ||
74 | + LDAP_ONLY: config.has('ldap.ldap_only') ? config.get<boolean>('ldap.ldap_only') : false, | ||
75 | + URL: config.has('ldap.url') ? config.get<string>('ldap.url') : null, | ||
76 | + BIND_DN: config.has('ldap.bind_dn') ? config.get<string>('ldap.bind_dn') : null, | ||
77 | + BIND_PASSWORD: config.has('ldap.bind_password') ? config.get<string>('ldap.bind_password') : null, | ||
78 | + BASE: config.has('ldap.base') ? config.get<string>('ldap.base') : null, | ||
79 | + MAIL_ENTRY: config.has('ldap.mail_entry') ? config.get<string>('ldap.mail_entry') : 'mail', | ||
80 | + USER_FILTER: config.has('ldap.user_filter') ? config.get<string>('ldap.user_filter') : '(|(email=%username%)(uid=%username%))' | ||
81 | + }, | ||
82 | SMTP: { | ||
83 | HOSTNAME: config.get<string>('smtp.hostname'), | ||
84 | PORT: config.get<number>('smtp.port'), | ||
85 | diff --git a/server/initializers/migrations/0326-user-ldap-dn.ts b/server/initializers/migrations/0326-user-ldap-dn.ts | ||
86 | new file mode 100644 | ||
87 | index 00000000..a9d68124 | ||
88 | --- /dev/null | ||
89 | +++ b/server/initializers/migrations/0326-user-ldap-dn.ts | ||
90 | @@ -0,0 +1,26 @@ | ||
91 | +import * as Sequelize from 'sequelize' | ||
92 | + | ||
93 | +async function up (utils: { | ||
94 | + transaction: Sequelize.Transaction, | ||
95 | + queryInterface: Sequelize.QueryInterface, | ||
96 | + sequelize: Sequelize.Sequelize | ||
97 | +}): Promise<void> { | ||
98 | + | ||
99 | + { | ||
100 | + const data = { | ||
101 | + type: Sequelize.STRING, | ||
102 | + allowNull: true, | ||
103 | + defaultValue: null | ||
104 | + } | ||
105 | + await utils.queryInterface.addColumn('user', 'ldapDn', data) | ||
106 | + } | ||
107 | +} | ||
108 | + | ||
109 | +function down (options) { | ||
110 | + throw new Error('Not implemented.') | ||
111 | +} | ||
112 | + | ||
113 | +export { | ||
114 | + up, | ||
115 | + down | ||
116 | +} | ||
117 | diff --git a/server/lib/oauth-model.ts b/server/lib/oauth-model.ts | ||
118 | index 2cd2ae97..3f14b216 100644 | ||
119 | --- a/server/lib/oauth-model.ts | ||
120 | +++ b/server/lib/oauth-model.ts | ||
121 | @@ -66,7 +66,13 @@ function getRefreshToken (refreshToken: string) { | ||
122 | async function getUser (usernameOrEmail: string, password: string) { | ||
123 | logger.debug('Getting User (username/email: ' + usernameOrEmail + ', password: ******).') | ||
124 | |||
125 | - const user = await UserModel.loadByUsernameOrEmail(usernameOrEmail) | ||
126 | + let user | ||
127 | + if (CONFIG.LDAP.ENABLE) { | ||
128 | + user = await UserModel.findOrCreateLDAPUser(usernameOrEmail) | ||
129 | + } | ||
130 | + if (!user && (!CONFIG.LDAP.ENABLE || !CONFIG.LDAP.LDAP_ONLY)) { | ||
131 | + user = await UserModel.loadByUsernameOrEmail(usernameOrEmail) | ||
132 | + } | ||
133 | if (!user) return null | ||
134 | |||
135 | const passwordMatch = await user.isPasswordMatch(password) | ||
136 | diff --git a/server/models/account/user.ts b/server/models/account/user.ts | ||
137 | index 017a9665..a4d0145c 100644 | ||
138 | --- a/server/models/account/user.ts | ||
139 | +++ b/server/models/account/user.ts | ||
140 | @@ -1,3 +1,4 @@ | ||
141 | +import * as ldap from 'ldapjs' | ||
142 | import * as Sequelize from 'sequelize' | ||
143 | import { | ||
144 | AfterDestroy, | ||
145 | @@ -42,8 +43,9 @@ import { VideoChannelModel } from '../video/video-channel' | ||
146 | import { AccountModel } from './account' | ||
147 | import { NSFWPolicyType } from '../../../shared/models/videos/nsfw-policy.type' | ||
148 | import { values } from 'lodash' | ||
149 | -import { NSFW_POLICY_TYPES } from '../../initializers' | ||
150 | +import { CONFIG, NSFW_POLICY_TYPES } from '../../initializers' | ||
151 | import { clearCacheByUserId } from '../../lib/oauth-model' | ||
152 | +import { createUserAccountAndChannel } from '../../lib/user' | ||
153 | import { UserNotificationSettingModel } from './user-notification-setting' | ||
154 | import { VideoModel } from '../video/video' | ||
155 | import { ActorModel } from '../activitypub/actor' | ||
156 | @@ -111,6 +113,11 @@ export class UserModel extends Model<UserModel> { | ||
157 | @Column(DataType.STRING(400)) | ||
158 | email: string | ||
159 | |||
160 | + @AllowNull(true) | ||
161 | + @Default(null) | ||
162 | + @Column | ||
163 | + ldapDn: string | ||
164 | + | ||
165 | @AllowNull(true) | ||
166 | @Default(null) | ||
167 | @Is('UserEmailVerified', value => throwIfNotValid(value, isUserEmailVerifiedValid, 'email verified boolean')) | ||
168 | @@ -354,6 +361,90 @@ export class UserModel extends Model<UserModel> { | ||
169 | return UserModel.findOne(query) | ||
170 | } | ||
171 | |||
172 | + static loadByLdapDn (ldapDn: string) { | ||
173 | + const query = { | ||
174 | + where: { | ||
175 | + ldapDn | ||
176 | + } | ||
177 | + } | ||
178 | + | ||
179 | + return UserModel.findOne(query) | ||
180 | + } | ||
181 | + | ||
182 | + static findOrCreateLDAPUser (username: string) { | ||
183 | + let userInfos | ||
184 | + | ||
185 | + return Promise.resolve(UserModel.findLDAPUser(username)) | ||
186 | + .then((_userInfos) => { | ||
187 | + userInfos = _userInfos | ||
188 | + return UserModel.loadByLdapDn(userInfos['dn']) | ||
189 | + }) | ||
190 | + .then((user) => { | ||
191 | + if (user) { | ||
192 | + return user | ||
193 | + } else { | ||
194 | + return UserModel.createLDAPUser(username, userInfos) | ||
195 | + } | ||
196 | + }) | ||
197 | + .catch(() => { return null }) | ||
198 | + } | ||
199 | + | ||
200 | + static findLDAPUser (username: string) { | ||
201 | + const client = ldap.createClient({ | ||
202 | + url: CONFIG.LDAP.URL | ||
203 | + }) | ||
204 | + const filter = ldap.parseFilter(CONFIG.LDAP.USER_FILTER) | ||
205 | + filter.forEach(function (element) { | ||
206 | + if (element.value === '%username%') element.value = username | ||
207 | + }) | ||
208 | + const opts = { | ||
209 | + filter, | ||
210 | + scope: 'sub', | ||
211 | + attributes: [ CONFIG.LDAP.MAIL_ENTRY, 'dn' ] | ||
212 | + } | ||
213 | + | ||
214 | + return new Promise(function (resolve, reject) { | ||
215 | + client.bind(CONFIG.LDAP.BIND_DN, CONFIG.LDAP.BIND_PASSWORD, function (err) { | ||
216 | + if (err) reject() | ||
217 | + let entries = [] | ||
218 | + client.search(CONFIG.LDAP.BASE, opts, function (err, search) { | ||
219 | + if (err) reject() | ||
220 | + search.on('searchEntry', function (entry) { | ||
221 | + entries.push(entry.object) | ||
222 | + }) | ||
223 | + search.on('end', function (result) { | ||
224 | + if (entries.length === 1) { | ||
225 | + resolve(entries[0]) | ||
226 | + } else { | ||
227 | + reject() | ||
228 | + } | ||
229 | + }) | ||
230 | + }) | ||
231 | + }) | ||
232 | + }) | ||
233 | + } | ||
234 | + | ||
235 | + static createLDAPUser (username: string, userInfos: {}) { | ||
236 | + return Promise.resolve(userInfos) | ||
237 | + .then((userInfos) => { | ||
238 | + const userToCreate = new UserModel({ | ||
239 | + username: username, | ||
240 | + password: 'SomeInvalidPassword', | ||
241 | + email: userInfos[CONFIG.LDAP.MAIL_ENTRY], | ||
242 | + ldapDn: userInfos['dn'], | ||
243 | + nsfwPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY, | ||
244 | + autoPlayVideo: true, | ||
245 | + role: UserRole.USER, | ||
246 | + videoQuota: CONFIG.USER.VIDEO_QUOTA, | ||
247 | + videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY, | ||
248 | + emailVerified: true | ||
249 | + }) | ||
250 | + | ||
251 | + return createUserAccountAndChannel(userToCreate) | ||
252 | + }) | ||
253 | + .then(({ user }) => { return user }) | ||
254 | + } | ||
255 | + | ||
256 | static loadByUsernameAndPopulateChannels (username: string) { | ||
257 | const query = { | ||
258 | where: { | ||
259 | @@ -516,8 +607,22 @@ export class UserModel extends Model<UserModel> { | ||
260 | return hasUserRight(this.role, right) | ||
261 | } | ||
262 | |||
263 | + static checkLDAPUser (dn: string, password: string) { | ||
264 | + const client = ldap.createClient({ url: CONFIG.LDAP.URL }) | ||
265 | + | ||
266 | + return new Promise(function (resolve, reject) { | ||
267 | + client.bind(dn, password, function (err) { | ||
268 | + resolve(!err) | ||
269 | + }) | ||
270 | + }) | ||
271 | + } | ||
272 | + | ||
273 | isPasswordMatch (password: string) { | ||
274 | - return comparePassword(password, this.password) | ||
275 | + if (this.ldapDn === null) { | ||
276 | + return comparePassword(password, this.password) | ||
277 | + } else { | ||
278 | + return UserModel.checkLDAPUser(this.ldapDn, password) | ||
279 | + } | ||
280 | } | ||
281 | |||
282 | toFormattedJSON (): User { | ||
283 | diff --git a/yarn.lock b/yarn.lock | ||
284 | index 1e759af1..1eb61a9f 100644 | ||
285 | --- a/yarn.lock | ||
286 | +++ b/yarn.lock | ||
287 | @@ -674,6 +674,11 @@ asap@^2.0.0: | ||
288 | resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" | ||
289 | integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= | ||
290 | |||
291 | +asn1@0.2.3: | ||
292 | + version "0.2.3" | ||
293 | + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" | ||
294 | + integrity sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y= | ||
295 | + | ||
296 | asn1@~0.2.3: | ||
297 | version "0.2.4" | ||
298 | resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" | ||
299 | @@ -681,6 +686,11 @@ asn1@~0.2.3: | ||
300 | dependencies: | ||
301 | safer-buffer "~2.1.0" | ||
302 | |||
303 | +assert-plus@0.1.5: | ||
304 | + version "0.1.5" | ||
305 | + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.1.5.tgz#ee74009413002d84cec7219c6ac811812e723160" | ||
306 | + integrity sha1-7nQAlBMALYTOxyGcasgRgS5yMWA= | ||
307 | + | ||
308 | assert-plus@1.0.0, assert-plus@^1.0.0: | ||
309 | version "1.0.0" | ||
310 | resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" | ||
311 | @@ -779,6 +789,13 @@ backo2@1.0.2: | ||
312 | resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" | ||
313 | integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= | ||
314 | |||
315 | +backoff@^2.5.0: | ||
316 | + version "2.5.0" | ||
317 | + resolved "https://registry.yarnpkg.com/backoff/-/backoff-2.5.0.tgz#f616eda9d3e4b66b8ca7fca79f695722c5f8e26f" | ||
318 | + integrity sha1-9hbtqdPktmuMp/ynn2lXIsX44m8= | ||
319 | + dependencies: | ||
320 | + precond "0.2" | ||
321 | + | ||
322 | balanced-match@^1.0.0: | ||
323 | version "1.0.0" | ||
324 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" | ||
325 | @@ -1186,6 +1203,16 @@ bull@^3.4.2: | ||
326 | semver "^5.6.0" | ||
327 | uuid "^3.2.1" | ||
328 | |||
329 | +bunyan@^1.8.3: | ||
330 | + version "1.8.12" | ||
331 | + resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.12.tgz#f150f0f6748abdd72aeae84f04403be2ef113797" | ||
332 | + integrity sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c= | ||
333 | + optionalDependencies: | ||
334 | + dtrace-provider "~0.8" | ||
335 | + moment "^2.10.6" | ||
336 | + mv "~2" | ||
337 | + safe-json-stringify "~1" | ||
338 | + | ||
339 | busboy@^0.2.11: | ||
340 | version "0.2.14" | ||
341 | resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" | ||
342 | @@ -1966,7 +1993,7 @@ d@1: | ||
343 | dependencies: | ||
344 | es5-ext "^0.10.9" | ||
345 | |||
346 | -dashdash@^1.12.0: | ||
347 | +dashdash@^1.12.0, dashdash@^1.14.0: | ||
348 | version "1.14.1" | ||
349 | resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" | ||
350 | integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= | ||
351 | @@ -2292,6 +2319,13 @@ double-ended-queue@^2.1.0-0: | ||
352 | resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" | ||
353 | integrity sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw= | ||
354 | |||
355 | +dtrace-provider@~0.8: | ||
356 | + version "0.8.7" | ||
357 | + resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.7.tgz#dc939b4d3e0620cfe0c1cd803d0d2d7ed04ffd04" | ||
358 | + integrity sha1-3JObTT4GIM/gwc2APQ0tftBP/QQ= | ||
359 | + dependencies: | ||
360 | + nan "^2.10.0" | ||
361 | + | ||
362 | duplexer3@^0.1.4: | ||
363 | version "0.1.4" | ||
364 | resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" | ||
365 | @@ -2864,6 +2898,11 @@ extglob@^2.0.4: | ||
366 | snapdragon "^0.8.1" | ||
367 | to-regex "^3.0.1" | ||
368 | |||
369 | +extsprintf@1.2.0: | ||
370 | + version "1.2.0" | ||
371 | + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.2.0.tgz#5ad946c22f5b32ba7f8cd7426711c6e8a3fc2529" | ||
372 | + integrity sha1-WtlGwi9bMrp/jNdCZxHG6KP8JSk= | ||
373 | + | ||
374 | extsprintf@1.3.0: | ||
375 | version "1.3.0" | ||
376 | resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" | ||
377 | @@ -3350,6 +3389,17 @@ glob@7.1.2: | ||
378 | once "^1.3.0" | ||
379 | path-is-absolute "^1.0.0" | ||
380 | |||
381 | +glob@^6.0.1: | ||
382 | + version "6.0.4" | ||
383 | + resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" | ||
384 | + integrity sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI= | ||
385 | + dependencies: | ||
386 | + inflight "^1.0.4" | ||
387 | + inherits "2" | ||
388 | + minimatch "2 || 3" | ||
389 | + once "^1.3.0" | ||
390 | + path-is-absolute "^1.0.0" | ||
391 | + | ||
392 | glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1, glob@~7.1.2: | ||
393 | version "7.1.3" | ||
394 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" | ||
395 | @@ -4522,6 +4572,30 @@ lcid@^2.0.0: | ||
396 | dependencies: | ||
397 | invert-kv "^2.0.0" | ||
398 | |||
399 | +ldap-filter@0.2.2: | ||
400 | + version "0.2.2" | ||
401 | + resolved "https://registry.yarnpkg.com/ldap-filter/-/ldap-filter-0.2.2.tgz#f2b842be0b86da3352798505b31ebcae590d77d0" | ||
402 | + integrity sha1-8rhCvguG2jNSeYUFsx68rlkNd9A= | ||
403 | + dependencies: | ||
404 | + assert-plus "0.1.5" | ||
405 | + | ||
406 | +ldapjs@^1.0.2: | ||
407 | + version "1.0.2" | ||
408 | + resolved "https://registry.yarnpkg.com/ldapjs/-/ldapjs-1.0.2.tgz#544ff7032b7b83c68f0701328d9297aa694340f9" | ||
409 | + integrity sha1-VE/3Ayt7g8aPBwEyjZKXqmlDQPk= | ||
410 | + dependencies: | ||
411 | + asn1 "0.2.3" | ||
412 | + assert-plus "^1.0.0" | ||
413 | + backoff "^2.5.0" | ||
414 | + bunyan "^1.8.3" | ||
415 | + dashdash "^1.14.0" | ||
416 | + ldap-filter "0.2.2" | ||
417 | + once "^1.4.0" | ||
418 | + vasync "^1.6.4" | ||
419 | + verror "^1.8.1" | ||
420 | + optionalDependencies: | ||
421 | + dtrace-provider "~0.8" | ||
422 | + | ||
423 | leven@^2.1.0: | ||
424 | version "2.1.0" | ||
425 | resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" | ||
426 | @@ -5186,7 +5260,7 @@ minimalistic-assert@^1.0.1: | ||
427 | resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" | ||
428 | integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== | ||
429 | |||
430 | -minimatch@3.0.4, minimatch@^3.0.4, minimatch@~3.0.2: | ||
431 | +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.4, minimatch@~3.0.2: | ||
432 | version "3.0.4" | ||
433 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" | ||
434 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== | ||
435 | @@ -5299,6 +5373,11 @@ moment-timezone@^0.5.14, moment-timezone@^0.5.23: | ||
436 | resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" | ||
437 | integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y= | ||
438 | |||
439 | +moment@^2.10.6: | ||
440 | + version "2.24.0" | ||
441 | + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" | ||
442 | + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== | ||
443 | + | ||
444 | morgan@^1.5.3: | ||
445 | version "1.9.1" | ||
446 | resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.1.tgz#0a8d16734a1d9afbc824b99df87e738e58e2da59" | ||
447 | @@ -5394,6 +5473,15 @@ mute-stream@~0.0.4: | ||
448 | resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" | ||
449 | integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= | ||
450 | |||
451 | +mv@~2: | ||
452 | + version "2.1.1" | ||
453 | + resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" | ||
454 | + integrity sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI= | ||
455 | + dependencies: | ||
456 | + mkdirp "~0.5.1" | ||
457 | + ncp "~2.0.0" | ||
458 | + rimraf "~2.4.0" | ||
459 | + | ||
460 | nan@2.11.1, nan@^2.10.0, nan@^2.11.1, nan@^2.9.2: | ||
461 | version "2.11.1" | ||
462 | resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" | ||
463 | @@ -5431,6 +5519,11 @@ ncp@1.0.x: | ||
464 | resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246" | ||
465 | integrity sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY= | ||
466 | |||
467 | +ncp@~2.0.0: | ||
468 | + version "2.0.0" | ||
469 | + resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" | ||
470 | + integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= | ||
471 | + | ||
472 | needle@^2.2.1: | ||
473 | version "2.2.4" | ||
474 | resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" | ||
475 | @@ -6520,6 +6613,11 @@ prebuild-install@^5.2.0: | ||
476 | tunnel-agent "^0.6.0" | ||
477 | which-pm-runs "^1.0.0" | ||
478 | |||
479 | +precond@0.2: | ||
480 | + version "0.2.3" | ||
481 | + resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" | ||
482 | + integrity sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw= | ||
483 | + | ||
484 | prelude-ls@~1.1.2: | ||
485 | version "1.1.2" | ||
486 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" | ||
487 | @@ -7141,6 +7239,13 @@ rimraf@2, rimraf@2.x.x, rimraf@^2.2.8, rimraf@^2.4.2, rimraf@^2.5.2, rimraf@^2.5 | ||
488 | dependencies: | ||
489 | glob "^7.0.5" | ||
490 | |||
491 | +rimraf@~2.4.0: | ||
492 | + version "2.4.5" | ||
493 | + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da" | ||
494 | + integrity sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto= | ||
495 | + dependencies: | ||
496 | + glob "^6.0.1" | ||
497 | + | ||
498 | run-async@^0.1.0: | ||
499 | version "0.1.0" | ||
500 | resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" | ||
501 | @@ -7197,6 +7302,11 @@ safe-buffer@5.1.2, safe-buffer@^5.0.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, s | ||
502 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" | ||
503 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== | ||
504 | |||
505 | +safe-json-stringify@~1: | ||
506 | + version "1.2.0" | ||
507 | + resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" | ||
508 | + integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg== | ||
509 | + | ||
510 | safe-regex@^1.1.0: | ||
511 | version "1.1.0" | ||
512 | resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" | ||
513 | @@ -8857,7 +8967,14 @@ vary@~1.0.1: | ||
514 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.0.1.tgz#99e4981566a286118dfb2b817357df7993376d10" | ||
515 | integrity sha1-meSYFWaihhGN+yuBc1ffeZM3bRA= | ||
516 | |||
517 | -verror@1.10.0: | ||
518 | +vasync@^1.6.4: | ||
519 | + version "1.6.4" | ||
520 | + resolved "https://registry.yarnpkg.com/vasync/-/vasync-1.6.4.tgz#dfe93616ad0e7ae801b332a9d88bfc5cdc8e1d1f" | ||
521 | + integrity sha1-3+k2Fq0OeugBszKp2Iv8XNyOHR8= | ||
522 | + dependencies: | ||
523 | + verror "1.6.0" | ||
524 | + | ||
525 | +verror@1.10.0, verror@^1.8.1: | ||
526 | version "1.10.0" | ||
527 | resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" | ||
528 | integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= | ||
529 | @@ -8866,6 +8983,13 @@ verror@1.10.0: | ||
530 | core-util-is "1.0.2" | ||
531 | extsprintf "^1.2.0" | ||
532 | |||
533 | +verror@1.6.0: | ||
534 | + version "1.6.0" | ||
535 | + resolved "https://registry.yarnpkg.com/verror/-/verror-1.6.0.tgz#7d13b27b1facc2e2da90405eb5ea6e5bdd252ea5" | ||
536 | + integrity sha1-fROyex+swuLakEBetepuW90lLqU= | ||
537 | + dependencies: | ||
538 | + extsprintf "1.2.0" | ||
539 | + | ||
540 | videostream@^2.5.1: | ||
541 | version "2.6.0" | ||
542 | resolved "https://registry.yarnpkg.com/videostream/-/videostream-2.6.0.tgz#7f0b2b84bc457c12cfe599aa2345f5cc06241ab6" | ||