diff --git a/client/src/app/+admin/follows/followers-list/followers-list.component.html b/client/src/app/+admin/follows/followers-list/followers-list.component.html
index a9e1d4cc9..b30edad9a 100644
--- a/client/src/app/+admin/follows/followers-list/followers-list.component.html
+++ b/client/src/app/+admin/follows/followers-list/followers-list.component.html
@@ -22,7 +22,7 @@
0" [totalRecords]="totalRecords" [rows]="rowsPerPage" [rowsPerPageOptions]="rowsPerPageOptions"
- [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id"
+ [sortField]="sort.field" [sortOrder]="sort.order" (onLazyLoad)="loadLazy($event)" dataKey="id" [resizableColumns]="true"
[(selection)]="selectedUsers"
[showCurrentPageReport]="true" i18n-currentPageReportTemplate
currentPageReportTemplate="Showing {{'{first}'}} to {{'{last}'}} of {{'{totalRecords}'}} users"
@@ -42,12 +42,12 @@
|
- Username |
+ Username |
Email |
- Video quota |
- Role |
- Auth plugin |
- Created |
+ Video quota |
+ Role |
+ Auth plugin |
+ Created |
|
@@ -103,7 +103,7 @@
{{ user.pluginAuth }}
- {{ user.createdAt }} |
+ {{ user.createdAt | date: 'short' }} |
diff --git a/package.json b/package.json
index e0dafd24a..6fb816d7f 100644
--- a/package.json
+++ b/package.json
@@ -98,6 +98,7 @@
"cors": "^2.8.1",
"create-torrent": "^4.0.0",
"deep-object-diff": "^1.1.0",
+ "email-templates": "^7.0.4",
"express": "^4.12.4",
"express-oauth-server": "^2.0.0",
"express-rate-limit": "^5.0.0",
@@ -127,6 +128,7 @@
"pfeed": "1.1.11",
"pg": "^7.4.1",
"prompt": "^1.0.0",
+ "pug": "^2.0.4",
"redis": "^3.0.2",
"reflect-metadata": "^0.1.12",
"request": "^2.81.0",
diff --git a/server/controllers/api/videos/abuse.ts b/server/controllers/api/videos/abuse.ts
index bce50aefb..ec28fce67 100644
--- a/server/controllers/api/videos/abuse.ts
+++ b/server/controllers/api/videos/abuse.ts
@@ -1,5 +1,5 @@
import * as express from 'express'
-import { UserRight, VideoAbuseCreate, VideoAbuseState } from '../../../../shared'
+import { UserRight, VideoAbuseCreate, VideoAbuseState, VideoAbuse } from '../../../../shared'
import { logger } from '../../../helpers/logger'
import { getFormattedObjects } from '../../../helpers/utils'
import { sequelizeTypescript } from '../../../initializers/database'
@@ -24,6 +24,7 @@ import { Notifier } from '../../../lib/notifier'
import { sendVideoAbuse } from '../../../lib/activitypub/send/send-flag'
import { MVideoAbuseAccountVideo } from '../../../typings/models/video'
import { getServerActor } from '@server/models/application/application'
+import { MAccountDefault } from '@server/typings/models'
const auditLogger = auditLoggerFactory('abuse')
const abuseVideoRouter = express.Router()
@@ -117,9 +118,11 @@ async function deleteVideoAbuse (req: express.Request, res: express.Response) {
async function reportVideoAbuse (req: express.Request, res: express.Response) {
const videoInstance = res.locals.videoAll
const body: VideoAbuseCreate = req.body
+ let reporterAccount: MAccountDefault
+ let videoAbuseJSON: VideoAbuse
- const videoAbuse = await sequelizeTypescript.transaction(async t => {
- const reporterAccount = await AccountModel.load(res.locals.oauth.token.User.Account.id, t)
+ const videoAbuseInstance = await sequelizeTypescript.transaction(async t => {
+ reporterAccount = await AccountModel.load(res.locals.oauth.token.User.Account.id, t)
const abuseToCreate = {
reporterAccountId: reporterAccount.id,
@@ -137,14 +140,19 @@ async function reportVideoAbuse (req: express.Request, res: express.Response) {
await sendVideoAbuse(reporterAccount.Actor, videoAbuseInstance, videoInstance, t)
}
- auditLogger.create(reporterAccount.Actor.getIdentifier(), new VideoAbuseAuditView(videoAbuseInstance.toFormattedJSON()))
+ videoAbuseJSON = videoAbuseInstance.toFormattedJSON()
+ auditLogger.create(reporterAccount.Actor.getIdentifier(), new VideoAbuseAuditView(videoAbuseJSON))
return videoAbuseInstance
})
- Notifier.Instance.notifyOnNewVideoAbuse(videoAbuse)
+ Notifier.Instance.notifyOnNewVideoAbuse({
+ videoAbuse: videoAbuseJSON,
+ videoAbuseInstance,
+ reporter: reporterAccount.Actor.getIdentifier()
+ })
logger.info('Abuse report for video %s created.', videoInstance.name)
- return res.json({ videoAbuse: videoAbuse.toFormattedJSON() }).end()
+ return res.json({ videoAbuseJSON }).end()
}
diff --git a/server/lib/activitypub/process/process-flag.ts b/server/lib/activitypub/process/process-flag.ts
index 9a488a473..7337f337c 100644
--- a/server/lib/activitypub/process/process-flag.ts
+++ b/server/lib/activitypub/process/process-flag.ts
@@ -8,7 +8,8 @@ import { getOrCreateVideoAndAccountAndChannel } from '../videos'
import { Notifier } from '../../notifier'
import { getAPId } from '../../../helpers/activitypub'
import { APProcessorOptions } from '../../../typings/activitypub-processor.model'
-import { MActorSignature, MVideoAbuseVideo } from '../../../typings/models'
+import { MActorSignature, MVideoAbuseAccountVideo } from '../../../typings/models'
+import { AccountModel } from '@server/models/account/account'
async function processFlagActivity (options: APProcessorOptions) {
const { activity, byActor } = options
@@ -36,8 +37,9 @@ async function processCreateVideoAbuse (activity: ActivityCreate | ActivityFlag,
logger.debug('Reporting remote abuse for video %s.', getAPId(object))
const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: object })
+ const reporterAccount = await sequelizeTypescript.transaction(async t => AccountModel.load(account.id, t))
- const videoAbuse = await sequelizeTypescript.transaction(async t => {
+ const videoAbuseInstance = await sequelizeTypescript.transaction(async t => {
const videoAbuseData = {
reporterAccountId: account.id,
reason: flag.content,
@@ -45,15 +47,22 @@ async function processCreateVideoAbuse (activity: ActivityCreate | ActivityFlag,
state: VideoAbuseState.PENDING
}
- const videoAbuseInstance = await VideoAbuseModel.create(videoAbuseData, { transaction: t }) as MVideoAbuseVideo
+ const videoAbuseInstance: MVideoAbuseAccountVideo = await VideoAbuseModel.create(videoAbuseData, { transaction: t })
videoAbuseInstance.Video = video
+ videoAbuseInstance.Account = reporterAccount
logger.info('Remote abuse for video uuid %s created', flag.object)
return videoAbuseInstance
})
- Notifier.Instance.notifyOnNewVideoAbuse(videoAbuse)
+ const videoAbuseJSON = videoAbuseInstance.toFormattedJSON()
+
+ Notifier.Instance.notifyOnNewVideoAbuse({
+ videoAbuse: videoAbuseJSON,
+ videoAbuseInstance,
+ reporter: reporterAccount.Actor.getIdentifier()
+ })
} catch (err) {
logger.debug('Cannot process report of %s. (Maybe not a video abuse).', getAPId(object), { err })
}
diff --git a/server/lib/emailer.ts b/server/lib/emailer.ts
index 45d57fd28..935c9e882 100644
--- a/server/lib/emailer.ts
+++ b/server/lib/emailer.ts
@@ -1,5 +1,5 @@
import { createTransport, Transporter } from 'nodemailer'
-import { isTestInstance } from '../helpers/core-utils'
+import { isTestInstance, root } from '../helpers/core-utils'
import { bunyanLogger, logger } from '../helpers/logger'
import { CONFIG, isEmailEnabled } from '../initializers/config'
import { JobQueue } from './job-queue'
@@ -16,6 +16,12 @@ import {
import { MActorFollowActors, MActorFollowFull, MUser } from '../typings/models'
import { MVideoImport, MVideoImportVideo } from '@server/typings/models/video/video-import'
import { EmailPayload } from '@shared/models'
+import { join } from 'path'
+import { VideoAbuse } from '../../shared/models/videos'
+import { SendEmailOptions } from '../../shared/models/server/emailer.model'
+import { merge } from 'lodash'
+import { VideoChannelModel } from '@server/models/video/video-channel'
+const Email = require('email-templates')
class Emailer {
@@ -105,37 +111,36 @@ class Emailer {
const channelName = video.VideoChannel.getDisplayName()
const videoUrl = WEBSERVER.URL + video.getWatchStaticPath()
- const text = 'Hi dear user,\n\n' +
- `Your subscription ${channelName} just published a new video: ${video.name}` +
- '\n\n' +
- `You can view it on ${videoUrl} ` +
- '\n\n' +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
-
const emailPayload: EmailPayload = {
to,
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + channelName + ' just published a new video',
- text
+ subject: channelName + ' just published a new video',
+ text: `Your subscription ${channelName} just published a new video: "${video.name}".`,
+ locals: {
+ title: 'New content ',
+ action: {
+ text: 'View video',
+ url: videoUrl
+ }
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
}
addNewFollowNotification (to: string[], actorFollow: MActorFollowFull, followType: 'account' | 'channel') {
- const followerName = actorFollow.ActorFollower.Account.getDisplayName()
const followingName = (actorFollow.ActorFollowing.VideoChannel || actorFollow.ActorFollowing.Account).getDisplayName()
- const text = 'Hi dear user,\n\n' +
- `Your ${followType} ${followingName} has a new subscriber: ${followerName}` +
- '\n\n' +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
-
const emailPayload: EmailPayload = {
+ template: 'follower-on-channel',
to,
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + 'New follower on your channel ' + followingName,
- text
+ subject: `New follower on your channel ${followingName}`,
+ locals: {
+ followerName: actorFollow.ActorFollower.Account.getDisplayName(),
+ followerUrl: actorFollow.ActorFollower.url,
+ followingName,
+ followingUrl: actorFollow.ActorFollowing.url,
+ followType
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
@@ -144,32 +149,28 @@ class Emailer {
addNewInstanceFollowerNotification (to: string[], actorFollow: MActorFollowActors) {
const awaitingApproval = actorFollow.state === 'pending' ? ' awaiting manual approval.' : ''
- const text = 'Hi dear admin,\n\n' +
- `Your instance has a new follower: ${actorFollow.ActorFollower.url}${awaitingApproval}` +
- '\n\n' +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
-
const emailPayload: EmailPayload = {
to,
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + 'New instance follower',
- text
+ subject: 'New instance follower',
+ text: `Your instance has a new follower: ${actorFollow.ActorFollower.url}${awaitingApproval}.`,
+ locals: {
+ title: 'New instance follower',
+ action: {
+ text: 'Review followers',
+ url: WEBSERVER.URL + '/admin/follows/followers-list'
+ }
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
}
addAutoInstanceFollowingNotification (to: string[], actorFollow: MActorFollowActors) {
- const text = 'Hi dear admin,\n\n' +
- `Your instance automatically followed a new instance: ${actorFollow.ActorFollowing.url}` +
- '\n\n' +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
-
+ const instanceUrl = actorFollow.ActorFollowing.url
const emailPayload: EmailPayload = {
to,
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + 'Auto instance following',
- text
+ subject: 'Auto instance following',
+ text: `Your instance automatically followed a new instance: ${instanceUrl}.`
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
@@ -178,18 +179,17 @@ class Emailer {
myVideoPublishedNotification (to: string[], video: MVideo) {
const videoUrl = WEBSERVER.URL + video.getWatchStaticPath()
- const text = 'Hi dear user,\n\n' +
- `Your video ${video.name} has been published.` +
- '\n\n' +
- `You can view it on ${videoUrl} ` +
- '\n\n' +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
-
const emailPayload: EmailPayload = {
to,
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + `Your video ${video.name} is published`,
- text
+ subject: `Your video ${video.name} has been published`,
+ text: `Your video "${video.name}" has been published.`,
+ locals: {
+ title: 'You video is live',
+ action: {
+ text: 'View video',
+ url: videoUrl
+ }
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
@@ -198,18 +198,17 @@ class Emailer {
myVideoImportSuccessNotification (to: string[], videoImport: MVideoImportVideo) {
const videoUrl = WEBSERVER.URL + videoImport.Video.getWatchStaticPath()
- const text = 'Hi dear user,\n\n' +
- `Your video import ${videoImport.getTargetIdentifier()} is finished.` +
- '\n\n' +
- `You can view the imported video on ${videoUrl} ` +
- '\n\n' +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
-
const emailPayload: EmailPayload = {
to,
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + `Your video import ${videoImport.getTargetIdentifier()} is finished`,
- text
+ subject: `Your video import ${videoImport.getTargetIdentifier()} is complete`,
+ text: `Your video "${videoImport.getTargetIdentifier()}" just finished importing.`,
+ locals: {
+ title: 'Import complete',
+ action: {
+ text: 'View video',
+ url: videoUrl
+ }
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
@@ -218,40 +217,47 @@ class Emailer {
myVideoImportErrorNotification (to: string[], videoImport: MVideoImport) {
const importUrl = WEBSERVER.URL + '/my-account/video-imports'
- const text = 'Hi dear user,\n\n' +
- `Your video import ${videoImport.getTargetIdentifier()} encountered an error.` +
+ const text =
+ `Your video import "${videoImport.getTargetIdentifier()}" encountered an error.` +
'\n\n' +
- `See your videos import dashboard for more information: ${importUrl}` +
- '\n\n' +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
+ `See your videos import dashboard for more information: ${importUrl}.`
const emailPayload: EmailPayload = {
to,
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + `Your video import ${videoImport.getTargetIdentifier()} encountered an error`,
- text
+ subject: `Your video import "${videoImport.getTargetIdentifier()}" encountered an error`,
+ text,
+ locals: {
+ title: 'Import failed',
+ action: {
+ text: 'Review imports',
+ url: importUrl
+ }
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
}
addNewCommentOnMyVideoNotification (to: string[], comment: MCommentOwnerVideo) {
- const accountName = comment.Account.getDisplayName()
const video = comment.Video
+ const videoUrl = WEBSERVER.URL + comment.Video.getWatchStaticPath()
const commentUrl = WEBSERVER.URL + comment.getCommentStaticPath()
- const text = 'Hi dear user,\n\n' +
- `A new comment has been posted by ${accountName} on your video ${video.name}` +
- '\n\n' +
- `You can view it on ${commentUrl} ` +
- '\n\n' +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
-
const emailPayload: EmailPayload = {
+ template: 'video-comment-new',
to,
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + 'New comment on your video ' + video.name,
- text
+ subject: 'New comment on your video ' + video.name,
+ locals: {
+ accountName: comment.Account.getDisplayName(),
+ accountUrl: comment.Account.Actor.url,
+ comment,
+ video,
+ videoUrl,
+ action: {
+ text: 'View comment',
+ url: commentUrl
+ }
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
@@ -260,75 +266,88 @@ class Emailer {
addNewCommentMentionNotification (to: string[], comment: MCommentOwnerVideo) {
const accountName = comment.Account.getDisplayName()
const video = comment.Video
+ const videoUrl = WEBSERVER.URL + comment.Video.getWatchStaticPath()
const commentUrl = WEBSERVER.URL + comment.getCommentStaticPath()
- const text = 'Hi dear user,\n\n' +
- `${accountName} mentioned you on video ${video.name}` +
- '\n\n' +
- `You can view the comment on ${commentUrl} ` +
- '\n\n' +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
-
const emailPayload: EmailPayload = {
+ template: 'video-comment-mention',
to,
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + 'Mention on video ' + video.name,
- text
+ subject: 'Mention on video ' + video.name,
+ locals: {
+ comment,
+ video,
+ videoUrl,
+ accountName,
+ action: {
+ text: 'View comment',
+ url: commentUrl
+ }
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
}
- addVideoAbuseModeratorsNotification (to: string[], videoAbuse: MVideoAbuseVideo) {
- const videoUrl = WEBSERVER.URL + videoAbuse.Video.getWatchStaticPath()
-
- const text = 'Hi,\n\n' +
- `${WEBSERVER.HOST} received an abuse for the following video: ${videoUrl}\n\n` +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
+ addVideoAbuseModeratorsNotification (to: string[], parameters: {
+ videoAbuse: VideoAbuse
+ videoAbuseInstance: MVideoAbuseVideo
+ reporter: string
+ }) {
+ const videoAbuseUrl = WEBSERVER.URL + '/admin/moderation/video-abuses/list?search=%23' + parameters.videoAbuse.id
+ const videoUrl = WEBSERVER.URL + parameters.videoAbuseInstance.Video.getWatchStaticPath()
const emailPayload: EmailPayload = {
+ template: 'video-abuse-new',
to,
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + 'Received a video abuse',
- text
+ subject: `New video abuse report from ${parameters.reporter}`,
+ locals: {
+ videoUrl,
+ videoAbuseUrl,
+ videoCreatedAt: new Date(parameters.videoAbuseInstance.Video.createdAt).toLocaleString(),
+ videoPublishedAt: new Date(parameters.videoAbuseInstance.Video.publishedAt).toLocaleString(),
+ videoAbuse: parameters.videoAbuse,
+ reporter: parameters.reporter,
+ action: {
+ text: 'View report #' + parameters.videoAbuse.id,
+ url: videoAbuseUrl
+ }
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
}
- addVideoAutoBlacklistModeratorsNotification (to: string[], videoBlacklist: MVideoBlacklistLightVideo) {
+ async addVideoAutoBlacklistModeratorsNotification (to: string[], videoBlacklist: MVideoBlacklistLightVideo) {
const VIDEO_AUTO_BLACKLIST_URL = WEBSERVER.URL + '/admin/moderation/video-auto-blacklist/list'
const videoUrl = WEBSERVER.URL + videoBlacklist.Video.getWatchStaticPath()
-
- const text = 'Hi,\n\n' +
- 'A recently added video was auto-blacklisted and requires moderator review before publishing.' +
- '\n\n' +
- `You can view it and take appropriate action on ${videoUrl}` +
- '\n\n' +
- `A full list of auto-blacklisted videos can be reviewed here: ${VIDEO_AUTO_BLACKLIST_URL}` +
- '\n\n' +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
+ const channel = (await VideoChannelModel.loadByIdAndPopulateAccount(videoBlacklist.Video.channelId)).toFormattedSummaryJSON()
const emailPayload: EmailPayload = {
+ template: 'video-auto-blacklist-new',
to,
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + 'An auto-blacklisted video is awaiting review',
- text
+ subject: 'A new video is pending moderation',
+ locals: {
+ channel,
+ videoUrl,
+ videoName: videoBlacklist.Video.name,
+ action: {
+ text: 'Review autoblacklist',
+ url: VIDEO_AUTO_BLACKLIST_URL
+ }
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
}
addNewUserRegistrationNotification (to: string[], user: MUser) {
- const text = 'Hi,\n\n' +
- `User ${user.username} just registered on ${WEBSERVER.HOST} PeerTube instance.\n\n` +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
-
const emailPayload: EmailPayload = {
+ template: 'user-registered',
to,
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + 'New user registration on ' + WEBSERVER.HOST,
- text
+ subject: `a new user registered on ${WEBSERVER.HOST}: ${user.username}`,
+ locals: {
+ user
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
@@ -341,16 +360,13 @@ class Emailer {
const reasonString = videoBlacklist.reason ? ` for the following reason: ${videoBlacklist.reason}` : ''
const blockedString = `Your video ${videoName} (${videoUrl} on ${WEBSERVER.HOST} has been blacklisted${reasonString}.`
- const text = 'Hi,\n\n' +
- blockedString +
- '\n\n' +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
-
const emailPayload: EmailPayload = {
to,
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + `Video ${videoName} blacklisted`,
- text
+ subject: `Video ${videoName} blacklisted`,
+ text: blockedString,
+ locals: {
+ title: 'Your video was blacklisted'
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
@@ -359,66 +375,53 @@ class Emailer {
addVideoUnblacklistNotification (to: string[], video: MVideo) {
const videoUrl = WEBSERVER.URL + video.getWatchStaticPath()
- const text = 'Hi,\n\n' +
- `Your video ${video.name} (${videoUrl}) on ${WEBSERVER.HOST} has been unblacklisted.` +
- '\n\n' +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
-
const emailPayload: EmailPayload = {
to,
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + `Video ${video.name} unblacklisted`,
- text
+ subject: `Video ${video.name} unblacklisted`,
+ text: `Your video "${video.name}" (${videoUrl}) on ${WEBSERVER.HOST} has been unblacklisted.`,
+ locals: {
+ title: 'Your video was unblacklisted'
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
}
addPasswordResetEmailJob (to: string, resetPasswordUrl: string) {
- const text = 'Hi dear user,\n\n' +
- `A reset password procedure for your account ${to} has been requested on ${WEBSERVER.HOST} ` +
- `Please follow this link to reset it: ${resetPasswordUrl} (the link will expire within 1 hour)\n\n` +
- 'If you are not the person who initiated this request, please ignore this email.\n\n' +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
-
const emailPayload: EmailPayload = {
+ template: 'password-reset',
to: [ to ],
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + 'Reset your password',
- text
+ subject: 'Reset your account password',
+ locals: {
+ resetPasswordUrl
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
}
- addPasswordCreateEmailJob (username: string, to: string, resetPasswordUrl: string) {
- const text = 'Hi,\n\n' +
- `Welcome to your ${WEBSERVER.HOST} PeerTube instance. Your username is: ${username}.\n\n` +
- `Please set your password by following this link: ${resetPasswordUrl} (this link will expire within seven days).\n\n` +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
-
+ addPasswordCreateEmailJob (username: string, to: string, createPasswordUrl: string) {
const emailPayload: EmailPayload = {
+ template: 'password-create',
to: [ to ],
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + 'New PeerTube account password',
- text
+ subject: 'Create your account password',
+ locals: {
+ username,
+ createPasswordUrl
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
}
addVerifyEmailJob (to: string, verifyEmailUrl: string) {
- const text = 'Welcome to PeerTube,\n\n' +
- `To start using PeerTube on ${WEBSERVER.HOST} you must verify your email! ` +
- `Please follow this link to verify this email belongs to you: ${verifyEmailUrl}\n\n` +
- 'If you are not the person who initiated this request, please ignore this email.\n\n' +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
-
const emailPayload: EmailPayload = {
+ template: 'verify-email',
to: [ to ],
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + 'Verify your email',
- text
+ subject: `Verify your email on ${WEBSERVER.HOST}`,
+ locals: {
+ verifyEmailUrl
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
@@ -427,39 +430,28 @@ class Emailer {
addUserBlockJob (user: MUser, blocked: boolean, reason?: string) {
const reasonString = reason ? ` for the following reason: ${reason}` : ''
const blockedWord = blocked ? 'blocked' : 'unblocked'
- const blockedString = `Your account ${user.username} on ${WEBSERVER.HOST} has been ${blockedWord}${reasonString}.`
-
- const text = 'Hi,\n\n' +
- blockedString +
- '\n\n' +
- 'Cheers,\n' +
- `${CONFIG.EMAIL.BODY.SIGNATURE}`
const to = user.email
const emailPayload: EmailPayload = {
to: [ to ],
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + 'Account ' + blockedWord,
- text
+ subject: 'Account ' + blockedWord,
+ text: `Your account ${user.username} on ${WEBSERVER.HOST} has been ${blockedWord}${reasonString}.`
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
}
addContactFormJob (fromEmail: string, fromName: string, subject: string, body: string) {
- const text = 'Hello dear admin,\n\n' +
- fromName + ' sent you a message' +
- '\n\n---------------------------------------\n\n' +
- body +
- '\n\n---------------------------------------\n\n' +
- 'Cheers,\n' +
- 'PeerTube.'
-
const emailPayload: EmailPayload = {
- fromDisplayName: fromEmail,
- replyTo: fromEmail,
+ template: 'contact-form',
to: [ CONFIG.ADMIN.EMAIL ],
- subject: CONFIG.EMAIL.SUBJECT.PREFIX + subject,
- text
+ replyTo: `"${fromName}" <${fromEmail}>`,
+ subject: `(contact form) ${subject}`,
+ locals: {
+ fromName,
+ fromEmail,
+ body
+ }
}
return JobQueue.Instance.createJob({ type: 'email', payload: emailPayload })
@@ -470,18 +462,44 @@ class Emailer {
throw new Error('Cannot send mail because SMTP is not configured.')
}
- const fromDisplayName = options.fromDisplayName
- ? options.fromDisplayName
+ const fromDisplayName = options.from
+ ? options.from
: WEBSERVER.HOST
+ const email = new Email({
+ send: true,
+ message: {
+ from: `"${fromDisplayName}" <${CONFIG.SMTP.FROM_ADDRESS}>`
+ },
+ transport: this.transporter,
+ views: {
+ root: join(root(), 'server', 'lib', 'emails')
+ },
+ subjectPrefix: CONFIG.EMAIL.SUBJECT.PREFIX
+ })
+
for (const to of options.to) {
- await this.transporter.sendMail({
- from: `"${fromDisplayName}" <${CONFIG.SMTP.FROM_ADDRESS}>`,
- replyTo: options.replyTo,
- to,
- subject: options.subject,
- text: options.text
- })
+ await email
+ .send(merge(
+ {
+ template: 'common',
+ message: {
+ to,
+ from: options.from,
+ subject: options.subject,
+ replyTo: options.replyTo
+ },
+ locals: { // default variables available in all templates
+ WEBSERVER,
+ EMAIL: CONFIG.EMAIL,
+ text: options.text,
+ subject: options.subject
+ }
+ },
+ options // overriden/new variables given for a specific template in the payload
+ ) as SendEmailOptions)
+ .then(logger.info)
+ .catch(logger.error)
}
}
diff --git a/server/lib/emails/common/base.pug b/server/lib/emails/common/base.pug
new file mode 100644
index 000000000..9a1894cab
--- /dev/null
+++ b/server/lib/emails/common/base.pug
@@ -0,0 +1,267 @@
+//-
+ The email background color is defined in three places:
+ 1. body tag: for most email clients
+ 2. center tag: for Gmail and Inbox mobile apps and web versions of Gmail, GSuite, Inbox, Yahoo, AOL, Libero, Comcast, freenet, Mail.ru, Orange.fr
+ 3. mso conditional: For Windows 10 Mail
+- var backgroundColor = "#fff";
+- var mainColor = "#f2690d";
+doctype html
+head
+ // This template is heavily adapted from the Cerberus Fluid template. Kudos to them!
+ meta(charset='utf-8')
+ //- utf-8 works for most cases
+ meta(name='viewport' content='width=device-width')
+ //- Forcing initial-scale shouldn't be necessary
+ meta(http-equiv='X-UA-Compatible' content='IE=edge')
+ //- Use the latest (edge) version of IE rendering engine
+ meta(name='x-apple-disable-message-reformatting')
+ //- Disable auto-scale in iOS 10 Mail entirely
+ meta(name='format-detection' content='telephone=no,address=no,email=no,date=no,url=no')
+ //- Tell iOS not to automatically link certain text strings.
+ meta(name='color-scheme' content='light')
+ meta(name='supported-color-schemes' content='light')
+ //- The title tag shows in email notifications, like Android 4.4.
+ title #{subject}
+ //- What it does: Makes background images in 72ppi Outlook render at correct size.
+ //if gte mso 9
+ xml
+ o:officedocumentsettings
+ o:allowpng
+ o:pixelsperinch 96
+ //- CSS Reset : BEGIN
+ style.
+ /* What it does: Tells the email client that only light styles are provided but the client can transform them to dark. A duplicate of meta color-scheme meta tag above. */
+ :root {
+ color-scheme: light;
+ supported-color-schemes: light;
+ }
+ /* What it does: Remove spaces around the email design added by some email clients. */
+ /* Beware: It can remove the padding / margin and add a background color to the compose a reply window. */
+ html,
+ body {
+ margin: 0 auto !important;
+ padding: 0 !important;
+ height: 100% !important;
+ width: 100% !important;
+ }
+ /* What it does: Stops email clients resizing small text. */
+ * {
+ -ms-text-size-adjust: 100%;
+ -webkit-text-size-adjust: 100%;
+ }
+ /* What it does: Centers email on Android 4.4 */
+ div[style*="margin: 16px 0"] {
+ margin: 0 !important;
+ }
+ /* What it does: forces Samsung Android mail clients to use the entire viewport */
+ #MessageViewBody, #MessageWebViewDiv{
+ width: 100% !important;
+ }
+ /* What it does: Stops Outlook from adding extra spacing to tables. */
+ table,
+ td {
+ mso-table-lspace: 0pt !important;
+ mso-table-rspace: 0pt !important;
+ }
+ /* What it does: Fixes webkit padding issue. */
+ table {
+ border-spacing: 0 !important;
+ border-collapse: collapse !important;
+ table-layout: fixed !important;
+ margin: 0 auto !important;
+ }
+ /* What it does: Uses a better rendering method when resizing images in IE. */
+ img {
+ -ms-interpolation-mode:bicubic;
+ }
+ /* What it does: Prevents Windows 10 Mail from underlining links despite inline CSS. Styles for underlined links should be inline. */
+ a {
+ text-decoration: none;
+ }
+ a:not(.nocolor) {
+ color: #{mainColor};
+ }
+ a.nocolor {
+ color: inherit !important;
+ }
+ /* What it does: A work-around for email clients meddling in triggered links. */
+ a[x-apple-data-detectors], /* iOS */
+ .unstyle-auto-detected-links a,
+ .aBn {
+ border-bottom: 0 !important;
+ cursor: default !important;
+ color: inherit !important;
+ text-decoration: none !important;
+ font-size: inherit !important;
+ font-family: inherit !important;
+ font-weight: inherit !important;
+ line-height: inherit !important;
+ }
+ /* What it does: Prevents Gmail from displaying a download button on large, non-linked images. */
+ .a6S {
+ display: none !important;
+ opacity: 0.01 !important;
+ }
+ /* What it does: Prevents Gmail from changing the text color in conversation threads. */
+ .im {
+ color: inherit !important;
+ }
+ /* If the above doesn't work, add a .g-img class to any image in question. */
+ img.g-img + div {
+ display: none !important;
+ }
+ /* What it does: Removes right gutter in Gmail iOS app: https://github.com/TedGoas/Cerberus/issues/89 */
+ /* Create one of these media queries for each additional viewport size you'd like to fix */
+ /* iPhone 4, 4S, 5, 5S, 5C, and 5SE */
+ @media only screen and (min-device-width: 320px) and (max-device-width: 374px) {
+ u ~ div .email-container {
+ min-width: 320px !important;
+ }
+ }
+ /* iPhone 6, 6S, 7, 8, and X */
+ @media only screen and (min-device-width: 375px) and (max-device-width: 413px) {
+ u ~ div .email-container {
+ min-width: 375px !important;
+ }
+ }
+ /* iPhone 6+, 7+, and 8+ */
+ @media only screen and (min-device-width: 414px) {
+ u ~ div .email-container {
+ min-width: 414px !important;
+ }
+ }
+ //- CSS Reset : END
+ //- CSS for PeerTube : START
+ style.
+ blockquote {
+ margin-left: 0;
+ padding-left: 20px;
+ border-left: 2px solid #f2690d;
+ }
+ //- CSS for PeerTube : END
+ //- Progressive Enhancements : BEGIN
+ style.
+ /* What it does: Hover styles for buttons */
+ .button-td,
+ .button-a {
+ transition: all 100ms ease-in;
+ }
+ .button-td-primary:hover,
+ .button-a-primary:hover {
+ background: #555555 !important;
+ border-color: #555555 !important;
+ }
+ /* Media Queries */
+ @media screen and (max-width: 600px) {
+ /* What it does: Adjust typography on small screens to improve readability */
+ .email-container p {
+ font-size: 17px !important;
+ }
+ }
+ //- Progressive Enhancements : END
+
+body(width="100%" style="margin: 0; padding: 0 !important; mso-line-height-rule: exactly; background-color: #{backgroundColor};")
+ center(role='article' aria-roledescription='email' lang='en' style='width: 100%; background-color: #{backgroundColor};')
+ //if mso | IE
+ table(role='presentation' border='0' cellpadding='0' cellspacing='0' width='100%' style='background-color: #fff;')
+ tr
+ td
+ //- Visually Hidden Preheader Text : BEGIN
+ div(style='max-height:0; overflow:hidden; mso-hide:all;' aria-hidden='true')
+ block preheader
+ //- Visually Hidden Preheader Text : END
+
+ //- Create white space after the desired preview text so email clients don’t pull other distracting text into the inbox preview. Extend as necessary.
+ //- Preview Text Spacing Hack : BEGIN
+ div(style='display: none; font-size: 1px; line-height: 1px; max-height: 0px; max-width: 0px; opacity: 0; overflow: hidden; mso-hide: all; font-family: sans-serif;')
+ |
+ //- Preview Text Spacing Hack : END
+
+ //-
+ Set the email width. Defined in two places:
+ 1. max-width for all clients except Desktop Windows Outlook, allowing the email to squish on narrow but never go wider than 600px.
+ 2. MSO tags for Desktop Windows Outlook enforce a 600px width.
+ .email-container(style='max-width: 600px; margin: 0 auto;')
+ //if mso
+ table(align='center' role='presentation' cellspacing='0' cellpadding='0' border='0' width='600')
+ tr
+ td
+ //- Email Body : BEGIN
+ table(align='center' role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%' style='margin: auto;')
+ //- 1 Column Text + Button : BEGIN
+ tr
+ td(style='background-color: #ffffff;')
+ table(role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%')
+ tr
+ td(style='padding: 20px; font-family: sans-serif; font-size: 15px; line-height: 20px; color: #555555;')
+ table(role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%")
+ tr
+ td(width="40px")
+ img(src=`${WEBSERVER.URL}/client/assets/images/icons/icon-192x192.png` width="auto" height="30px" alt="icon" border="0" style="height: 30px; background: #ffffff; font-family: sans-serif; font-size: 15px; line-height: 15px; color: #555555;")
+ td
+ h1(style='margin: 10px 0 10px 0; font-family: sans-serif; font-size: 25px; line-height: 30px; color: #333333; font-weight: normal;')
+ block title
+ if title
+ | #{title}
+ else
+ | Something requires your attention
+ p(style='margin: 0;')
+ block body
+ if action
+ tr
+ td(style='padding: 0 20px;')
+ //- Button : BEGIN
+ table(align='center' role='presentation' cellspacing='0' cellpadding='0' border='0' style='margin: auto;')
+ tr
+ td.button-td.button-td-primary(style='border-radius: 4px; background: #222222;')
+ a.button-a.button-a-primary(href=action.url style='background: #222222; border: 1px solid #000000; font-family: sans-serif; font-size: 15px; line-height: 15px; text-decoration: none; padding: 13px 17px; color: #ffffff; display: block; border-radius: 4px;') #{action.text}
+ //- Button : END
+ //- 1 Column Text + Button : END
+ //- Clear Spacer : BEGIN
+ tr
+ td(aria-hidden='true' height='20' style='font-size: 0px; line-height: 0px;')
+ br
+ //- Clear Spacer : END
+ //- 1 Column Text : BEGIN
+ if username
+ tr
+ td(style='background-color: #cccccc;')
+ table(role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%')
+ tr
+ td(style='padding: 20px; font-family: sans-serif; font-size: 15px; line-height: 20px; color: #555555;')
+ p(style='margin: 0;')
+ | You are receiving this email as part of your notification settings on #{WEBSERVER.HOST} for your account #{username}.
+ //- 1 Column Text : END
+ //- Email Body : END
+ //- Email Footer : BEGIN
+ table(align='center' role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%' style='margin: auto;')
+ tr
+ td(style='padding: 20px; padding-bottom: 0px; font-family: sans-serif; font-size: 12px; line-height: 15px; text-align: center; color: #888888;')
+ webversion
+ a.nocolor(href=`${WEBSERVER.URL}/my-account/notifications` style='color: #cccccc; font-weight: bold;') View in your notifications
+ br
+ tr
+ td(style='padding: 20px; padding-top: 10px; font-family: sans-serif; font-size: 12px; line-height: 15px; text-align: center; color: #888888;')
+ unsubscribe
+ a.nocolor(href=`${WEBSERVER.URL}/my-account/settings#notifications` style='color: #888888;') Manage your notification preferences in your profile
+ br
+ //- Email Footer : END
+ //if mso
+ //- Full Bleed Background Section : BEGIN
+ table(role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%' style=`background-color: ${mainColor};`)
+ tr
+ td
+ .email-container(align='center' style='max-width: 600px; margin: auto;')
+ //if mso
+ table(role='presentation' cellspacing='0' cellpadding='0' border='0' width='600' align='center')
+ tr
+ td
+ table(role='presentation' cellspacing='0' cellpadding='0' border='0' width='100%')
+ tr
+ td(style='padding: 20px; text-align: left; font-family: sans-serif; font-size: 12px; line-height: 20px; color: #ffffff;')
+ table(role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%")
+ tr
+ td(valign="top") #[a(href="https://github.com/Chocobozzz/PeerTube" style="color: white !important") PeerTube © 2015-#{new Date().getFullYear()}] #[a(href="https://github.com/Chocobozzz/PeerTube/blob/master/CREDITS.md" style="color: white !important") PeerTube Contributors]
+ //if mso
+ //- Full Bleed Background Section : END
+ //if mso | IE
diff --git a/server/lib/emails/common/greetings.pug b/server/lib/emails/common/greetings.pug
new file mode 100644
index 000000000..5efe29dfb
--- /dev/null
+++ b/server/lib/emails/common/greetings.pug
@@ -0,0 +1,11 @@
+extends base
+
+block body
+ if username
+ p Hi #{username},
+ else
+ p Hi,
+ block content
+ p
+ | Cheers,#[br]
+ | #{EMAIL.BODY.SIGNATURE}
\ No newline at end of file
diff --git a/server/lib/emails/common/html.pug b/server/lib/emails/common/html.pug
new file mode 100644
index 000000000..d76168b85
--- /dev/null
+++ b/server/lib/emails/common/html.pug
@@ -0,0 +1,4 @@
+extends greetings
+
+block content
+ p !{text}
\ No newline at end of file
diff --git a/server/lib/emails/common/mixins.pug b/server/lib/emails/common/mixins.pug
new file mode 100644
index 000000000..76b805a24
--- /dev/null
+++ b/server/lib/emails/common/mixins.pug
@@ -0,0 +1,3 @@
+mixin channel(channel)
+ - var handle = `${channel.name}@${channel.host}`
+ | #[a(href=`${WEBSERVER.URL}/video-channels/${handle}` title=handle) #{channel.displayName}]
\ No newline at end of file
diff --git a/server/lib/emails/contact-form/html.pug b/server/lib/emails/contact-form/html.pug
new file mode 100644
index 000000000..0073ff78e
--- /dev/null
+++ b/server/lib/emails/contact-form/html.pug
@@ -0,0 +1,9 @@
+extends ../common/greetings
+
+block title
+ | Someone just used the contact form
+
+block content
+ p #{fromName} sent you a message via the contact form on #[a(href=WEBSERVER.URL) #{WEBSERVER.HOST}]:
+ blockquote(style='white-space: pre-wrap') #{body}
+ p You can contact them at #[a(href=`mailto:${fromEmail}`) #{fromEmail}], or simply reply to this email to get in touch.
\ No newline at end of file
diff --git a/server/lib/emails/follower-on-channel/html.pug b/server/lib/emails/follower-on-channel/html.pug
new file mode 100644
index 000000000..8a352e90f
--- /dev/null
+++ b/server/lib/emails/follower-on-channel/html.pug
@@ -0,0 +1,9 @@
+extends ../common/greetings
+
+block title
+ | New follower on your channel
+
+block content
+ p.
+ Your #{followType} #[a(href=followingUrl) #{followingName}] has a new subscriber:
+ #[a(href=followerUrl) #{followerName}].
\ No newline at end of file
diff --git a/server/lib/emails/password-create/html.pug b/server/lib/emails/password-create/html.pug
new file mode 100644
index 000000000..45ff3078a
--- /dev/null
+++ b/server/lib/emails/password-create/html.pug
@@ -0,0 +1,10 @@
+extends ../common/greetings
+
+block title
+ | Password creation for your account
+
+block content
+ p.
+ Welcome to #[a(href=WEBSERVER.URL) #{WEBSERVER.HOST}], your PeerTube instance. Your username is: #{username}.
+ Please set your password by following #[a(href=createPasswordUrl) this link]: #[a(href=createPasswordUrl) #{createPasswordUrl}]
+ (this link will expire within seven days).
\ No newline at end of file
diff --git a/server/lib/emails/password-reset/html.pug b/server/lib/emails/password-reset/html.pug
new file mode 100644
index 000000000..bb6a9d16b
--- /dev/null
+++ b/server/lib/emails/password-reset/html.pug
@@ -0,0 +1,12 @@
+extends ../common/greetings
+
+block title
+ | Password reset for your account
+
+block content
+ p.
+ A reset password procedure for your account ${to} has been requested on #[a(href=WEBSERVER.URL) #{WEBSERVER.HOST}].
+ Please follow #[a(href=resetPasswordUrl) this link] to reset it: #[a(href=resetPasswordUrl) #{resetPasswordUrl}]
+ (the link will expire within 1 hour)
+ p.
+ If you are not the person who initiated this request, please ignore this email.
\ No newline at end of file
diff --git a/server/lib/emails/user-registered/html.pug b/server/lib/emails/user-registered/html.pug
new file mode 100644
index 000000000..20f62125e
--- /dev/null
+++ b/server/lib/emails/user-registered/html.pug
@@ -0,0 +1,10 @@
+extends ../common/greetings
+
+block title
+ | A new user registered
+
+block content
+ - var mail = user.email || user.pendingEmail;
+ p
+ | User #[a(href=`${WEBSERVER.URL}/accounts/${user.username}`) #{user.username}] just registered.
+ | You might want to contact them at #[a(href=`mailto:${mail}`) #{mail}].
\ No newline at end of file
diff --git a/server/lib/emails/verify-email/html.pug b/server/lib/emails/verify-email/html.pug
new file mode 100644
index 000000000..8a4a77703
--- /dev/null
+++ b/server/lib/emails/verify-email/html.pug
@@ -0,0 +1,14 @@
+extends ../common/greetings
+
+block title
+ | Account verification
+
+block content
+ p Welcome to PeerTube!
+ p.
+ You just created an account #[a(href=WEBSERVER.URL) #{WEBSERVER.HOST}], your new PeerTube instance.
+ Your username there is: #{username}.
+ p.
+ To start using PeerTube on #[a(href=WEBSERVER.URL) #{WEBSERVER.HOST}] you must verify your email first!
+ Please follow #[a(href=verifyEmailUrl) this link] to verify this email belongs to you: #[a(href=verifyEmailUrl) #{verifyEmailUrl}]
+ If you are not the person who initiated this request, please ignore this email.
\ No newline at end of file
diff --git a/server/lib/emails/video-abuse-new/html.pug b/server/lib/emails/video-abuse-new/html.pug
new file mode 100644
index 000000000..999c89d26
--- /dev/null
+++ b/server/lib/emails/video-abuse-new/html.pug
@@ -0,0 +1,18 @@
+extends ../common/greetings
+include ../common/mixins.pug
+
+block title
+ | A video is pending moderation
+
+block content
+ p
+ | #[a(href=WEBSERVER.URL) #{WEBSERVER.HOST}] received an abuse report for the #{videoAbuse.video.channel.isLocal ? '' : 'remote '}video "
+ a(href=videoUrl) #{videoAbuse.video.name}
+ | " by #[+channel(videoAbuse.video.channel)]
+ if videoPublishedAt
+ | , published the #{videoPublishedAt}.
+ else
+ | , uploaded the #{videoCreatedAt} but not yet published.
+ p The reporter, #{reporter}, cited the following reason(s):
+ blockquote #{videoAbuse.reason}
+ br(style="display: none;")
diff --git a/server/lib/emails/video-auto-blacklist-new/html.pug b/server/lib/emails/video-auto-blacklist-new/html.pug
new file mode 100644
index 000000000..07c8dfd16
--- /dev/null
+++ b/server/lib/emails/video-auto-blacklist-new/html.pug
@@ -0,0 +1,17 @@
+extends ../common/greetings
+include ../common/mixins
+
+block title
+ | A video is pending moderation
+
+block content
+ p
+ | A recently added video was auto-blacklisted and requires moderator review before going public:
+ |
+ a(href=videoUrl) #{videoName}
+ |
+ | by #[+channel(channel)].
+ p.
+ Apart from the publisher and the moderation team, no one will be able to see the video until you
+ unblacklist it. If you trust the publisher, any admin can whitelist the user for later videos so
+ that they don't require approval before going public.
diff --git a/server/lib/emails/video-comment-mention/html.pug b/server/lib/emails/video-comment-mention/html.pug
new file mode 100644
index 000000000..9e9ced62d
--- /dev/null
+++ b/server/lib/emails/video-comment-mention/html.pug
@@ -0,0 +1,11 @@
+extends ../common/greetings
+
+block title
+ | Someone mentioned you
+
+block content
+ p.
+ #[a(href=accountUrl title=handle) #{accountName}] mentioned you in a comment on video
+ "#[a(href=videoUrl) #{video.name}]":
+ blockquote #{comment.text}
+ br(style="display: none;")
\ No newline at end of file
diff --git a/server/lib/emails/video-comment-new/html.pug b/server/lib/emails/video-comment-new/html.pug
new file mode 100644
index 000000000..075af5717
--- /dev/null
+++ b/server/lib/emails/video-comment-new/html.pug
@@ -0,0 +1,11 @@
+extends ../common/greetings
+
+block title
+ | Someone commented your video
+
+block content
+ p.
+ #[a(href=accountUrl title=handle) #{accountName}] added a comment on your video
+ "#[a(href=videoUrl) #{video.name}]":
+ blockquote #{comment.text}
+ br(style="display: none;")
\ No newline at end of file
diff --git a/server/lib/notifier.ts b/server/lib/notifier.ts
index 710c2d30f..017739523 100644
--- a/server/lib/notifier.ts
+++ b/server/lib/notifier.ts
@@ -5,7 +5,7 @@ import { UserNotificationModel } from '../models/account/user-notification'
import { UserModel } from '../models/account/user'
import { PeerTubeSocket } from './peertube-socket'
import { CONFIG } from '../initializers/config'
-import { VideoPrivacy, VideoState } from '../../shared/models/videos'
+import { VideoPrivacy, VideoState, VideoAbuse } from '../../shared/models/videos'
import { AccountBlocklistModel } from '../models/account/account-blocklist'
import {
MCommentOwnerVideo,
@@ -77,9 +77,9 @@ class Notifier {
.catch(err => logger.error('Cannot notify mentions of comment %s.', comment.url, { err }))
}
- notifyOnNewVideoAbuse (videoAbuse: MVideoAbuseVideo): void {
- this.notifyModeratorsOfNewVideoAbuse(videoAbuse)
- .catch(err => logger.error('Cannot notify of new video abuse of video %s.', videoAbuse.Video.url, { err }))
+ notifyOnNewVideoAbuse (parameters: { videoAbuse: VideoAbuse, videoAbuseInstance: MVideoAbuseVideo, reporter: string }): void {
+ this.notifyModeratorsOfNewVideoAbuse(parameters)
+ .catch(err => logger.error('Cannot notify of new video abuse of video %s.', parameters.videoAbuseInstance.Video.url, { err }))
}
notifyOnVideoAutoBlacklist (videoBlacklist: MVideoBlacklistLightVideo): void {
@@ -350,11 +350,15 @@ class Notifier {
return this.notify({ users: admins, settingGetter, notificationCreator, emailSender })
}
- private async notifyModeratorsOfNewVideoAbuse (videoAbuse: MVideoAbuseVideo) {
+ private async notifyModeratorsOfNewVideoAbuse (parameters: {
+ videoAbuse: VideoAbuse
+ videoAbuseInstance: MVideoAbuseVideo
+ reporter: string
+ }) {
const moderators = await UserModel.listWithRight(UserRight.MANAGE_VIDEO_ABUSES)
if (moderators.length === 0) return
- logger.info('Notifying %s user/moderators of new video abuse %s.', moderators.length, videoAbuse.Video.url)
+ logger.info('Notifying %s user/moderators of new video abuse %s.', moderators.length, parameters.videoAbuseInstance.Video.url)
function settingGetter (user: MUserWithNotificationSetting) {
return user.NotificationSetting.videoAbuseAsModerator
@@ -364,15 +368,15 @@ class Notifier {
const notification: UserNotificationModelForApi = await UserNotificationModel.create({
type: UserNotificationType.NEW_VIDEO_ABUSE_FOR_MODERATORS,
userId: user.id,
- videoAbuseId: videoAbuse.id
+ videoAbuseId: parameters.videoAbuse.id
})
- notification.VideoAbuse = videoAbuse
+ notification.VideoAbuse = parameters.videoAbuseInstance
return notification
}
function emailSender (emails: string[]) {
- return Emailer.Instance.addVideoAbuseModeratorsNotification(emails, videoAbuse)
+ return Emailer.Instance.addVideoAbuseModeratorsNotification(emails, parameters)
}
return this.notify({ users: moderators, settingGetter, notificationCreator, emailSender })
diff --git a/server/tests/api/server/contact-form.ts b/server/tests/api/server/contact-form.ts
index bd1b0e38a..8d1270358 100644
--- a/server/tests/api/server/contact-form.ts
+++ b/server/tests/api/server/contact-form.ts
@@ -46,7 +46,7 @@ describe('Test contact form', function () {
const email = emails[0]
expect(email['from'][0]['address']).equal('test-admin@localhost')
- expect(email['from'][0]['name']).equal('toto@example.com')
+ expect(email['replyTo'][0]['address']).equal('toto@example.com')
expect(email['to'][0]['address']).equal('admin' + server.internalServerNumber + '@example.com')
expect(email['subject']).contains('my subject')
expect(email['text']).contains('my super message')
diff --git a/shared/extra-utils/users/user-notifications.ts b/shared/extra-utils/users/user-notifications.ts
index f949878e4..bd00894c4 100644
--- a/shared/extra-utils/users/user-notifications.ts
+++ b/shared/extra-utils/users/user-notifications.ts
@@ -110,10 +110,10 @@ async function checkNotification (
if (checkType === 'presence') {
const obj = inspect(base.socketNotifications, { depth: 5 })
- expect(socketNotification, 'The socket notification is absent. ' + obj).to.not.be.undefined
+ expect(socketNotification, 'The socket notification is absent when is should be present. ' + obj).to.not.be.undefined
} else {
const obj = inspect(socketNotification, { depth: 5 })
- expect(socketNotification, 'The socket notification is present. ' + obj).to.be.undefined
+ expect(socketNotification, 'The socket notification is present when is should not be present. ' + obj).to.be.undefined
}
}
@@ -125,9 +125,9 @@ async function checkNotification (
.find(e => emailNotificationFinder(e))
if (checkType === 'presence') {
- expect(email, 'The email is absent. ' + inspect(base.emails)).to.not.be.undefined
+ expect(email, 'The email is absent when is should be present. ' + inspect(base.emails)).to.not.be.undefined
} else {
- expect(email, 'The email is present. ' + inspect(email)).to.be.undefined
+ expect(email, 'The email is present when is should not be present. ' + inspect(email)).to.be.undefined
}
}
}
@@ -172,12 +172,12 @@ async function checkNewVideoFromSubscription (base: CheckerBaseParams, videoName
}
}
- function emailFinder (email: object) {
+ function emailNotificationFinder (email: object) {
const text = email['text']
return text.indexOf(videoUUID) !== -1 && text.indexOf('Your subscription') !== -1
}
- await checkNotification(base, notificationChecker, emailFinder, type)
+ await checkNotification(base, notificationChecker, emailNotificationFinder, type)
}
async function checkVideoIsPublished (base: CheckerBaseParams, videoName: string, videoUUID: string, type: CheckerType) {
@@ -195,12 +195,12 @@ async function checkVideoIsPublished (base: CheckerBaseParams, videoName: string
}
}
- function emailFinder (email: object) {
+ function emailNotificationFinder (email: object) {
const text: string = email['text']
return text.includes(videoUUID) && text.includes('Your video')
}
- await checkNotification(base, notificationChecker, emailFinder, type)
+ await checkNotification(base, notificationChecker, emailNotificationFinder, type)
}
async function checkMyVideoImportIsFinished (
@@ -226,14 +226,14 @@ async function checkMyVideoImportIsFinished (
}
}
- function emailFinder (email: object) {
+ function emailNotificationFinder (email: object) {
const text: string = email['text']
const toFind = success ? ' finished' : ' error'
return text.includes(url) && text.includes(toFind)
}
- await checkNotification(base, notificationChecker, emailFinder, type)
+ await checkNotification(base, notificationChecker, emailNotificationFinder, type)
}
async function checkUserRegistered (base: CheckerBaseParams, username: string, type: CheckerType) {
@@ -251,13 +251,13 @@ async function checkUserRegistered (base: CheckerBaseParams, username: string, t
}
}
- function emailFinder (email: object) {
+ function emailNotificationFinder (email: object) {
const text: string = email['text']
- return text.includes(' registered ') && text.includes(username)
+ return text.includes(' registered.') && text.includes(username)
}
- await checkNotification(base, notificationChecker, emailFinder, type)
+ await checkNotification(base, notificationChecker, emailNotificationFinder, type)
}
async function checkNewActorFollow (
@@ -291,13 +291,13 @@ async function checkNewActorFollow (
}
}
- function emailFinder (email: object) {
+ function emailNotificationFinder (email: object) {
const text: string = email['text']
- return text.includes('Your ' + followType) && text.includes(followingDisplayName) && text.includes(followerDisplayName)
+ return text.includes(followType) && text.includes(followingDisplayName) && text.includes(followerDisplayName)
}
- await checkNotification(base, notificationChecker, emailFinder, type)
+ await checkNotification(base, notificationChecker, emailNotificationFinder, type)
}
async function checkNewInstanceFollower (base: CheckerBaseParams, followerHost: string, type: CheckerType) {
@@ -320,13 +320,13 @@ async function checkNewInstanceFollower (base: CheckerBaseParams, followerHost:
}
}
- function emailFinder (email: object) {
+ function emailNotificationFinder (email: object) {
const text: string = email['text']
return text.includes('instance has a new follower') && text.includes(followerHost)
}
- await checkNotification(base, notificationChecker, emailFinder, type)
+ await checkNotification(base, notificationChecker, emailNotificationFinder, type)
}
async function checkAutoInstanceFollowing (base: CheckerBaseParams, followerHost: string, followingHost: string, type: CheckerType) {
@@ -351,13 +351,13 @@ async function checkAutoInstanceFollowing (base: CheckerBaseParams, followerHost
}
}
- function emailFinder (email: object) {
+ function emailNotificationFinder (email: object) {
const text: string = email['text']
return text.includes(' automatically followed a new instance') && text.includes(followingHost)
}
- await checkNotification(base, notificationChecker, emailFinder, type)
+ await checkNotification(base, notificationChecker, emailNotificationFinder, type)
}
async function checkCommentMention (
@@ -385,13 +385,13 @@ async function checkCommentMention (
}
}
- function emailFinder (email: object) {
+ function emailNotificationFinder (email: object) {
const text: string = email['text']
return text.includes(' mentioned ') && text.includes(uuid) && text.includes(byAccountDisplayName)
}
- await checkNotification(base, notificationChecker, emailFinder, type)
+ await checkNotification(base, notificationChecker, emailNotificationFinder, type)
}
let lastEmailCount = 0
@@ -416,11 +416,11 @@ async function checkNewCommentOnMyVideo (base: CheckerBaseParams, uuid: string,
const commentUrl = `http://localhost:${base.server.port}/videos/watch/${uuid};threadId=${threadId}`
- function emailFinder (email: object) {
+ function emailNotificationFinder (email: object) {
return email['text'].indexOf(commentUrl) !== -1
}
- await checkNotification(base, notificationChecker, emailFinder, type)
+ await checkNotification(base, notificationChecker, emailNotificationFinder, type)
if (type === 'presence') {
// We cannot detect email duplicates, so check we received another email
@@ -446,12 +446,12 @@ async function checkNewVideoAbuseForModerators (base: CheckerBaseParams, videoUU
}
}
- function emailFinder (email: object) {
+ function emailNotificationFinder (email: object) {
const text = email['text']
return text.indexOf(videoUUID) !== -1 && text.indexOf('abuse') !== -1
}
- await checkNotification(base, notificationChecker, emailFinder, type)
+ await checkNotification(base, notificationChecker, emailNotificationFinder, type)
}
async function checkVideoAutoBlacklistForModerators (base: CheckerBaseParams, videoUUID: string, videoName: string, type: CheckerType) {
@@ -471,12 +471,12 @@ async function checkVideoAutoBlacklistForModerators (base: CheckerBaseParams, vi
}
}
- function emailFinder (email: object) {
+ function emailNotificationFinder (email: object) {
const text = email['text']
return text.indexOf(videoUUID) !== -1 && email['text'].indexOf('video-auto-blacklist/list') !== -1
}
- await checkNotification(base, notificationChecker, emailFinder, type)
+ await checkNotification(base, notificationChecker, emailNotificationFinder, type)
}
async function checkNewBlacklistOnMyVideo (
@@ -498,12 +498,12 @@ async function checkNewBlacklistOnMyVideo (
checkVideo(video, videoName, videoUUID)
}
- function emailFinder (email: object) {
+ function emailNotificationFinder (email: object) {
const text = email['text']
return text.indexOf(videoUUID) !== -1 && text.indexOf(' ' + blacklistType) !== -1
}
- await checkNotification(base, notificationChecker, emailFinder, 'presence')
+ await checkNotification(base, notificationChecker, emailNotificationFinder, 'presence')
}
// ---------------------------------------------------------------------------
diff --git a/shared/models/server/emailer.model.ts b/shared/models/server/emailer.model.ts
index 2d8feda81..069ef0bab 100644
--- a/shared/models/server/emailer.model.ts
+++ b/shared/models/server/emailer.model.ts
@@ -1,8 +1,12 @@
export type SendEmailOptions = {
to: string[]
- subject: string
- text: string
- fromDisplayName?: string
+ template?: string
+ locals?: { [key: string]: any }
+
+ // override defaults
+ subject?: string
+ text?: string
+ from?: string | { name?: string, address: string }
replyTo?: string
}
diff --git a/yarn.lock b/yarn.lock
index 6bda65a91..7add25761 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -65,16 +65,57 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
+"@babel/runtime@^7.6.3":
+ version "7.9.6"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.6.tgz#a9102eb5cadedf3f31d08a9ecf294af7827ea29f"
+ integrity sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==
+ dependencies:
+ regenerator-runtime "^0.13.4"
+
+"@hapi/boom@^9.0.0":
+ version "9.1.0"
+ resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.0.tgz#0d9517657a56ff1e0b42d0aca9da1b37706fec56"
+ integrity sha512-4nZmpp4tXbm162LaZT45P7F7sgiem8dwAh2vHWT6XX24dozNjGMg6BvKCRvtCUcmcXqeMIUqWN8Rc5X8yKuROQ==
+ dependencies:
+ "@hapi/hoek" "9.x.x"
+
+"@hapi/hoek@9.x.x":
+ version "9.0.4"
+ resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.0.4.tgz#e80ad4e8e8d2adc6c77d985f698447e8628b6010"
+ integrity sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw==
+
"@jsdevtools/ono@^7.1.0":
version "7.1.1"
resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.1.tgz#36034f9cb0fb456858c137a3f3e6d6db67ab5cc5"
integrity sha512-pu5fxkbLQWzRbBgfFbZfHXz0KlYojOfVdUhcNfy9lef8ZhBt0pckGr8g7zv4vPX4Out5vBNvqd/az4UaVWzZ9A==
+"@ladjs/i18n@^3.0.4":
+ version "3.0.5"
+ resolved "https://registry.yarnpkg.com/@ladjs/i18n/-/i18n-3.0.5.tgz#2083b987db85b7671d934734003fd41e753c3892"
+ integrity sha512-iSHpzLTPE+lEgPiECUcnVHDidZFnyahpNj6azsQ316mQU2owGH2YXky0zjYsA4p8aSnzGtGYsgfPNfLZASIcSQ==
+ dependencies:
+ "@hapi/boom" "^9.0.0"
+ boolean "3.0.0"
+ country-language "^0.1.7"
+ debug "^4.1.1"
+ i18n "^0.9.1"
+ i18n-locales "^0.0.4"
+ lodash "^4.17.15"
+ moment "^2.24.0"
+ multimatch "^4.0.0"
+ qs "^6.9.1"
+ titleize "^2.1.0"
+
"@openapitools/openapi-generator-cli@^1.0.12-4.3.0":
version "1.0.12-4.3.0"
resolved "https://registry.yarnpkg.com/@openapitools/openapi-generator-cli/-/openapi-generator-cli-1.0.12-4.3.0.tgz#845f0bfd47a73bdaa188667c3085d721e0d91785"
integrity sha512-p6y0ur69/vEslpARrcWg3geujOAjxoQIlIamZGm1cWsu4y4RrEdrolueWA1Lxww2pUzgxvb9PwD6hHFZNNfgrw==
+"@sindresorhus/is@^2.1.0":
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-2.1.1.tgz#ceff6a28a5b4867c2dd4a1ba513de278ccbe8bb1"
+ integrity sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==
+
"@types/apicache@^1.2.0":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@types/apicache/-/apicache-1.2.2.tgz#b820659b1d95e66ec0e71dcd0317e9d30f0c154b"
@@ -92,6 +133,18 @@
resolved "https://registry.yarnpkg.com/@types/async/-/async-3.2.0.tgz#2bf5c62ca7f50efa77b74c971f1401a6db9ff938"
integrity sha512-7dhGj2u7hS+Y/NPxFDaTL/kbTvVjOKvZmD+GZp0jGGOLvnakomncrqSReX+xPAGGZuCUSUsXXy9I9pEpSwxpKA==
+"@types/babel-types@*", "@types/babel-types@^7.0.0":
+ version "7.0.7"
+ resolved "https://registry.yarnpkg.com/@types/babel-types/-/babel-types-7.0.7.tgz#667eb1640e8039436028055737d2b9986ee336e3"
+ integrity sha512-dBtBbrc+qTHy1WdfHYjBwRln4+LWqASWakLHsWHR2NWHIFkv4W3O070IGoGLEBrJBvct3r0L1BUPuvURi7kYUQ==
+
+"@types/babylon@^6.16.2":
+ version "6.16.5"
+ resolved "https://registry.yarnpkg.com/@types/babylon/-/babylon-6.16.5.tgz#1c5641db69eb8cdf378edd25b4be7754beeb48b4"
+ integrity sha512-xH2e58elpj1X4ynnKp9qSnWlsRTIs6n3tgLGNfwAGHwePw0mulHQllV34n0T25uYSu1k0hRKkWXF890B1yS47w==
+ dependencies:
+ "@types/babel-types" "*"
+
"@types/bcrypt@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/bcrypt/-/bcrypt-3.0.0.tgz#851489a9065a067cb7f3c9cbe4ce9bed8bba0876"
@@ -277,6 +330,11 @@
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d"
integrity sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==
+"@types/minimatch@^3.0.3":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
+ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
+
"@types/mkdirp@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/mkdirp/-/mkdirp-1.0.0.tgz#16ce0eabe4a9a3afe64557ad0ee6886ec3d32927"
@@ -516,11 +574,28 @@ accepts@~1.3.4, accepts@~1.3.7:
mime-types "~2.1.24"
negotiator "0.6.2"
+acorn-globals@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf"
+ integrity sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=
+ dependencies:
+ acorn "^4.0.4"
+
acorn-jsx@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe"
integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==
+acorn@^3.1.0:
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
+ integrity sha1-ReN/s56No/JbruP/U2niu18iAXo=
+
+acorn@^4.0.4, acorn@~4.0.2:
+ version "4.0.13"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787"
+ integrity sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=
+
acorn@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf"
@@ -551,6 +626,15 @@ ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
+align-text@^0.1.1, align-text@^0.1.3:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
+ integrity sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=
+ dependencies:
+ kind-of "^3.0.2"
+ longest "^1.0.1"
+ repeat-string "^1.5.2"
+
ansi-align@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f"
@@ -653,6 +737,11 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
+array-differ@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b"
+ integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==
+
array-flatten@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
@@ -667,6 +756,11 @@ array-includes@^3.0.3:
es-abstract "^1.17.0"
is-string "^1.0.5"
+array-union@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
+ integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
+
array.prototype.flat@^1.2.1:
version "1.2.3"
resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b"
@@ -680,6 +774,16 @@ arraybuffer.slice@~0.0.7:
resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675"
integrity sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==
+arrify@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa"
+ integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==
+
+asap@~2.0.3:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
+ integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
+
asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
@@ -761,6 +865,29 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e"
integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==
+babel-runtime@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
+ integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4=
+ dependencies:
+ core-js "^2.4.0"
+ regenerator-runtime "^0.11.0"
+
+babel-types@^6.26.0:
+ version "6.26.0"
+ resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497"
+ integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=
+ dependencies:
+ babel-runtime "^6.26.0"
+ esutils "^2.0.2"
+ lodash "^4.17.4"
+ to-fast-properties "^1.0.3"
+
+babylon@^6.18.0:
+ version "6.18.0"
+ resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3"
+ integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==
+
backo2@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947"
@@ -946,7 +1073,7 @@ bluebird@^2.10.0:
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
integrity sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=
-bluebird@^3.0.5, bluebird@^3.5.0, bluebird@^3.5.1:
+bluebird@^3.0.5, bluebird@^3.1.1, bluebird@^3.5.0, bluebird@^3.5.1:
version "3.7.2"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
@@ -972,6 +1099,16 @@ body-parser@1.19.0, body-parser@^1.12.4:
raw-body "2.4.0"
type-is "~1.6.17"
+boolbase@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
+ integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
+
+boolean@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.0.0.tgz#fab78d5907dbae6216ab46d32733bb7b76b99e76"
+ integrity sha512-OElxJ1lUSinuoUnkpOgLmxp0DC4ytEhODEL6QJU0NpxE/mI4rUSh8h1P1Wkvfi3xQEBcxXR2gBIPNYNuaFcAbQ==
+
bowser@2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.9.0.tgz#3bed854233b419b9a7422d9ee3e85504373821c9"
@@ -1102,6 +1239,11 @@ callsites@^3.0.0:
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
+camelcase@^1.0.2:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39"
+ integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=
+
camelcase@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd"
@@ -1132,6 +1274,14 @@ caseless@~0.12.0:
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
+center-align@^0.1.1:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad"
+ integrity sha1-qg0yYptu6XIgBBHL1EYckHvCt60=
+ dependencies:
+ align-text "^0.1.3"
+ lazy-cache "^1.0.3"
+
chai-json-schema@^1.5.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/chai-json-schema/-/chai-json-schema-1.5.1.tgz#d9ae4c8f8c6e24ff4d402ceddfaa865d1ca107f4"
@@ -1185,6 +1335,13 @@ chalk@^3.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
+character-parser@^2.1.1:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0"
+ integrity sha1-x84o821LzZdE5f/CxfzeHHMmH8A=
+ dependencies:
+ is-regex "^1.0.3"
+
chardet@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
@@ -1205,6 +1362,28 @@ check-error@^1.0.2:
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=
+cheerio@^0.22.0:
+ version "0.22.0"
+ resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e"
+ integrity sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=
+ dependencies:
+ css-select "~1.2.0"
+ dom-serializer "~0.1.0"
+ entities "~1.1.1"
+ htmlparser2 "^3.9.1"
+ lodash.assignin "^4.0.9"
+ lodash.bind "^4.1.4"
+ lodash.defaults "^4.0.1"
+ lodash.filter "^4.4.0"
+ lodash.flatten "^4.2.0"
+ lodash.foreach "^4.3.0"
+ lodash.map "^4.4.0"
+ lodash.merge "^4.4.0"
+ lodash.pick "^4.2.1"
+ lodash.reduce "^4.4.0"
+ lodash.reject "^4.4.0"
+ lodash.some "^4.4.0"
+
chokidar@3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6"
@@ -1287,6 +1466,13 @@ circular-json@^0.5.9:
resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.5.9.tgz#932763ae88f4f7dead7a0d09c8a51a4743a53b1d"
integrity sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==
+clean-css@^4.1.11:
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"
+ integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==
+ dependencies:
+ source-map "~0.6.0"
+
cli-boxes@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143"
@@ -1304,6 +1490,15 @@ cli-width@^2.0.0:
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=
+cliui@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
+ integrity sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=
+ dependencies:
+ center-align "^0.1.1"
+ right-align "^0.1.1"
+ wordwrap "0.0.2"
+
cliui@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5"
@@ -1431,7 +1626,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
dependencies:
delayed-stream "~1.0.0"
-commander@^2.20.0, commander@^2.7.1:
+commander@^2.15.1, commander@^2.20.0, commander@^2.7.1:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@@ -1522,6 +1717,23 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0:
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
+consolidate@^0.15.1:
+ version "0.15.1"
+ resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.15.1.tgz#21ab043235c71a07d45d9aad98593b0dba56bab7"
+ integrity sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==
+ dependencies:
+ bluebird "^3.1.1"
+
+constantinople@^3.0.1, constantinople@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-3.1.2.tgz#d45ed724f57d3d10500017a7d3a889c1381ae647"
+ integrity sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw==
+ dependencies:
+ "@types/babel-types" "^7.0.0"
+ "@types/babylon" "^6.16.2"
+ babel-types "^6.26.0"
+ babylon "^6.18.0"
+
contains-path@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a"
@@ -1572,6 +1784,11 @@ cookiejar@^2.1.0:
resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c"
integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==
+core-js@^2.4.0:
+ version "2.6.11"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c"
+ integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==
+
core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@@ -1585,6 +1802,14 @@ cors@^2.8.1, cors@^2.8.5:
object-assign "^4"
vary "^1"
+country-language@^0.1.7:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/country-language/-/country-language-0.1.7.tgz#7870f4ba125db9a6071f19737bd9ef9343ae35db"
+ integrity sha1-eHD0uhJduaYHHxlze9nvk0OuNds=
+ dependencies:
+ underscore "~1.7.0"
+ underscore.deep "~0.5.1"
+
create-error-class@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6"
@@ -1657,6 +1882,21 @@ crypto-random-string@^1.0.0:
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"
integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=
+css-select@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
+ integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=
+ dependencies:
+ boolbase "~1.0.0"
+ css-what "2.1"
+ domutils "1.5.1"
+ nth-check "~1.0.1"
+
+css-what@2.1:
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2"
+ integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==
+
cycle@1.0.x:
version "1.0.3"
resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2"
@@ -1682,11 +1922,31 @@ dasherize@2.0.0:
resolved "https://registry.yarnpkg.com/dasherize/-/dasherize-2.0.0.tgz#6d809c9cd0cf7bb8952d80fc84fa13d47ddb1308"
integrity sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg=
+datauri@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/datauri/-/datauri-2.0.0.tgz#ff0ee23729935a6bcc81f301621bed3e692bf3c7"
+ integrity sha512-zS2HSf9pI5XPlNZgIqJg/wCJpecgU/HA6E/uv2EfaWnW1EiTGLfy/EexTIsC9c99yoCOTXlqeeWk4FkCSuO3/g==
+ dependencies:
+ image-size "^0.7.3"
+ mimer "^1.0.0"
+
date-fns@^2.0.1:
version "2.11.1"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.11.1.tgz#197b8be1bbf5c5e6fe8bea817f0fe111820e7a12"
integrity sha512-3RdUoinZ43URd2MJcquzBbDQo+J87cSzB8NkXdZiN5ia1UNyep0oCyitfiL88+R7clGTeq/RniXAc16gWyAu1w==
+dayjs@^1.8.16:
+ version "1.8.26"
+ resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.26.tgz#c6d62ccdf058ca72a8d14bb93a23501058db9f1e"
+ integrity sha512-KqtAuIfdNfZR5sJY1Dixr2Is4ZvcCqhb0dZpCOt5dGEFiMzoIbjkTSzUb4QKTCsP+WNpGwUjAFIZrnZvUxxkhw==
+
+debug@*, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0, debug@~4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
+ integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
+ dependencies:
+ ms "^2.1.1"
+
debug@2.6.9, debug@^2.2.0, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@@ -1701,13 +1961,6 @@ debug@3.2.6, debug@^3.1.0, debug@^3.2.6:
dependencies:
ms "^2.1.1"
-debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0, debug@~4.1.1:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
- integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
- dependencies:
- ms "^2.1.1"
-
debug@~3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
@@ -1720,7 +1973,7 @@ debuglog@^1.0.0:
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=
-decamelize@^1.2.0:
+decamelize@^1.0.0, decamelize@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
@@ -1855,6 +2108,76 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
+doctypes@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9"
+ integrity sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk=
+
+dom-serializer@0, dom-serializer@^0.2.1:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
+ integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==
+ dependencies:
+ domelementtype "^2.0.1"
+ entities "^2.0.0"
+
+dom-serializer@~0.1.0:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0"
+ integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==
+ dependencies:
+ domelementtype "^1.3.0"
+ entities "^1.1.1"
+
+domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
+ integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
+
+domelementtype@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d"
+ integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==
+
+domhandler@^2.3.0:
+ version "2.4.2"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
+ integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==
+ dependencies:
+ domelementtype "1"
+
+domhandler@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-3.0.0.tgz#51cd13efca31da95bbb0c5bee3a48300e333b3e9"
+ integrity sha512-eKLdI5v9m67kbXQbJSNn1zjh0SDzvzWVWtX+qEI3eMjZw8daH9k8rlj1FZY9memPwjiskQFbe7vHVVJIAqoEhw==
+ dependencies:
+ domelementtype "^2.0.1"
+
+domutils@1.5.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
+ integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=
+ dependencies:
+ dom-serializer "0"
+ domelementtype "1"
+
+domutils@^1.5.1:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
+ integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==
+ dependencies:
+ dom-serializer "0"
+ domelementtype "1"
+
+domutils@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.0.0.tgz#15b8278e37bfa8468d157478c58c367718133c08"
+ integrity sha512-n5SelJ1axbO636c2yUtOGia/IcJtVtlhQbFiVDBZHKV5ReJO1ViX7sFEemtuyoAnBxk5meNSYgA8V4s0271efg==
+ dependencies:
+ dom-serializer "^0.2.1"
+ domelementtype "^2.0.1"
+ domhandler "^3.0.0"
+
dont-sniff-mimetype@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/dont-sniff-mimetype/-/dont-sniff-mimetype-1.1.0.tgz#c7d0427f8bcb095762751252af59d148b0a623b2"
@@ -1900,6 +2223,23 @@ ee-first@1.1.1:
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
+email-templates@^7.0.4:
+ version "7.0.4"
+ resolved "https://registry.yarnpkg.com/email-templates/-/email-templates-7.0.4.tgz#1e1e1b360e4a91c7b9cf536716381615ba6cf1ae"
+ integrity sha512-+s8Eav1XCF6IveHXK4lWxXdMm3XCk9eDIMX0p9simqIPW1gzR4haMpNhID2pZBQzDyY0yylW74IMB9+3Ntwjmw==
+ dependencies:
+ "@ladjs/i18n" "^3.0.4"
+ "@sindresorhus/is" "^2.1.0"
+ consolidate "^0.15.1"
+ debug "^4.1.1"
+ get-paths "^0.0.7"
+ html-to-text "^5.1.1"
+ juice "^6.0.0"
+ lodash "^4.17.15"
+ nodemailer "^6.4.2"
+ pify "^5.0.0"
+ preview-email "^2.0.1"
+
emoji-regex@^7.0.1:
version "7.0.3"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
@@ -1922,6 +2262,11 @@ encodeurl@~1.0.2:
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=
+encoding-japanese@1.0.30:
+ version "1.0.30"
+ resolved "https://registry.yarnpkg.com/encoding-japanese/-/encoding-japanese-1.0.30.tgz#537c4d62881767925d601acb4c79fb14db81703a"
+ integrity sha512-bd/DFLAoJetvv7ar/KIpE3CNO8wEuyrt9Xuw6nSMiZ+Vrz/Q21BPsMHvARL2Wz6IKHKXgb+DWZqtRg1vql9cBg==
+
end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
@@ -2009,6 +2354,16 @@ engine.io@~3.4.0:
engine.io-parser "~2.2.0"
ws "^7.1.2"
+entities@^1.1.1, entities@~1.1.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
+ integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
+
+entities@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4"
+ integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==
+
env-variable@0.0.x:
version "0.0.6"
resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.6.tgz#74ab20b3786c545b62b4a4813ab8cf22726c9808"
@@ -2701,6 +3056,13 @@ get-func-name@^2.0.0:
resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=
+get-paths@^0.0.7:
+ version "0.0.7"
+ resolved "https://registry.yarnpkg.com/get-paths/-/get-paths-0.0.7.tgz#15331086752077cf130166ccd233a1cdbeefcf38"
+ integrity sha512-0wdJt7C1XKQxuCgouqd+ZvLJ56FQixKoki9MrFaO4EriqzXOiH9gbukaDE1ou08S8Ns3/yDzoBAISNPqj6e6tA==
+ dependencies:
+ pify "^4.0.1"
+
get-port@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193"
@@ -2878,7 +3240,7 @@ hashish@~0.0.4:
dependencies:
traverse ">=0.2.4"
-he@1.2.0:
+he@1.2.0, he@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
@@ -2948,6 +3310,38 @@ hsts@2.2.0:
dependencies:
depd "2.0.0"
+html-to-text@5.1.1, html-to-text@^5.1.1:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/html-to-text/-/html-to-text-5.1.1.tgz#2d89db7bf34bc7bcb7d546b1b228991a16926e87"
+ integrity sha512-Bci6bD/JIfZSvG4s0gW/9mMKwBRoe/1RWLxUME/d6WUSZCdY7T60bssf/jFf7EYXRyqU4P5xdClVqiYU0/ypdA==
+ dependencies:
+ he "^1.2.0"
+ htmlparser2 "^3.10.1"
+ lodash "^4.17.11"
+ minimist "^1.2.0"
+
+htmlparser2@^3.10.1, htmlparser2@^3.9.1:
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
+ integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==
+ dependencies:
+ domelementtype "^1.3.1"
+ domhandler "^2.3.0"
+ domutils "^1.5.1"
+ entities "^1.1.1"
+ inherits "^2.0.1"
+ readable-stream "^3.1.1"
+
+htmlparser2@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-4.1.0.tgz#9a4ef161f2e4625ebf7dfbe6c0a2f52d18a59e78"
+ integrity sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==
+ dependencies:
+ domelementtype "^2.0.1"
+ domhandler "^3.0.0"
+ domutils "^2.0.0"
+ entities "^2.0.0"
+
http-errors@1.7.2:
version "1.7.2"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
@@ -2997,6 +3391,25 @@ human-signals@^1.1.1:
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3"
integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==
+i18n-locales@^0.0.4:
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/i18n-locales/-/i18n-locales-0.0.4.tgz#95d6505f6563f870f68860c23d35f82bd805cbf5"
+ integrity sha512-aP6VjhoBwSC8uZUehHWSszqdeWiheNXp0+oLPcZY4QAktsqcouHNYQee2NQFM4KNcCTKHHbfXrRUuOxjxF2jYw==
+ dependencies:
+ country-language "^0.1.7"
+
+i18n@^0.9.1:
+ version "0.9.1"
+ resolved "https://registry.yarnpkg.com/i18n/-/i18n-0.9.1.tgz#a9dda09e582286c81a584374ac9f2aaef7ec37fb"
+ integrity sha512-ERo9WloOP2inRsJzAlzn4JDm3jvX7FW1+KB/JGXTzUVzi9Bsf4LNLXUQTMgM/aze4LNW/kvmxQX6bzg5UzqMJw==
+ dependencies:
+ debug "*"
+ make-plural "^6.2.1"
+ math-interval-parser "^2.0.1"
+ messageformat "^2.3.0"
+ mustache "^4.0.1"
+ sprintf-js "^1.1.2"
+
i@0.3.x:
version "0.3.6"
resolved "https://registry.yarnpkg.com/i/-/i-0.3.6.tgz#d96c92732076f072711b6b10fd7d4f65ad8ee23d"
@@ -3009,6 +3422,13 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.24:
dependencies:
safer-buffer ">= 2.1.2 < 3"
+iconv-lite@0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.5.0.tgz#59cdde0a2a297cc2aeb0c6445a195ee89f127550"
+ integrity sha512-NnEhI9hIEKHOzJ4f697DMz9IQEXr/MMJ5w64vN2/4Ai+wRnvV7SBrL0KLoRlwaKVghOc7LQ5YkPLuX146b6Ydw==
+ dependencies:
+ safer-buffer ">= 2.1.2 < 3"
+
ieee754@^1.1.4:
version "1.1.13"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
@@ -3041,6 +3461,11 @@ ignore@^5.1.1:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf"
integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==
+image-size@^0.7.3:
+ version "0.7.5"
+ resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.7.5.tgz#269f357cf5797cb44683dfa99790e54c705ead04"
+ integrity sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==
+
immediate-chunk-store@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/immediate-chunk-store/-/immediate-chunk-store-2.1.0.tgz#3dbd3b5cc77182526188a8da47e38488a6627336"
@@ -3192,7 +3617,7 @@ is-bluebird@^1.0.2:
resolved "https://registry.yarnpkg.com/is-bluebird/-/is-bluebird-1.0.2.tgz#096439060f4aa411abee19143a84d6a55346d6e2"
integrity sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=
-is-buffer@~1.1.1:
+is-buffer@^1.1.5, is-buffer@~1.1.1:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
@@ -3226,6 +3651,14 @@ is-date-object@^1.0.1:
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e"
integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==
+is-expression@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-3.0.0.tgz#39acaa6be7fd1f3471dc42c7416e61c24317ac9f"
+ integrity sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=
+ dependencies:
+ acorn "~4.0.2"
+ object-assign "^4.0.1"
+
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
@@ -3302,6 +3735,11 @@ is-path-inside@^1.0.0:
dependencies:
path-is-inside "^1.0.1"
+is-promise@^2.0.0:
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1"
+ integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==
+
is-promise@^2.1, is-promise@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
@@ -3312,7 +3750,7 @@ is-redirect@^1.0.0:
resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24"
integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=
-is-regex@^1.0.5:
+is-regex@^1.0.3, is-regex@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae"
integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==
@@ -3386,6 +3824,11 @@ isstream@0.1.x, isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
+js-stringify@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db"
+ integrity sha1-Fzb939lyTyijaCrcYjCufk6Weds=
+
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -3480,6 +3923,27 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.10.0"
+jstransformer@1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3"
+ integrity sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=
+ dependencies:
+ is-promise "^2.0.0"
+ promise "^7.0.1"
+
+juice@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/juice/-/juice-6.0.0.tgz#cd8f8fe5210ef129d186fe2c41c0ec169f7b07b6"
+ integrity sha512-5T3JPgXYiw6A6axsb9E09Gzq46WbfJeDirY6nMrqY55iAdqEoPDxSr1GpXqYfoyndx4ujpBPXGLzBRzbiqOOaw==
+ dependencies:
+ cheerio "^0.22.0"
+ commander "^2.15.1"
+ cross-spawn "^6.0.5"
+ deep-extend "^0.6.0"
+ mensch "^0.3.4"
+ slick "^1.12.2"
+ web-resource-inliner "^4.3.3"
+
junk@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1"
@@ -3511,6 +3975,13 @@ k-rpc@^5.0.0:
k-rpc-socket "^1.7.2"
randombytes "^2.0.5"
+kind-of@^3.0.2:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
+ integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=
+ dependencies:
+ is-buffer "^1.1.5"
+
kuler@1.0.x:
version "1.0.1"
resolved "https://registry.yarnpkg.com/kuler/-/kuler-1.0.1.tgz#ef7c784f36c9fb6e16dd3150d152677b2b0228a6"
@@ -3530,6 +4001,11 @@ latest-version@^3.0.0:
dependencies:
package-json "^4.0.0"
+lazy-cache@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e"
+ integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4=
+
levn@^0.3.0, levn@~0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
@@ -3538,6 +4014,26 @@ levn@^0.3.0, levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"
+libbase64@1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/libbase64/-/libbase64-1.2.1.tgz#fb93bf4cb6d730f29b92155b6408d1bd2176a8c8"
+ integrity sha512-l+nePcPbIG1fNlqMzrh68MLkX/gTxk/+vdvAb388Ssi7UuUN31MI44w4Yf33mM3Cm4xDfw48mdf3rkdHszLNew==
+
+libmime@4.2.1:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/libmime/-/libmime-4.2.1.tgz#d21aa5db88b131af18bf5a3caa1013da2c21a9dd"
+ integrity sha512-09y7zjSc5im1aNsq815zgo4/G3DnIzym3aDOHsGq4Ee5vrX4PdgQRybAsztz9Rv0NhO+J5C0llEUloa3sUmjmA==
+ dependencies:
+ encoding-japanese "1.0.30"
+ iconv-lite "0.5.0"
+ libbase64 "1.2.1"
+ libqp "1.1.0"
+
+libqp@1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/libqp/-/libqp-1.1.0.tgz#f5e6e06ad74b794fb5b5b66988bf728ef1dedbe8"
+ integrity sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=
+
libxmljs@0.19.7:
version "0.19.7"
resolved "https://registry.yarnpkg.com/libxmljs/-/libxmljs-0.19.7.tgz#96c2151b0b73f33dd29917edec82902587004e5a"
@@ -3547,6 +4043,13 @@ libxmljs@0.19.7:
nan "~2.14.0"
node-pre-gyp "~0.11.0"
+linkify-it@2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf"
+ integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==
+ dependencies:
+ uc.micro "^1.0.1"
+
load-ip-set@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/load-ip-set/-/load-ip-set-2.1.0.tgz#2d50b737cae41de4e413d213991d4083a3e1784b"
@@ -3591,16 +4094,36 @@ locate-path@^5.0.0:
dependencies:
p-locate "^4.1.0"
-lodash.defaults@^4.2.0:
+lodash.assignin@^4.0.9:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2"
+ integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI=
+
+lodash.bind@^4.1.4:
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35"
+ integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=
+
+lodash.defaults@^4.0.1, lodash.defaults@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=
-lodash.flatten@^4.4.0:
+lodash.filter@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace"
+ integrity sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=
+
+lodash.flatten@^4.2.0, lodash.flatten@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
+lodash.foreach@^4.3.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53"
+ integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=
+
lodash.get@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
@@ -3611,7 +4134,42 @@ lodash.isequal@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
-lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15:
+lodash.map@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3"
+ integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=
+
+lodash.merge@^4.4.0:
+ version "4.6.2"
+ resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
+ integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
+
+lodash.pick@^4.2.1:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
+ integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=
+
+lodash.reduce@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b"
+ integrity sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=
+
+lodash.reject@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415"
+ integrity sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=
+
+lodash.some@^4.4.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d"
+ integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=
+
+lodash.unescape@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c"
+ integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=
+
+lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
@@ -3634,6 +4192,11 @@ logform@^2.1.1:
ms "^2.1.1"
triple-beam "^1.3.0"
+longest@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
+ integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=
+
lowercase-keys@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
@@ -3703,6 +4266,30 @@ mailparser-mit@^1.0.0:
mime "^1.6.0"
uue "^3.1.0"
+mailparser@^2.7.7:
+ version "2.7.7"
+ resolved "https://registry.yarnpkg.com/mailparser/-/mailparser-2.7.7.tgz#7d3fe616797427629c59992a34d84820d550676b"
+ integrity sha512-FcVkXYm+zIg59HNPINGQw99eMTvcAkmQZHmabF8aSeMZ6/vWkx0HdT6FpXApelfe5IKRk6nWEg+YAuuXZl9+Fg==
+ dependencies:
+ encoding-japanese "1.0.30"
+ he "1.2.0"
+ html-to-text "5.1.1"
+ iconv-lite "0.5.0"
+ libmime "4.2.1"
+ linkify-it "2.2.0"
+ mailsplit "4.6.2"
+ nodemailer "6.4.0"
+ tlds "1.207.0"
+
+mailsplit@4.6.2:
+ version "4.6.2"
+ resolved "https://registry.yarnpkg.com/mailsplit/-/mailsplit-4.6.2.tgz#ce622cea460406035ff9f7d493ed00ea52a27aaa"
+ integrity sha512-7Bw2R0QfORXexGGQCEK64EeShHacUNyU5kV5F5sj4jPQB3ITe2v9KRqxD40wpuue6W/sBJlSNBZ0AypIeTGQMQ==
+ dependencies:
+ libbase64 "1.2.1"
+ libmime "4.2.1"
+ libqp "1.1.0"
+
make-dir@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
@@ -3715,6 +4302,18 @@ make-error@^1.1.1:
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
+make-plural@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/make-plural/-/make-plural-4.3.0.tgz#f23de08efdb0cac2e0c9ba9f315b0dff6b4c2735"
+ integrity sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==
+ optionalDependencies:
+ minimist "^1.2.0"
+
+make-plural@^6.2.1:
+ version "6.2.1"
+ resolved "https://registry.yarnpkg.com/make-plural/-/make-plural-6.2.1.tgz#2790af1d05fb2fc35a111ce759ffdb0aca1339a3"
+ integrity sha512-AmkruwJ9EjvyTv6AM8MBMK3TAeOJvhgTv5YQXzF0EP2qawhpvMjDpHvsdOIIT0Vn+BB0+IogmYZ1z+Ulm/m0Fg==
+
marked-man@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/marked-man/-/marked-man-0.7.0.tgz#220ba01d275d16f1a98e4e7fc3c5eac0630c68e4"
@@ -3725,6 +4324,11 @@ marked@^0.8.0:
resolved "https://registry.yarnpkg.com/marked/-/marked-0.8.2.tgz#4faad28d26ede351a7a1aaa5fec67915c869e355"
integrity sha512-EGwzEeCcLniFX51DhTpmTom+dSA/MG/OBUDjnWtHbEnjAH180VzUeAw+oE4+Zv+CoYBWyRlYOTR0N8SO9R1PVw==
+math-interval-parser@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/math-interval-parser/-/math-interval-parser-2.0.1.tgz#e22cd6d15a0a7f4c03aec560db76513da615bed4"
+ integrity sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==
+
md5@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9"
@@ -3767,6 +4371,11 @@ memory-chunk-store@^1.2.0:
resolved "https://registry.yarnpkg.com/memory-chunk-store/-/memory-chunk-store-1.3.0.tgz#ae99e7e3b58b52db43d49d94722930d39459d0c4"
integrity sha512-6LsOpHKKhxYrLhHmOJdBCUtSO7op5rUs1pag0fhjHo0QiXRyna0bwYf4EmQuL7InUeF2J7dUMPr6VMogRyf9NA==
+mensch@^0.3.4:
+ version "0.3.4"
+ resolved "https://registry.yarnpkg.com/mensch/-/mensch-0.3.4.tgz#770f91b46cb16ea5b204ee735768c3f0c491fecd"
+ integrity sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==
+
merge-descriptors@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
@@ -3777,6 +4386,25 @@ merge-stream@^2.0.0:
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
+messageformat-formatters@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz#0492c1402a48775f751c9b17c0354e92be012b08"
+ integrity sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg==
+
+messageformat-parser@^4.1.2:
+ version "4.1.3"
+ resolved "https://registry.yarnpkg.com/messageformat-parser/-/messageformat-parser-4.1.3.tgz#b824787f57fcda7d50769f5b63e8d4fda68f5b9e"
+ integrity sha512-2fU3XDCanRqeOCkn7R5zW5VQHWf+T3hH65SzuqRvjatBK7r4uyFa5mEX+k6F9Bd04LVM5G4/BHBTUJsOdW7uyg==
+
+messageformat@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/messageformat/-/messageformat-2.3.0.tgz#de263c49029d5eae65d7ee25e0754f57f425ad91"
+ integrity sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==
+ dependencies:
+ make-plural "^4.3.0"
+ messageformat-formatters "^2.0.1"
+ messageformat-parser "^4.1.2"
+
methods@^1.1.1, methods@^1.1.2, methods@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
@@ -3804,6 +4432,11 @@ mime@^2.4.0:
resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5"
integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==
+mimer@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/mimer/-/mimer-1.1.0.tgz#2cb67f7093998e772a0e62c090f77daa1b8a2dbe"
+ integrity sha512-y9dVfy2uiycQvDNiAYW6zp49ZhFlXDMr5wfdOiMbdzGM/0N5LNR6HTUn3un+WUQcM0koaw8FMTG1bt5EnHJdvQ==
+
mimic-fn@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
@@ -3988,6 +4621,17 @@ multer@^1.1.0:
type-is "^1.6.4"
xtend "^4.0.0"
+multimatch@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-4.0.0.tgz#8c3c0f6e3e8449ada0af3dd29efb491a375191b3"
+ integrity sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==
+ dependencies:
+ "@types/minimatch" "^3.0.3"
+ array-differ "^3.0.0"
+ array-union "^2.1.0"
+ arrify "^2.0.1"
+ minimatch "^3.0.4"
+
multistream@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/multistream/-/multistream-4.0.0.tgz#c771b6d17d169138b6abcb15f0061170e3c09cea"
@@ -3995,6 +4639,11 @@ multistream@^4.0.0:
dependencies:
readable-stream "^3.4.0"
+mustache@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.0.1.tgz#d99beb031701ad433338e7ea65e0489416c854a2"
+ integrity sha512-yL5VE97+OXn4+Er3THSmTdCFCtx5hHWzrolvH+JObZnUYwuaG7XV+Ch4fR2cIrcYI0tFHxS7iyFYl14bW8y2sA==
+
mute-stream@0.0.8, mute-stream@~0.0.4:
version "0.0.8"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
@@ -4131,12 +4780,17 @@ nodemailer@5.0.0:
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-5.0.0.tgz#bcb409eca613114e85de42646d0ce7f1fa70b716"
integrity sha512-XI4PI5L7GYcJyHkPcHlvPyRrYohNYBNRNbt1tU8PXNU3E1ADJC84a13V0vbL9AM431OP+ETacaGXAF8fGn1JvA==
+nodemailer@6.4.0:
+ version "6.4.0"
+ resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.4.0.tgz#91482ebc09d39156d933eb9e6159642cd27bf02c"
+ integrity sha512-UBqPOfQGD1cM3HnjhuQe+0u3DWx47WWK7lBjG5UtPnGOysr7oDK5lNCzcjK6zzeBSdTk4m1tGx1xNbWFZQmMNA==
+
nodemailer@^3.1.1:
version "3.1.8"
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-3.1.8.tgz#febfaccb4bd273678473a309c6cb4b4a2f3c48e3"
integrity sha1-/r+sy0vSc2eEc6MJxstLSi88SOM=
-nodemailer@^6.0.0:
+nodemailer@^6.0.0, nodemailer@^6.3.1, nodemailer@^6.4.2:
version "6.4.6"
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.4.6.tgz#d37f504f6560b36616f646a606894fe18819107f"
integrity sha512-/kJ+FYVEm2HuUlw87hjSqTss+GU35D4giOpdSfGp7DO+5h6RlJj7R94YaYHOkoxu1CSaM0d3WRBtCzwXrY6MKA==
@@ -4237,6 +4891,13 @@ npmlog@^4.0.1, npmlog@^4.0.2, npmlog@^4.1.2:
gauge "~2.7.3"
set-blocking "~2.0.0"
+nth-check@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c"
+ integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==
+ dependencies:
+ boolbase "~1.0.0"
+
number-is-nan@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
@@ -4259,7 +4920,7 @@ oauth2-server@3.0.0, oauth2-server@3.1.0-beta.1, oauth2-server@^3.1.0-beta.1:
statuses "^1.5.0"
type-is "^1.6.16"
-object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1:
+object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
@@ -4348,6 +5009,13 @@ onetime@^5.1.0:
dependencies:
mimic-fn "^2.1.0"
+open@^6.4.0:
+ version "6.4.0"
+ resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9"
+ integrity sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==
+ dependencies:
+ is-wsl "^1.1.0"
+
openapi-types@^1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/openapi-types/-/openapi-types-1.3.5.tgz#6718cfbc857fe6c6f1471f65b32bdebb9c10ce40"
@@ -4695,6 +5363,16 @@ pify@^3.0.0:
resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=
+pify@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
+ integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
+
+pify@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f"
+ integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==
+
pkg-dir@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
@@ -4765,6 +5443,21 @@ prepend-http@^1.0.1:
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=
+preview-email@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/preview-email/-/preview-email-2.0.1.tgz#da237848702778b5a2dca38ed5963aa854c1ac3e"
+ integrity sha512-KXmv0oKonf9slHXjZ1O+QvGsq7IKJs3IINB4b8XWZ3IwONyGiGqpXthCrTZuDzhLG1kPn6FKOOikdm21bturcQ==
+ dependencies:
+ "@babel/runtime" "^7.6.3"
+ dayjs "^1.8.16"
+ debug "^4.1.1"
+ mailparser "^2.7.7"
+ nodemailer "^6.3.1"
+ open "^6.4.0"
+ pify "^4.0.1"
+ pug "^2.0.4"
+ uuid "^3.3.3"
+
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@@ -4784,6 +5477,13 @@ promise.prototype.finally@^3.1.2:
es-abstract "^1.17.0-next.0"
function-bind "^1.1.1"
+promise@^7.0.1:
+ version "7.3.1"
+ resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
+ integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==
+ dependencies:
+ asap "~2.0.3"
+
promisify-any@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/promisify-any/-/promisify-any-2.0.1.tgz#403e00a8813f175242ab50fe33a69f8eece47305"
@@ -4828,6 +5528,111 @@ pstree.remy@^1.1.7:
resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.7.tgz#c76963a28047ed61542dc361aa26ee55a7fa15f3"
integrity sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==
+pug-attrs@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-2.0.4.tgz#b2f44c439e4eb4ad5d4ef25cac20d18ad28cc336"
+ integrity sha512-TaZ4Z2TWUPDJcV3wjU3RtUXMrd3kM4Wzjbe3EWnSsZPsJ3LDI0F3yCnf2/W7PPFF+edUFQ0HgDL1IoxSz5K8EQ==
+ dependencies:
+ constantinople "^3.0.1"
+ js-stringify "^1.0.1"
+ pug-runtime "^2.0.5"
+
+pug-code-gen@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-2.0.2.tgz#ad0967162aea077dcf787838d94ed14acb0217c2"
+ integrity sha512-kROFWv/AHx/9CRgoGJeRSm+4mLWchbgpRzTEn8XCiwwOy6Vh0gAClS8Vh5TEJ9DBjaP8wCjS3J6HKsEsYdvaCw==
+ dependencies:
+ constantinople "^3.1.2"
+ doctypes "^1.1.0"
+ js-stringify "^1.0.1"
+ pug-attrs "^2.0.4"
+ pug-error "^1.3.3"
+ pug-runtime "^2.0.5"
+ void-elements "^2.0.1"
+ with "^5.0.0"
+
+pug-error@^1.3.3:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-1.3.3.tgz#f342fb008752d58034c185de03602dd9ffe15fa6"
+ integrity sha512-qE3YhESP2mRAWMFJgKdtT5D7ckThRScXRwkfo+Erqga7dyJdY3ZquspprMCj/9sJ2ijm5hXFWQE/A3l4poMWiQ==
+
+pug-filters@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-3.1.1.tgz#ab2cc82db9eeccf578bda89130e252a0db026aa7"
+ integrity sha512-lFfjNyGEyVWC4BwX0WyvkoWLapI5xHSM3xZJFUhx4JM4XyyRdO8Aucc6pCygnqV2uSgJFaJWW3Ft1wCWSoQkQg==
+ dependencies:
+ clean-css "^4.1.11"
+ constantinople "^3.0.1"
+ jstransformer "1.0.0"
+ pug-error "^1.3.3"
+ pug-walk "^1.1.8"
+ resolve "^1.1.6"
+ uglify-js "^2.6.1"
+
+pug-lexer@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-4.1.0.tgz#531cde48c7c0b1fcbbc2b85485c8665e31489cfd"
+ integrity sha512-i55yzEBtjm0mlplW4LoANq7k3S8gDdfC6+LThGEvsK4FuobcKfDAwt6V4jKPH9RtiE3a2Akfg5UpafZ1OksaPA==
+ dependencies:
+ character-parser "^2.1.1"
+ is-expression "^3.0.0"
+ pug-error "^1.3.3"
+
+pug-linker@^3.0.6:
+ version "3.0.6"
+ resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-3.0.6.tgz#f5bf218b0efd65ce6670f7afc51658d0f82989fb"
+ integrity sha512-bagfuHttfQOpANGy1Y6NJ+0mNb7dD2MswFG2ZKj22s8g0wVsojpRlqveEQHmgXXcfROB2RT6oqbPYr9EN2ZWzg==
+ dependencies:
+ pug-error "^1.3.3"
+ pug-walk "^1.1.8"
+
+pug-load@^2.0.12:
+ version "2.0.12"
+ resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-2.0.12.tgz#d38c85eb85f6e2f704dea14dcca94144d35d3e7b"
+ integrity sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg==
+ dependencies:
+ object-assign "^4.1.0"
+ pug-walk "^1.1.8"
+
+pug-parser@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-5.0.1.tgz#03e7ada48b6840bd3822f867d7d90f842d0ffdc9"
+ integrity sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA==
+ dependencies:
+ pug-error "^1.3.3"
+ token-stream "0.0.1"
+
+pug-runtime@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-2.0.5.tgz#6da7976c36bf22f68e733c359240d8ae7a32953a"
+ integrity sha512-P+rXKn9un4fQY77wtpcuFyvFaBww7/91f3jHa154qU26qFAnOe6SW1CbIDcxiG5lLK9HazYrMCCuDvNgDQNptw==
+
+pug-strip-comments@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz#cc1b6de1f6e8f5931cf02ec66cdffd3f50eaf8a8"
+ integrity sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw==
+ dependencies:
+ pug-error "^1.3.3"
+
+pug-walk@^1.1.8:
+ version "1.1.8"
+ resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-1.1.8.tgz#b408f67f27912f8c21da2f45b7230c4bd2a5ea7a"
+ integrity sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA==
+
+pug@^2.0.4:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/pug/-/pug-2.0.4.tgz#ee7682ec0a60494b38d48a88f05f3b0ac931377d"
+ integrity sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw==
+ dependencies:
+ pug-code-gen "^2.0.2"
+ pug-filters "^3.1.1"
+ pug-lexer "^4.1.0"
+ pug-linker "^3.0.6"
+ pug-load "^2.0.12"
+ pug-parser "^5.0.1"
+ pug-runtime "^2.0.5"
+ pug-strip-comments "^1.0.4"
+
pump@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909"
@@ -4868,6 +5673,11 @@ qs@^6.5.1:
resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e"
integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw==
+qs@^6.9.1:
+ version "6.9.4"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687"
+ integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==
+
qs@~6.5.2:
version "6.5.2"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
@@ -5083,6 +5893,16 @@ reflect-metadata@^0.1.12:
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==
+regenerator-runtime@^0.11.0:
+ version "0.11.1"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
+ integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
+
+regenerator-runtime@^0.13.4:
+ version "0.13.5"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697"
+ integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==
+
regexpp@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
@@ -5119,6 +5939,11 @@ render-media@^3.0.0:
stream-to-blob-url "^3.0.0"
videostream "^3.2.0"
+repeat-string@^1.5.2:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
+ integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
+
request@^2.81.0, request@^2.88.0, request@~2.88.0:
version "2.88.2"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
@@ -5172,6 +5997,13 @@ resolve-pkg@^1.0.0:
dependencies:
resolve-from "^2.0.0"
+resolve@^1.1.6:
+ version "1.17.0"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
+ integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==
+ dependencies:
+ path-parse "^1.0.6"
+
resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.13.1:
version "1.15.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8"
@@ -5199,6 +6031,13 @@ revalidator@0.1.x:
resolved "https://registry.yarnpkg.com/revalidator/-/revalidator-0.1.8.tgz#fece61bfa0c1b52a206bd6b18198184bdd523a3b"
integrity sha1-/s5hv6DBtSoga9axgZgYS91SOjs=
+right-align@^0.1.1:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef"
+ integrity sha1-YTObci/mo1FWiSENJOFMlhSGE+8=
+ dependencies:
+ align-text "^0.1.1"
+
rimraf@2.6.3:
version "2.6.3"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
@@ -5264,7 +6103,7 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2,
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
-"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
+"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@^2.1.2, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
@@ -5502,6 +6341,11 @@ slice-ansi@^2.1.0:
astral-regex "^1.0.0"
is-fullwidth-code-point "^2.0.0"
+slick@^1.12.2:
+ version "1.12.2"
+ resolved "https://registry.yarnpkg.com/slick/-/slick-1.12.2.tgz#bd048ddb74de7d1ca6915faa4a57570b3550c2d7"
+ integrity sha1-vQSN23TefRymkV+qSldXCzVQwtc=
+
smtp-connection@4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/smtp-connection/-/smtp-connection-4.0.2.tgz#d9dd68d38569f3ad9265473670d09d8f3ea518db"
@@ -5613,11 +6457,16 @@ source-map-support@^0.5.0, source-map-support@^0.5.6:
buffer-from "^1.0.0"
source-map "^0.6.0"
-source-map@^0.6.0:
+source-map@^0.6.0, source-map@~0.6.0:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+source-map@~0.5.1:
+ version "0.5.7"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
+ integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
+
spawn-command@^0.0.2-1:
version "0.0.2-1"
resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0"
@@ -5668,6 +6517,11 @@ split@^1.0.0:
dependencies:
through "2"
+sprintf-js@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
+ integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
+
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
@@ -6096,6 +6950,16 @@ timers-ext@^0.1.5:
es5-ext "~0.10.46"
next-tick "1"
+titleize@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/titleize/-/titleize-2.1.0.tgz#5530de07c22147a0488887172b5bd94f5b30a48f"
+ integrity sha512-m+apkYlfiQTKLW+sI4vqUkwMEzfgEUEYSqljx1voUE3Wz/z1ZsxyzSxvH2X8uKVrOp7QkByWt0rA6+gvhCKy6g==
+
+tlds@1.207.0:
+ version "1.207.0"
+ resolved "https://registry.yarnpkg.com/tlds/-/tlds-1.207.0.tgz#459264e644cf63ddc0965fece3898913286b1afd"
+ integrity sha512-k7d7Q1LqjtAvhtEOs3yN14EabsNO8ZCoY6RESSJDB9lst3bTx3as/m1UuAeCKzYxiyhR1qq72ZPhpSf+qlqiwg==
+
tmp@0.0.x, tmp@^0.0.33:
version "0.0.33"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
@@ -6113,6 +6977,11 @@ to-arraybuffer@^1.0.1:
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=
+to-fast-properties@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
+ integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=
+
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
@@ -6136,6 +7005,11 @@ toidentifier@1.0.0:
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
+token-stream@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-0.0.1.tgz#ceeefc717a76c4316f126d0b9dbaa55d7e7df01a"
+ integrity sha1-zu78cXp2xDFvEm0LnbqlXX598Bo=
+
toposort-class@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/toposort-class/-/toposort-class-1.0.1.tgz#7ffd1f78c8be28c3ba45cd4e1a3f5ee193bd9988"
@@ -6298,6 +7172,26 @@ typescript@^3.7.2:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061"
integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==
+uc.micro@^1.0.1:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
+ integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
+
+uglify-js@^2.6.1:
+ version "2.8.29"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd"
+ integrity sha1-KcVzMUgFe7Th913zW3qcty5qWd0=
+ dependencies:
+ source-map "~0.5.1"
+ yargs "~3.10.0"
+ optionalDependencies:
+ uglify-to-browserify "~1.0.0"
+
+uglify-to-browserify@~1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7"
+ integrity sha1-bgkk1r2mta/jSeOabWMoUKD4grc=
+
uint64be@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/uint64be/-/uint64be-2.0.2.tgz#ef4a179752fe8f9ddaa29544ecfc13490031e8e5"
@@ -6312,6 +7206,16 @@ undefsafe@^2.0.2:
dependencies:
debug "^2.2.0"
+underscore.deep@~0.5.1:
+ version "0.5.1"
+ resolved "https://registry.yarnpkg.com/underscore.deep/-/underscore.deep-0.5.1.tgz#072671f48d68735c34223fcfef63e69e5276cc2b"
+ integrity sha1-ByZx9I1oc1w0Ij/P72PmnlJ2zCs=
+
+underscore@~1.7.0:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209"
+ integrity sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=
+
uniq@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff"
@@ -6468,6 +7372,11 @@ v8-compile-cache@^2.0.3:
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e"
integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==
+valid-data-url@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/valid-data-url/-/valid-data-url-2.0.0.tgz#2220fa9f8d4e761ebd3f3bb02770f1212b810537"
+ integrity sha512-dyCZnv3aCey7yfTgIqdZanKl7xWAEEKCbgmR7SKqyK6QT/Z07ROactrgD1eA37C69ODRj7rNOjzKWVPh0EUjBA==
+
validate-npm-package-license@^3.0.1:
version "3.0.4"
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
@@ -6522,6 +7431,26 @@ videostream@^3.2.0:
pump "^3.0.0"
range-slice-stream "^2.0.0"
+void-elements@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
+ integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
+
+web-resource-inliner@^4.3.3:
+ version "4.3.4"
+ resolved "https://registry.yarnpkg.com/web-resource-inliner/-/web-resource-inliner-4.3.4.tgz#07e1b4bcbcbee1021251b018e902bac5713f1be0"
+ integrity sha512-agVAgRhOOi4GVlvKK34oM23tDgH8390HfLnZY2HZl8OFBwKNvUJkH7t89AT2iluQP8w9VHAAKX6Z8EN7/9tqKA==
+ dependencies:
+ async "^3.1.0"
+ chalk "^2.4.2"
+ datauri "^2.0.0"
+ htmlparser2 "^4.0.0"
+ lodash.unescape "^4.0.1"
+ request "^2.88.0"
+ safer-buffer "^2.1.2"
+ valid-data-url "^2.0.0"
+ xtend "^4.0.2"
+
webfinger.js@^2.6.6:
version "2.7.0"
resolved "https://registry.yarnpkg.com/webfinger.js/-/webfinger.js-2.7.0.tgz#403354a14a65aeeba64c1408c18a387487cea106"
@@ -6620,6 +7549,11 @@ wildstring@1.0.9:
resolved "https://registry.yarnpkg.com/wildstring/-/wildstring-1.0.9.tgz#82a696d5653c7d4ec9ba716859b6b53aba2761c5"
integrity sha1-gqaW1WU8fU7JunFoWba1OronYcU=
+window-size@0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"
+ integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=
+
winston-transport@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.3.0.tgz#df68c0c202482c448d9b47313c07304c2d7c2c66"
@@ -6656,6 +7590,14 @@ winston@3.2.1:
triple-beam "^1.3.0"
winston-transport "^4.3.0"
+with@^5.0.0:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/with/-/with-5.1.1.tgz#fa4daa92daf32c4ea94ed453c81f04686b575dfe"
+ integrity sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=
+ dependencies:
+ acorn "^3.1.0"
+ acorn-globals "^3.0.0"
+
wkx@^0.4.8:
version "0.4.8"
resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.4.8.tgz#a092cf088d112683fdc7182fd31493b2c5820003"
@@ -6668,6 +7610,11 @@ word-wrap@~1.2.3:
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
+wordwrap@0.0.2:
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
+ integrity sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=
+
wrap-ansi@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09"
@@ -6762,7 +7709,7 @@ xmlhttprequest-ssl@~1.5.4:
resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e"
integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=
-"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.1:
+"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
@@ -6853,6 +7800,16 @@ yargs@^15.3.1:
y18n "^4.0.0"
yargs-parser "^18.1.1"
+yargs@~3.10.0:
+ version "3.10.0"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1"
+ integrity sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=
+ dependencies:
+ camelcase "^1.0.2"
+ cliui "^2.1.0"
+ decamelize "^1.0.0"
+ window-size "0.1.0"
+
yeast@0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"
|