aboutsummaryrefslogtreecommitdiff
path: root/pkgs/webapps/peertube/ldap.patch
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/webapps/peertube/ldap.patch')
-rw-r--r--pkgs/webapps/peertube/ldap.patch507
1 files changed, 281 insertions, 226 deletions
diff --git a/pkgs/webapps/peertube/ldap.patch b/pkgs/webapps/peertube/ldap.patch
index 7ad5cc5..438eaa0 100644
--- a/pkgs/webapps/peertube/ldap.patch
+++ b/pkgs/webapps/peertube/ldap.patch
@@ -1,92 +1,100 @@
1commit 45a9e4a7b1badbea15d74bd8b3990303a424dfa6 1commit ffb4a59047a014d6bb050b67a2fc7bc116be4682
2Author: Ismaël Bouya <ismael.bouya@normalesup.org> 2Author: Ismaël Bouya <ismael.bouya@normalesup.org>
3Date: Tue Feb 12 18:47:53 2019 +0100 3Date: Tue Feb 12 18:47:53 2019 +0100
4 4
5 Add LDAP authentication 5 Add LDAP authentication
6 6
7diff --git a/config/default.yaml b/config/default.yaml 7diff --git a/config/default.yaml b/config/default.yaml
8index e16b8c35..eac0dd3f 100644 8index 3260c62fc..dcce721b9 100644
9--- a/config/default.yaml 9--- a/config/default.yaml
10+++ b/config/default.yaml 10+++ b/config/default.yaml
11@@ -33,6 +33,9 @@ redis: 11@@ -51,6 +51,19 @@ redis:
12 auth: null 12 auth: null
13 db: 0 13 db: 0
14 14
15+ldap: 15+auth:
16+ enable: false 16+ local:
17+ enabled: true
18+ ldap:
19+ enabled: true
20+ url: ldap://localhost:389/dc=example,dc=com
21+ insecure_tls: false
22+ bind_dn: cn=admin,dc=example,dc=com
23+ bind_password: adminPass
24+ base: dc=example,dc=com
25+ mail_entry: "mail"
26+ user_filter: "(|(email=%username%)(uid=%username%))"
17+ 27+
18 smtp: 28 smtp:
19 hostname: null 29 hostname: null
20 port: 465 30 port: 465
21diff --git a/config/production.yaml.example b/config/production.yaml.example 31diff --git a/config/production.yaml.example b/config/production.yaml.example
22index 661eac0d..bb5ac251 100644 32index 30cd2ffe0..c56691bf4 100644
23--- a/config/production.yaml.example 33--- a/config/production.yaml.example
24+++ b/config/production.yaml.example 34+++ b/config/production.yaml.example
25@@ -33,6 +33,17 @@ redis: 35@@ -51,6 +51,19 @@ redis:
26 auth: null 36 auth: null
27 db: 0 37 db: 0
28 38
29+ldap: 39+auth:
30+ enable: true 40+ local:
31+ # Disallow non-ldap users (it also disables root!) 41+ enabled: true
32+ ldap_only: true 42+ ldap:
33+ url: ldap://localhost:389/dc=example,dc=com 43+ enabled: true
34+ bind_dn: cn=admin,dc=example,dc=com 44+ url: ldap://localhost:389/dc=example,dc=com
35+ bind_password: adminPass 45+ insecure_tls: false
36+ base: dc=example,dc=com 46+ bind_dn: cn=admin,dc=example,dc=com
37+ mail_entry: "mail" 47+ bind_password: adminPass
38+ user_filter: "(|(email=%username%)(uid=%username%))" 48+ base: dc=example,dc=com
49+ mail_entry: "mail"
50+ user_filter: "(|(email=%username%)(uid=%username%))"
39+ 51+
40 # SMTP server to send emails 52 # SMTP server to send emails
41 smtp: 53 smtp:
42 hostname: null 54 hostname: null
43diff --git a/package.json b/package.json 55diff --git a/package.json b/package.json
44index 0cf39c7e..fd1ce3ea 100644 56index 49d9faf97..31eccf797 100644
45--- a/package.json 57--- a/package.json
46+++ b/package.json 58+++ b/package.json
47@@ -125,6 +125,7 @@ 59@@ -112,6 +112,7 @@
60 "iso-639-3": "^1.0.1",
48 "js-yaml": "^3.5.4", 61 "js-yaml": "^3.5.4",
49 "jsonld": "^1.0.1", 62 "jsonld": "~2.0.1",
50 "jsonld-signatures": "https://github.com/Chocobozzz/jsonld-signatures#rsa2017",
51+ "ldapjs": "^1.0.2", 63+ "ldapjs": "^1.0.2",
52 "lodash": "^4.17.10", 64 "lodash": "^4.17.10",
65 "lru-cache": "^5.1.1",
53 "magnet-uri": "^5.1.4", 66 "magnet-uri": "^5.1.4",
54 "memoizee": "^0.4.14", 67diff --git a/server/initializers/config.ts b/server/initializers/config.ts
55diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts 68index 7fd77f3e8..45a667826 100644
56index 6f3ebb9a..fb21df37 100644 69--- a/server/initializers/config.ts
57--- a/server/initializers/constants.ts 70+++ b/server/initializers/config.ts
58+++ b/server/initializers/constants.ts 71@@ -34,6 +34,21 @@ const CONFIG = {
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, 72 AUTH: config.has('redis.auth') ? config.get<string>('redis.auth') : null,
70 DB: config.has('redis.db') ? config.get<number>('redis.db') : null 73 DB: config.has('redis.db') ? config.get<number>('redis.db') : null
71 }, 74 },
72+ LDAP: { 75+ AUTH: {
73+ ENABLE: config.has('ldap.enable') ? config.get<boolean>('ldap.enable') : false, 76+ LOCAL: {
74+ LDAP_ONLY: config.has('ldap.ldap_only') ? config.get<boolean>('ldap.ldap_only') : false, 77+ ENABLED: config.has('auth.local.enabled') ? config.get<boolean>('auth.local.enabled') : true,
75+ URL: config.has('ldap.url') ? config.get<string>('ldap.url') : null, 78+ },
76+ BIND_DN: config.has('ldap.bind_dn') ? config.get<string>('ldap.bind_dn') : null, 79+ LDAP: {
77+ BIND_PASSWORD: config.has('ldap.bind_password') ? config.get<string>('ldap.bind_password') : null, 80+ ENABLED: config.has('auth.ldap.enabled') ? config.get<boolean>('auth.ldap.enabled') : false,
78+ BASE: config.has('ldap.base') ? config.get<string>('ldap.base') : null, 81+ URL: config.has('auth.ldap.url') ? config.get<string>('auth.ldap.url') : null,
79+ MAIL_ENTRY: config.has('ldap.mail_entry') ? config.get<string>('ldap.mail_entry') : 'mail', 82+ INSECURE_TLS: config.has('auth.ldap.insecure_tls') ? config.get<boolean>('auth.ldap.insecure_tls') : false,
80+ USER_FILTER: config.has('ldap.user_filter') ? config.get<string>('ldap.user_filter') : '(|(email=%username%)(uid=%username%))' 83+ BIND_DN: config.has('auth.ldap.bind_dn') ? config.get<string>('auth.ldap.bind_dn') : null,
84+ BIND_PASSWORD: config.has('auth.ldap.bind_password') ? config.get<string>('auth.ldap.bind_password') : null,
85+ BASE: config.has('auth.ldap.base') ? config.get<string>('auth.ldap.base') : null,
86+ MAIL_ENTRY: config.has('auth.ldap.mail_entry') ? config.get<string>('auth.ldap.mail_entry') : 'mail',
87+ USER_FILTER: config.has('auth.ldap.user_filter') ? config.get<string>('auth.ldap.user_filter') : null
88+ },
81+ }, 89+ },
82 SMTP: { 90 SMTP: {
83 HOSTNAME: config.get<string>('smtp.hostname'), 91 HOSTNAME: config.get<string>('smtp.hostname'),
84 PORT: config.get<number>('smtp.port'), 92 PORT: config.get<number>('smtp.port'),
85diff --git a/server/initializers/migrations/0326-user-ldap-dn.ts b/server/initializers/migrations/0326-user-ldap-dn.ts 93diff --git a/server/initializers/migrations/0375-user-ldap-dn.ts b/server/initializers/migrations/0375-user-ldap-dn.ts
86new file mode 100644 94new file mode 100644
87index 00000000..a9d68124 95index 000000000..a9d68124b
88--- /dev/null 96--- /dev/null
89+++ b/server/initializers/migrations/0326-user-ldap-dn.ts 97+++ b/server/initializers/migrations/0375-user-ldap-dn.ts
90@@ -0,0 +1,26 @@ 98@@ -0,0 +1,26 @@
91+import * as Sequelize from 'sequelize' 99+import * as Sequelize from 'sequelize'
92+ 100+
@@ -114,48 +122,151 @@ index 00000000..a9d68124
114+ up, 122+ up,
115+ down 123+ down
116+} 124+}
125diff --git a/server/lib/ldap.ts b/server/lib/ldap.ts
126new file mode 100644
127index 000000000..e6601e5cb
128--- /dev/null
129+++ b/server/lib/ldap.ts
130@@ -0,0 +1,89 @@
131+import * as express from 'express'
132+import { createClient, Client, parseFilter } from 'ldapjs'
133+import { logger } from '../helpers/logger'
134+import { CONFIG } from '../initializers/config'
135+
136+class Ldap {
137+
138+ private static instance: Ldap
139+ private initialized = false
140+ private client: Client
141+ private prefix: string
142+
143+ private constructor () {}
144+
145+ init () {
146+ // Already initialized
147+ if (this.initialized === true) return
148+ this.initialized = true
149+
150+ this.client = createClient(Ldap.getLdapClientOptions())
151+ }
152+
153+ static getLdapClientOptions () {
154+ return Object.assign({}, {
155+ url: CONFIG.AUTH.LDAP.URL,
156+ reconnect: true,
157+ tlsOptions: { rejectUnauthorized: !CONFIG.AUTH.LDAP.INSECURE_TLS }
158+ })
159+ }
160+
161+ getClient () {
162+ this.init()
163+ return this.client
164+ }
165+
166+ findUser (username: string) {
167+ const filter = parseFilter(CONFIG.AUTH.LDAP.USER_FILTER)
168+ filter.forEach(function (element) {
169+ if (element.value === '%username%') element.value = username
170+ })
171+ const opts = {
172+ filter,
173+ scope: 'sub',
174+ attributes: [ CONFIG.AUTH.LDAP.MAIL_ENTRY, 'dn' ]
175+ }
176+
177+ const client = this.getClient()
178+
179+ return new Promise(function (resolve, reject) {
180+ client.bind(CONFIG.AUTH.LDAP.BIND_DN, CONFIG.AUTH.LDAP.BIND_PASSWORD, function (err) {
181+ if (err) reject(err)
182+ let entries = []
183+ client.search(CONFIG.AUTH.LDAP.BASE, opts, function (err, search) {
184+ if (err) reject(err)
185+ search.on('searchEntry', function (entry) {
186+ entries.push(entry.object)
187+ })
188+ search.on('end', function (result) {
189+ if (entries.length === 1) {
190+ resolve(entries[0])
191+ } else {
192+ reject("No user found corresponding to this username")
193+ }
194+ })
195+ })
196+ })
197+ })
198+ }
199+
200+ checkUser (dn: string, password: string) {
201+ const client = this.getClient()
202+ return new Promise(function (resolve, reject) {
203+ client.bind(dn, password, function (err) {
204+ resolve(!err)
205+ })
206+ })
207+ }
208+
209+
210+ static get Instance () {
211+ return this.instance || (this.instance = new this())
212+ }
213+}
214+
215+// ---------------------------------------------------------------------------
216+
217+export {
218+ Ldap
219+}
117diff --git a/server/lib/oauth-model.ts b/server/lib/oauth-model.ts 220diff --git a/server/lib/oauth-model.ts b/server/lib/oauth-model.ts
118index 2cd2ae97..3f14b216 100644 221index 086856f41..ab10effd0 100644
119--- a/server/lib/oauth-model.ts 222--- a/server/lib/oauth-model.ts
120+++ b/server/lib/oauth-model.ts 223+++ b/server/lib/oauth-model.ts
121@@ -66,7 +66,13 @@ function getRefreshToken (refreshToken: string) { 224@@ -9,6 +9,7 @@ import { Transaction } from 'sequelize'
225 import { CONFIG } from '../initializers/config'
226 import * as LRUCache from 'lru-cache'
227 import { MOAuthTokenUser } from '@server/typings/models/oauth/oauth-token'
228+import { MUserDefault } from '@server/typings/models'
229
230 type TokenInfo = { accessToken: string, refreshToken: string, accessTokenExpiresAt: Date, refreshTokenExpiresAt: Date }
231
232@@ -74,7 +75,13 @@ function getRefreshToken (refreshToken: string) {
122 async function getUser (usernameOrEmail: string, password: string) { 233 async function getUser (usernameOrEmail: string, password: string) {
123 logger.debug('Getting User (username/email: ' + usernameOrEmail + ', password: ******).') 234 logger.debug('Getting User (username/email: ' + usernameOrEmail + ', password: ******).')
124 235
125- const user = await UserModel.loadByUsernameOrEmail(usernameOrEmail) 236- const user = await UserModel.loadByUsernameOrEmail(usernameOrEmail)
126+ let user 237+ let user : MUserDefault
127+ if (CONFIG.LDAP.ENABLE) { 238+ if (CONFIG.AUTH.LDAP.ENABLED) {
128+ user = await UserModel.findOrCreateLDAPUser(usernameOrEmail) 239+ user = await UserModel.findOrCreateLDAPUser(usernameOrEmail)
129+ } 240+ }
130+ if (!user && (!CONFIG.LDAP.ENABLE || !CONFIG.LDAP.LDAP_ONLY)) { 241+ if (!user && CONFIG.AUTH.LOCAL.ENABLED) {
131+ user = await UserModel.loadByUsernameOrEmail(usernameOrEmail) 242+ user = await UserModel.loadByUsernameOrEmail(usernameOrEmail)
132+ } 243+ }
133 if (!user) return null 244 if (!user) return null
134 245
135 const passwordMatch = await user.isPasswordMatch(password) 246 const passwordMatch = await user.isPasswordMatch(password)
136diff --git a/server/models/account/user.ts b/server/models/account/user.ts 247diff --git a/server/models/account/user.ts b/server/models/account/user.ts
137index 017a9665..a4d0145c 100644 248index 4c2c5e278..0b38f7cb2 100644
138--- a/server/models/account/user.ts 249--- a/server/models/account/user.ts
139+++ b/server/models/account/user.ts 250+++ b/server/models/account/user.ts
140@@ -1,3 +1,4 @@ 251@@ -1,4 +1,5 @@
141+import * as ldap from 'ldapjs' 252 import { FindOptions, literal, Op, QueryTypes, where, fn, col } from 'sequelize'
142 import * as Sequelize from 'sequelize' 253+import { Ldap } from '../../lib/ldap'
143 import { 254 import {
144 AfterDestroy, 255 AfterDestroy,
145@@ -42,8 +43,9 @@ import { VideoChannelModel } from '../video/video-channel' 256 AfterUpdate,
146 import { AccountModel } from './account' 257@@ -50,7 +51,9 @@ import { AccountModel } from './account'
147 import { NSFWPolicyType } from '../../../shared/models/videos/nsfw-policy.type' 258 import { NSFWPolicyType } from '../../../shared/models/videos/nsfw-policy.type'
148 import { values } from 'lodash' 259 import { values } from 'lodash'
149-import { NSFW_POLICY_TYPES } from '../../initializers' 260 import { DEFAULT_THEME_NAME, DEFAULT_USER_THEME_NAME, NSFW_POLICY_TYPES } from '../../initializers/constants'
150+import { CONFIG, NSFW_POLICY_TYPES } from '../../initializers' 261+import { CONFIG } from '../../initializers/config'
151 import { clearCacheByUserId } from '../../lib/oauth-model' 262 import { clearCacheByUserId } from '../../lib/oauth-model'
152+import { createUserAccountAndChannel } from '../../lib/user' 263+import { createUserAccountAndChannelAndPlaylist } from '../../lib/user'
153 import { UserNotificationSettingModel } from './user-notification-setting' 264 import { UserNotificationSettingModel } from './user-notification-setting'
154 import { VideoModel } from '../video/video' 265 import { VideoModel } from '../video/video'
155 import { ActorModel } from '../activitypub/actor' 266 import { ActorModel } from '../activitypub/actor'
156@@ -111,6 +113,11 @@ export class UserModel extends Model<UserModel> { 267@@ -149,6 +152,11 @@ export class UserModel extends Model<UserModel> {
157 @Column(DataType.STRING(400)) 268 @Column(DataType.STRING(400))
158 email: string 269 pendingEmail: string
159 270
160+ @AllowNull(true) 271+ @AllowNull(true)
161+ @Default(null) 272+ @Default(null)
@@ -164,8 +275,8 @@ index 017a9665..a4d0145c 100644
164+ 275+
165 @AllowNull(true) 276 @AllowNull(true)
166 @Default(null) 277 @Default(null)
167 @Is('UserEmailVerified', value => throwIfNotValid(value, isUserEmailVerifiedValid, 'email verified boolean')) 278 @Is('UserEmailVerified', value => throwIfNotValid(value, isUserEmailVerifiedValid, 'email verified boolean', true))
168@@ -354,6 +361,90 @@ export class UserModel extends Model<UserModel> { 279@@ -440,6 +448,48 @@ export class UserModel extends Model<UserModel> {
169 return UserModel.findOne(query) 280 return UserModel.findOne(query)
170 } 281 }
171 282
@@ -179,114 +290,61 @@ index 017a9665..a4d0145c 100644
179+ return UserModel.findOne(query) 290+ return UserModel.findOne(query)
180+ } 291+ }
181+ 292+
182+ static findOrCreateLDAPUser (username: string) { 293+ static async findOrCreateLDAPUser (username: string) {
183+ let userInfos 294+ try {
184+ 295+ const userInfos = await Ldap.Instance.findUser(username)
185+ return Promise.resolve(UserModel.findLDAPUser(username)) 296+ const user = await UserModel.loadByLdapDn(userInfos['dn'])
186+ .then((_userInfos) => { 297+ if (user) {
187+ userInfos = _userInfos 298+ return user
188+ return UserModel.loadByLdapDn(userInfos['dn']) 299+ } else {
189+ }) 300+ return await UserModel.createLDAPUser(username, userInfos)
190+ .then((user) => { 301+ }
191+ if (user) { 302+ } catch (e) {
192+ return user 303+ return null
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+ } 304+ }
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+ } 305+ }
234+ 306+
235+ static createLDAPUser (username: string, userInfos: {}) { 307+ static async createLDAPUser (username: string, userInfos: {}) {
236+ return Promise.resolve(userInfos) 308+ const userToCreate = new UserModel({
237+ .then((userInfos) => { 309+ username,
238+ const userToCreate = new UserModel({ 310+ password: 'SomeInvalidPassword',
239+ username: username, 311+ email: userInfos[CONFIG.AUTH.LDAP.MAIL_ENTRY],
240+ password: 'SomeInvalidPassword', 312+ ldapDn: userInfos['dn'],
241+ email: userInfos[CONFIG.LDAP.MAIL_ENTRY], 313+ nsfwPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY,
242+ ldapDn: userInfos['dn'], 314+ autoPlayVideo: true,
243+ nsfwPolicy: CONFIG.INSTANCE.DEFAULT_NSFW_POLICY, 315+ role: UserRole.USER,
244+ autoPlayVideo: true, 316+ videoQuota: CONFIG.USER.VIDEO_QUOTA,
245+ role: UserRole.USER, 317+ videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY,
246+ videoQuota: CONFIG.USER.VIDEO_QUOTA, 318+ emailVerified: true,
247+ videoQuotaDaily: CONFIG.USER.VIDEO_QUOTA_DAILY, 319+ adminFlags: UserAdminFlag.NONE
248+ emailVerified: true 320+ })
249+ }) 321+ const { user } = await createUserAccountAndChannelAndPlaylist({ userToCreate })
250+ 322+ return user
251+ return createUserAccountAndChannel(userToCreate)
252+ })
253+ .then(({ user }) => { return user })
254+ } 323+ }
255+ 324+
256 static loadByUsernameAndPopulateChannels (username: string) { 325 static loadForMeAPI (username: string): Bluebird<MUserNotifSettingChannelDefault> {
257 const query = { 326 const query = {
258 where: { 327 where: {
259@@ -516,8 +607,22 @@ export class UserModel extends Model<UserModel> { 328@@ -627,7 +677,11 @@ export class UserModel extends Model<UserModel> {
260 return hasUserRight(this.role, right)
261 } 329 }
262 330
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) { 331 isPasswordMatch (password: string) {
274- return comparePassword(password, this.password) 332- return comparePassword(password, this.password)
275+ if (this.ldapDn === null) { 333+ if (this.ldapDn === null) {
276+ return comparePassword(password, this.password) 334+ return comparePassword(password, this.password)
277+ } else { 335+ } else {
278+ return UserModel.checkLDAPUser(this.ldapDn, password) 336+ return Ldap.Instance.checkUser(this.ldapDn, password)
279+ } 337+ }
280 } 338 }
281 339
282 toFormattedJSON (): User { 340 toFormattedJSON (this: MUserFormattable, parameters: { withAdminFlags?: boolean } = {}): User {
283diff --git a/yarn.lock b/yarn.lock 341diff --git a/yarn.lock b/yarn.lock
284index 1e759af1..1eb61a9f 100644 342index 76ce7ed27..f087746df 100644
285--- a/yarn.lock 343--- a/yarn.lock
286+++ b/yarn.lock 344+++ b/yarn.lock
287@@ -674,6 +674,11 @@ asap@^2.0.0: 345@@ -616,6 +616,11 @@ arraybuffer.slice@~0.0.7:
288 resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" 346 resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
289 integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= 347 integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==
290 348
291+asn1@0.2.3: 349+asn1@0.2.3:
292+ version "0.2.3" 350+ version "0.2.3"
@@ -296,7 +354,7 @@ index 1e759af1..1eb61a9f 100644
296 asn1@~0.2.3: 354 asn1@~0.2.3:
297 version "0.2.4" 355 version "0.2.4"
298 resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" 356 resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
299@@ -681,6 +686,11 @@ asn1@~0.2.3: 357@@ -623,6 +628,11 @@ asn1@~0.2.3:
300 dependencies: 358 dependencies:
301 safer-buffer "~2.1.0" 359 safer-buffer "~2.1.0"
302 360
@@ -308,7 +366,7 @@ index 1e759af1..1eb61a9f 100644
308 assert-plus@1.0.0, assert-plus@^1.0.0: 366 assert-plus@1.0.0, assert-plus@^1.0.0:
309 version "1.0.0" 367 version "1.0.0"
310 resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" 368 resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
311@@ -779,6 +789,13 @@ backo2@1.0.2: 369@@ -692,6 +702,13 @@ backo2@1.0.2:
312 resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" 370 resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947"
313 integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= 371 integrity sha1-MasayLEpNjRj41s+u2n038+6eUc=
314 372
@@ -322,9 +380,9 @@ index 1e759af1..1eb61a9f 100644
322 balanced-match@^1.0.0: 380 balanced-match@^1.0.0:
323 version "1.0.0" 381 version "1.0.0"
324 resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 382 resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
325@@ -1186,6 +1203,16 @@ bull@^3.4.2: 383@@ -1001,6 +1018,16 @@ bull@^3.4.2:
326 semver "^5.6.0" 384 util.promisify "^1.0.0"
327 uuid "^3.2.1" 385 uuid "^3.3.3"
328 386
329+bunyan@^1.8.3: 387+bunyan@^1.8.3:
330+ version "1.8.12" 388+ version "1.8.12"
@@ -339,32 +397,32 @@ index 1e759af1..1eb61a9f 100644
339 busboy@^0.2.11: 397 busboy@^0.2.11:
340 version "0.2.14" 398 version "0.2.14"
341 resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" 399 resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453"
342@@ -1966,7 +1993,7 @@ d@1: 400@@ -1619,7 +1646,7 @@ d@1, d@^1.0.1:
343 dependencies: 401 es5-ext "^0.10.50"
344 es5-ext "^0.10.9" 402 type "^1.0.1"
345 403
346-dashdash@^1.12.0: 404-dashdash@^1.12.0:
347+dashdash@^1.12.0, dashdash@^1.14.0: 405+dashdash@^1.12.0, dashdash@^1.14.0:
348 version "1.14.1" 406 version "1.14.1"
349 resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" 407 resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
350 integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= 408 integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
351@@ -2292,6 +2319,13 @@ double-ended-queue@^2.1.0-0: 409@@ -1845,6 +1872,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" 410 resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c"
353 integrity sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw= 411 integrity sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=
354 412
355+dtrace-provider@~0.8: 413+dtrace-provider@~0.8:
356+ version "0.8.7" 414+ version "0.8.8"
357+ resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.7.tgz#dc939b4d3e0620cfe0c1cd803d0d2d7ed04ffd04" 415+ resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.8.tgz#2996d5490c37e1347be263b423ed7b297fb0d97e"
358+ integrity sha1-3JObTT4GIM/gwc2APQ0tftBP/QQ= 416+ integrity sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==
359+ dependencies: 417+ dependencies:
360+ nan "^2.10.0" 418+ nan "^2.14.0"
361+ 419+
362 duplexer3@^0.1.4: 420 duplexer3@^0.1.4:
363 version "0.1.4" 421 version "0.1.4"
364 resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" 422 resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
365@@ -2864,6 +2898,11 @@ extglob@^2.0.4: 423@@ -2228,6 +2262,11 @@ extend@^3.0.0, extend@~3.0.0, extend@~3.0.2:
366 snapdragon "^0.8.1" 424 resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
367 to-regex "^3.0.1" 425 integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
368 426
369+extsprintf@1.2.0: 427+extsprintf@1.2.0:
370+ version "1.2.0" 428+ version "1.2.0"
@@ -374,7 +432,7 @@ index 1e759af1..1eb61a9f 100644
374 extsprintf@1.3.0: 432 extsprintf@1.3.0:
375 version "1.3.0" 433 version "1.3.0"
376 resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" 434 resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
377@@ -3350,6 +3389,17 @@ glob@7.1.2: 435@@ -2567,6 +2606,17 @@ glob@7.1.3:
378 once "^1.3.0" 436 once "^1.3.0"
379 path-is-absolute "^1.0.0" 437 path-is-absolute "^1.0.0"
380 438
@@ -389,12 +447,12 @@ index 1e759af1..1eb61a9f 100644
389+ once "^1.3.0" 447+ once "^1.3.0"
390+ path-is-absolute "^1.0.0" 448+ path-is-absolute "^1.0.0"
391+ 449+
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: 450 glob@^7.0.3, glob@^7.1.1, glob@^7.1.3:
393 version "7.1.3" 451 version "7.1.6"
394 resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" 452 resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
395@@ -4522,6 +4572,30 @@ lcid@^2.0.0: 453@@ -3356,6 +3406,30 @@ latest-version@^3.0.0:
396 dependencies: 454 dependencies:
397 invert-kv "^2.0.0" 455 package-json "^4.0.0"
398 456
399+ldap-filter@0.2.2: 457+ldap-filter@0.2.2:
400+ version "0.2.2" 458+ version "0.2.2"
@@ -420,33 +478,30 @@ index 1e759af1..1eb61a9f 100644
420+ optionalDependencies: 478+ optionalDependencies:
421+ dtrace-provider "~0.8" 479+ dtrace-provider "~0.8"
422+ 480+
423 leven@^2.1.0: 481 libxmljs@0.19.7:
424 version "2.1.0" 482 version "0.19.7"
425 resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" 483 resolved "https://registry.yarnpkg.com/libxmljs/-/libxmljs-0.19.7.tgz#96c2151b0b73f33dd29917edec82902587004e5a"
426@@ -5186,7 +5260,7 @@ minimalistic-assert@^1.0.1: 484@@ -3724,7 +3798,7 @@ mimic-response@^2.0.0:
427 resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" 485 resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.0.0.tgz#996a51c60adf12cb8a87d7fb8ef24c2f3d5ebb46"
428 integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== 486 integrity sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ==
429 487
430-minimatch@3.0.4, minimatch@^3.0.4, minimatch@~3.0.2: 488-minimatch@3.0.4, minimatch@^3.0.4:
431+"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.4, minimatch@~3.0.2: 489+"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.4:
432 version "3.0.4" 490 version "3.0.4"
433 resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 491 resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
434 integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 492 integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
435@@ -5299,6 +5373,11 @@ moment-timezone@^0.5.14, moment-timezone@^0.5.23: 493@@ -3825,7 +3899,7 @@ moment-timezone@^0.5.21, moment-timezone@^0.5.25:
436 resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" 494 dependencies:
437 integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y= 495 moment ">= 2.9.0"
438 496
439+moment@^2.10.6: 497-"moment@>= 2.9.0", moment@^2.24.0:
440+ version "2.24.0" 498+"moment@>= 2.9.0", moment@^2.10.6, moment@^2.24.0:
441+ resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" 499 version "2.24.0"
442+ integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== 500 resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
443+ 501 integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
444 morgan@^1.5.3: 502@@ -3898,6 +3972,15 @@ mute-stream@~0.0.4:
445 version "1.9.1" 503 resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
446 resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.1.tgz#0a8d16734a1d9afbc824b99df87e738e58e2da59" 504 integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
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 505
451+mv@~2: 506+mv@~2:
452+ version "2.1.1" 507+ version "2.1.1"
@@ -457,10 +512,10 @@ index 1e759af1..1eb61a9f 100644
457+ ncp "~2.0.0" 512+ ncp "~2.0.0"
458+ rimraf "~2.4.0" 513+ rimraf "~2.4.0"
459+ 514+
460 nan@2.11.1, nan@^2.10.0, nan@^2.11.1, nan@^2.9.2: 515 nan@2.14.0, nan@^2.14.0, nan@~2.14.0:
461 version "2.11.1" 516 version "2.14.0"
462 resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" 517 resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
463@@ -5431,6 +5519,11 @@ ncp@1.0.x: 518@@ -3913,6 +3996,11 @@ ncp@1.0.x:
464 resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246" 519 resolved "https://registry.yarnpkg.com/ncp/-/ncp-1.0.1.tgz#d15367e5cb87432ba117d2bf80fdf45aecfb4246"
465 integrity sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY= 520 integrity sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY=
466 521
@@ -470,9 +525,9 @@ index 1e759af1..1eb61a9f 100644
470+ integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= 525+ integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=
471+ 526+
472 needle@^2.2.1: 527 needle@^2.2.1:
473 version "2.2.4" 528 version "2.4.0"
474 resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" 529 resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.0.tgz#6833e74975c444642590e15a750288c5f939b57c"
475@@ -6520,6 +6613,11 @@ prebuild-install@^5.2.0: 530@@ -4597,6 +4685,11 @@ prebuild-install@^5.3.3:
476 tunnel-agent "^0.6.0" 531 tunnel-agent "^0.6.0"
477 which-pm-runs "^1.0.0" 532 which-pm-runs "^1.0.0"
478 533
@@ -481,12 +536,12 @@ index 1e759af1..1eb61a9f 100644
481+ resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac" 536+ resolved "https://registry.yarnpkg.com/precond/-/precond-0.2.3.tgz#aa9591bcaa24923f1e0f4849d240f47efc1075ac"
482+ integrity sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw= 537+ integrity sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=
483+ 538+
484 prelude-ls@~1.1.2: 539 prepend-http@^1.0.1:
485 version "1.1.2" 540 version "1.0.4"
486 resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" 541 resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
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 542@@ -5032,6 +5125,13 @@ rimraf@^3.0.0:
488 dependencies: 543 dependencies:
489 glob "^7.0.5" 544 glob "^7.1.3"
490 545
491+rimraf@~2.4.0: 546+rimraf@~2.4.0:
492+ version "2.4.5" 547+ version "2.4.5"
@@ -495,24 +550,24 @@ index 1e759af1..1eb61a9f 100644
495+ dependencies: 550+ dependencies:
496+ glob "^6.0.1" 551+ glob "^6.0.1"
497+ 552+
498 run-async@^0.1.0: 553 run-parallel-limit@^1.0.3:
499 version "0.1.0" 554 version "1.0.5"
500 resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" 555 resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.0.5.tgz#c29a4fd17b4df358cb52a8a697811a63c984f1b7"
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 556@@ -5069,6 +5169,11 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2,
502 resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 557 resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
503 integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 558 integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
504 559
505+safe-json-stringify@~1: 560+safe-json-stringify@~1:
506+ version "1.2.0" 561+ version "1.2.0"
507+ resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" 562+ resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd"
508+ integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg== 563+ integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==
509+ 564+
510 safe-regex@^1.1.0: 565 "safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
511 version "1.1.0" 566 version "2.1.2"
512 resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" 567 resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
513@@ -8857,7 +8967,14 @@ vary@~1.0.1: 568@@ -6337,7 +6442,14 @@ vary@^1, vary@~1.1.2:
514 resolved "https://registry.yarnpkg.com/vary/-/vary-1.0.1.tgz#99e4981566a286118dfb2b817357df7993376d10" 569 resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
515 integrity sha1-meSYFWaihhGN+yuBc1ffeZM3bRA= 570 integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
516 571
517-verror@1.10.0: 572-verror@1.10.0:
518+vasync@^1.6.4: 573+vasync@^1.6.4:
@@ -526,7 +581,7 @@ index 1e759af1..1eb61a9f 100644
526 version "1.10.0" 581 version "1.10.0"
527 resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" 582 resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
528 integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= 583 integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
529@@ -8866,6 +8983,13 @@ verror@1.10.0: 584@@ -6346,6 +6458,13 @@ verror@1.10.0:
530 core-util-is "1.0.2" 585 core-util-is "1.0.2"
531 extsprintf "^1.2.0" 586 extsprintf "^1.2.0"
532 587
@@ -537,6 +592,6 @@ index 1e759af1..1eb61a9f 100644
537+ dependencies: 592+ dependencies:
538+ extsprintf "1.2.0" 593+ extsprintf "1.2.0"
539+ 594+
540 videostream@^2.5.1: 595 videostream@^3.2.0:
541 version "2.6.0" 596 version "3.2.1"
542 resolved "https://registry.yarnpkg.com/videostream/-/videostream-2.6.0.tgz#7f0b2b84bc457c12cfe599aa2345f5cc06241ab6" 597 resolved "https://registry.yarnpkg.com/videostream/-/videostream-3.2.1.tgz#643688ad4bfbf37570d421e3196b7e0ad38eeebc"