]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Add more embed parameters
authorChocobozzz <me@florianbigard.com>
Tue, 11 Jun 2019 13:59:10 +0000 (15:59 +0200)
committerChocobozzz <me@florianbigard.com>
Tue, 11 Jun 2019 14:05:03 +0000 (16:05 +0200)
12 files changed:
client/src/app/videos/+video-watch/video-watch.component.ts
client/src/assets/player/peertube-player-manager.ts
client/src/sass/include/_variables.scss
client/src/sass/player/_player-variables.scss
client/src/sass/player/context-menu.scss
client/src/sass/player/peertube-skin.scss
client/src/sass/player/settings-menu.scss
client/src/standalone/videos/embed-api.ts [new file with mode: 0644]
client/src/standalone/videos/embed.html
client/src/standalone/videos/embed.ts
server/tests/api/check-params/users.ts
server/tests/api/users/users-verification.ts

index 2d13f1b58cc82cca10b4d0a66793e62a18a1120a..cf9dc8f9ce6327e89d5dbe74f71174a93524979e 100644 (file)
@@ -20,6 +20,7 @@ import { environment } from '../../../environments/environment'
 import { VideoCaptionService } from '@app/shared/video-caption'
 import { MarkdownService } from '@app/shared/renderer'
 import {
+  CustomizationOptions,
   P2PMediaLoaderOptions,
   PeertubePlayerManager,
   PeertubePlayerManagerOptions,
@@ -28,7 +29,7 @@ import {
 import { VideoPlaylist } from '@app/shared/video-playlist/video-playlist.model'
 import { VideoPlaylistService } from '@app/shared/video-playlist/video-playlist.service'
 import { Video } from '@app/shared/video/video.model'
-import { isWebRTCDisabled } from '../../../assets/player/utils'
+import { isWebRTCDisabled, timeToInt } from '../../../assets/player/utils'
 import { VideoWatchPlaylistComponent } from '@app/videos/+video-watch/video-watch-playlist.component'
 
 @Component({
@@ -249,8 +250,13 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
         const urlOptions = {
           startTime: queryParams.start,
           stopTime: queryParams.stop,
+
+          muted: queryParams.muted,
+          loop: queryParams.loop,
           subtitle: queryParams.subtitle,
-          playerMode: queryParams.mode
+
+          playerMode: queryParams.mode,
+          peertubeLink: false
         }
 
         this.onVideoFetched(video, captionsResult.data, urlOptions)
@@ -327,7 +333,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
   private async onVideoFetched (
     video: VideoDetails,
     videoCaptions: VideoCaption[],
-    urlOptions: { startTime?: number, stopTime?: number, subtitle?: string, playerMode?: string }
+    urlOptions: CustomizationOptions & { playerMode: PlayerMode }
   ) {
     this.video = video
 
@@ -339,7 +345,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
 
     this.videoWatchPlaylist.updatePlaylistIndex(video)
 
-    let startTime = urlOptions.startTime || (this.video.userHistory ? this.video.userHistory.currentTime : 0)
+    let startTime = timeToInt(urlOptions.startTime) || (this.video.userHistory ? this.video.userHistory.currentTime : 0)
     // If we are at the end of the video, reset the timer
     if (this.video.duration - startTime <= 1) startTime = 0
 
@@ -378,12 +384,18 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
         enableHotkeys: true,
         inactivityTimeout: 2500,
         poster: this.video.previewUrl,
+
         startTime,
         stopTime: urlOptions.stopTime,
+        controls: urlOptions.controls,
+        muted: urlOptions.muted,
+        loop: urlOptions.loop,
+        subtitle: urlOptions.subtitle,
+
+        peertubeLink: urlOptions.peertubeLink,
 
         theaterMode: true,
         captions: videoCaptions.length !== 0,
-        peertubeLink: false,
 
         videoViewUrl: this.video.privacy.id !== VideoPrivacy.PRIVATE
           ? this.videoService.getVideoViewUrl(this.video.uuid)
@@ -392,8 +404,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
 
         language: this.localeId,
 
-        subtitle: urlOptions.subtitle,
-
         userWatching: this.user && this.user.videosHistoryEnabled === true ? {
           url: this.videoService.getUserWatchingVideoUrl(this.video.uuid),
           authorizationHeader: this.authService.getRequestHeaderValue()
index 31cbc7dfd4c17c3b18f6b3cbcd2572de57968512..8f6237326aff094f6a759a4b0ed09ff0ea0807e7 100644 (file)
@@ -39,7 +39,19 @@ export type P2PMediaLoaderOptions = {
   videoFiles: VideoFile[]
 }
 
-export type CommonOptions = {
+export interface CustomizationOptions {
+  startTime: number | string
+  stopTime: number | string
+
+  controls?: boolean
+  muted?: boolean
+  loop?: boolean
+  subtitle?: string
+
+  peertubeLink: boolean
+}
+
+export interface CommonOptions extends CustomizationOptions {
   playerElement: HTMLVideoElement
   onPlayerElementChange: (element: HTMLVideoElement) => void
 
@@ -48,21 +60,14 @@ export type CommonOptions = {
   enableHotkeys: boolean
   inactivityTimeout: number
   poster: string
-  startTime: number | string
-  stopTime: number | string
 
   theaterMode: boolean
   captions: boolean
-  peertubeLink: boolean
 
   videoViewUrl: string
   embedUrl: string
 
   language?: string
-  controls?: boolean
-  muted?: boolean
-  loop?: boolean
-  subtitle?: string
 
   videoCaptions: VideoJSCaption[]
 
index c7b205b110b1e08f691da6f857fc1cd40ec0c9d0..aafeda2577d0d80af58ac8836e1cb3c1ffb8bd2a 100644 (file)
@@ -71,7 +71,9 @@ $variables: (
   --menuForegroundColor: var(--menuForegroundColor),
   --submenuColor: var(--submenuColor),
   --inputColor: var(--inputColor),
-  --inputPlaceholderColor: var(--inputPlaceholderColor)
+  --inputPlaceholderColor: var(--inputPlaceholderColor),
+  --embedForegroundColor: var(--embedForegroundColor),
+  --embedBigPlayBackgroundColor: var(--embedBigPlayBackgroundColor)
 );
 
 /*** theme helper ***/
index 1101297907b0cd5c881b660d3e9772112a1d9cd6..4e9e8736c02c1a24c9e2a4d6f7a6c8d0f385a16b 100644 (file)
@@ -10,4 +10,10 @@ $slider-bg-color: lighten($primary-background-color, 33%);
 
 $progress-margin: 10px;
 
-$assets-path: '../../assets/' !default;
\ No newline at end of file
+$assets-path: '../../assets/' !default;
+
+body {
+  --embedForegroundColor: #{$primary-foreground-color};
+
+  --embedBigPlayBackgroundColor: #{$primary-background-color};
+}
index 71d6d1b1dbdba5d0a2312006c94205246e4431e3..eeab0ccdfc4b747a2275c4dfde1aa1a66635ff58 100644 (file)
@@ -14,7 +14,7 @@ $context-menu-width: 350px;
 
   .vjs-menu-content {
     opacity: $primary-foreground-opacity;
-    color: $primary-foreground-color;
+    color: var(--embedForegroundCsolor);
     font-size: $font-size !important;
     font-weight: $font-semibold;
   }
@@ -30,4 +30,4 @@ $context-menu-width: 350px;
       background-color: rgba(255, 255, 255, 0.2);
     }
   }
-}
\ No newline at end of file
+}
index e63a2875cd80a65723632a3b820ef85ac3da1afe..996024adeb7f6d20cba4ba670972b63e442845d1 100644 (file)
@@ -10,9 +10,8 @@
 }
 
 .video-js.vjs-peertube-skin {
-
   font-size: $font-size;
-  color: $primary-foreground-color;
+  color: var(--embedForegroundColor);
 
   .vjs-dock-text {
     padding-right: 10px;
   .vjs-control-bar,
   .vjs-big-play-button,
   .vjs-settings-dialog {
-    background-color: rgba($primary-background-color, 0.5);
+    background-color: var(--embedBigPlayBackgroundColor);
   }
 
   .vjs-poster {
     .vjs-theater-control,
     .vjs-settings
     {
-      color: $primary-foreground-color !important;
+      color: var(--embedForegroundColor) !important;
+
       opacity: $primary-foreground-opacity;
       transition: opacity .1s;
 
     .vjs-current-time,
     .vjs-duration,
     .vjs-peertube {
-      color: $primary-foreground-color;
+      color: var(--embedForegroundColor);
       opacity: $primary-foreground-opacity;
     }
 
         transition: none;
 
         .vjs-play-progress {
-          background: $primary-foreground-color;
+          background: var(--embedForegroundColor);
 
           // Not display the circle if the progress is not hovered
           &::before {
index 61965c85ee71c0e98f750cf09549ea6493499bf8..83407b4459f1b3d5d9f0d1a7b41f3aab4752b866 100644 (file)
@@ -38,7 +38,7 @@ $setting-transition-easing: ease-out;
     position: absolute;
     right: .5em;
     bottom: 3.5em;
-    color: $primary-foreground-color;
+    color: var(--embedForegroundColor);
     opacity: $primary-foreground-opacity;
     margin: 0 auto;
     font-size: $font-size !important;
diff --git a/client/src/standalone/videos/embed-api.ts b/client/src/standalone/videos/embed-api.ts
new file mode 100644 (file)
index 0000000..169e371
--- /dev/null
@@ -0,0 +1,130 @@
+import './embed.scss'
+
+import * as Channel from 'jschannel'
+import { PeerTubeResolution } from '../player/definitions'
+import { PeerTubeEmbed } from './embed'
+
+/**
+ * Embed API exposes control of the embed player to the outside world via
+ * JSChannels and window.postMessage
+ */
+export class PeerTubeEmbedApi {
+  private channel: Channel.MessagingChannel
+  private isReady = false
+  private resolutions: PeerTubeResolution[] = null
+
+  constructor (private embed: PeerTubeEmbed) {
+  }
+
+  initialize () {
+    this.constructChannel()
+    this.setupStateTracking()
+
+    // We're ready!
+
+    this.notifyReady()
+  }
+
+  private get element () {
+    return this.embed.videoElement
+  }
+
+  private constructChannel () {
+    const channel = Channel.build({ window: window.parent, origin: '*', scope: this.embed.scope })
+
+    channel.bind('play', (txn, params) => this.embed.player.play())
+    channel.bind('pause', (txn, params) => this.embed.player.pause())
+    channel.bind('seek', (txn, time) => this.embed.player.currentTime(time))
+    channel.bind('setVolume', (txn, value) => this.embed.player.volume(value))
+    channel.bind('getVolume', (txn, value) => this.embed.player.volume())
+    channel.bind('isReady', (txn, params) => this.isReady)
+    channel.bind('setResolution', (txn, resolutionId) => this.setResolution(resolutionId))
+    channel.bind('getResolutions', (txn, params) => this.resolutions)
+    channel.bind('setPlaybackRate', (txn, playbackRate) => this.embed.player.playbackRate(playbackRate))
+    channel.bind('getPlaybackRate', (txn, params) => this.embed.player.playbackRate())
+    channel.bind('getPlaybackRates', (txn, params) => this.embed.playerOptions.playbackRates)
+
+    this.channel = channel
+  }
+
+  private setResolution (resolutionId: number) {
+    if (resolutionId === -1 && this.embed.player.webtorrent().isAutoResolutionForbidden()) return
+
+    // Auto resolution
+    if (resolutionId === -1) {
+      this.embed.player.webtorrent().enableAutoResolution()
+      return
+    }
+
+    this.embed.player.webtorrent().disableAutoResolution()
+    this.embed.player.webtorrent().updateResolution(resolutionId)
+  }
+
+  /**
+   * Let the host know that we're ready to go!
+   */
+  private notifyReady () {
+    this.isReady = true
+    this.channel.notify({ method: 'ready', params: true })
+  }
+
+  private setupStateTracking () {
+    let currentState: 'playing' | 'paused' | 'unstarted' = 'unstarted'
+
+    setInterval(() => {
+      const position = this.element.currentTime
+      const volume = this.element.volume
+
+      this.channel.notify({
+        method: 'playbackStatusUpdate',
+        params: {
+          position,
+          volume,
+          playbackState: currentState
+        }
+      })
+    }, 500)
+
+    this.element.addEventListener('play', ev => {
+      currentState = 'playing'
+      this.channel.notify({ method: 'playbackStatusChange', params: 'playing' })
+    })
+
+    this.element.addEventListener('pause', ev => {
+      currentState = 'paused'
+      this.channel.notify({ method: 'playbackStatusChange', params: 'paused' })
+    })
+
+    // PeerTube specific capabilities
+
+    if (this.embed.player.webtorrent) {
+      this.embed.player.webtorrent().on('autoResolutionUpdate', () => this.loadWebTorrentResolutions())
+      this.embed.player.webtorrent().on('videoFileUpdate', () => this.loadWebTorrentResolutions())
+    }
+  }
+
+  private loadWebTorrentResolutions () {
+    const resolutions = []
+    const currentResolutionId = this.embed.player.webtorrent().getCurrentResolutionId()
+
+    for (const videoFile of this.embed.player.webtorrent().videoFiles) {
+      let label = videoFile.resolution.label
+      if (videoFile.fps && videoFile.fps >= 50) {
+        label += videoFile.fps
+      }
+
+      resolutions.push({
+        id: videoFile.resolution.id,
+        label,
+        src: videoFile.magnetUri,
+        active: videoFile.resolution.id === currentResolutionId
+      })
+    }
+
+    this.resolutions = resolutions
+    this.channel.notify({
+      method: 'resolutionUpdate',
+      params: this.resolutions
+    })
+  }
+}
index c3b6e08ca11bf8f942aa2a19de69b86ec1be7cf8..5a15bf552e845ad41cf5fbfe5fe8de4e9b99901e 100644 (file)
@@ -11,7 +11,7 @@
     <link rel="icon" type="image/png" href="/client/assets/images/favicon.png" />
   </head>
 
-  <body>
+  <body id="custom-css">
 
     <div id="error-block">
       <h1 id="error-title"></h1>
index 707f04253c3ad741fbbec2dd071a5e5420906e93..cfe8e94b178da84560a1ca29d2e760f286fb8bc1 100644 (file)
@@ -1,9 +1,6 @@
 import './embed.scss'
 
-import * as Channel from 'jschannel'
-
 import { peertubeTranslate, ResultList, ServerConfig, VideoDetails } from '../../../../shared'
-import { PeerTubeResolution } from '../player/definitions'
 import { VideoJSCaption } from '../../assets/player/peertube-videojs-typings'
 import { VideoCaption } from '../../../../shared/models/videos/caption/video-caption.model'
 import {
@@ -13,133 +10,9 @@ import {
   PlayerMode
 } from '../../assets/player/peertube-player-manager'
 import { VideoStreamingPlaylistType } from '../../../../shared/models/videos/video-streaming-playlist.type'
+import { PeerTubeEmbedApi } from './embed-api'
 
-/**
- * Embed API exposes control of the embed player to the outside world via
- * JSChannels and window.postMessage
- */
-class PeerTubeEmbedApi {
-  private channel: Channel.MessagingChannel
-  private isReady = false
-  private resolutions: PeerTubeResolution[] = null
-
-  constructor (private embed: PeerTubeEmbed) {
-  }
-
-  initialize () {
-    this.constructChannel()
-    this.setupStateTracking()
-
-    // We're ready!
-
-    this.notifyReady()
-  }
-
-  private get element () {
-    return this.embed.videoElement
-  }
-
-  private constructChannel () {
-    const channel = Channel.build({ window: window.parent, origin: '*', scope: this.embed.scope })
-
-    channel.bind('play', (txn, params) => this.embed.player.play())
-    channel.bind('pause', (txn, params) => this.embed.player.pause())
-    channel.bind('seek', (txn, time) => this.embed.player.currentTime(time))
-    channel.bind('setVolume', (txn, value) => this.embed.player.volume(value))
-    channel.bind('getVolume', (txn, value) => this.embed.player.volume())
-    channel.bind('isReady', (txn, params) => this.isReady)
-    channel.bind('setResolution', (txn, resolutionId) => this.setResolution(resolutionId))
-    channel.bind('getResolutions', (txn, params) => this.resolutions)
-    channel.bind('setPlaybackRate', (txn, playbackRate) => this.embed.player.playbackRate(playbackRate))
-    channel.bind('getPlaybackRate', (txn, params) => this.embed.player.playbackRate())
-    channel.bind('getPlaybackRates', (txn, params) => this.embed.playerOptions.playbackRates)
-
-    this.channel = channel
-  }
-
-  private setResolution (resolutionId: number) {
-    if (resolutionId === -1 && this.embed.player.webtorrent().isAutoResolutionForbidden()) return
-
-    // Auto resolution
-    if (resolutionId === -1) {
-      this.embed.player.webtorrent().enableAutoResolution()
-      return
-    }
-
-    this.embed.player.webtorrent().disableAutoResolution()
-    this.embed.player.webtorrent().updateResolution(resolutionId)
-  }
-
-  /**
-   * Let the host know that we're ready to go!
-   */
-  private notifyReady () {
-    this.isReady = true
-    this.channel.notify({ method: 'ready', params: true })
-  }
-
-  private setupStateTracking () {
-    let currentState: 'playing' | 'paused' | 'unstarted' = 'unstarted'
-
-    setInterval(() => {
-      const position = this.element.currentTime
-      const volume = this.element.volume
-
-      this.channel.notify({
-        method: 'playbackStatusUpdate',
-        params: {
-          position,
-          volume,
-          playbackState: currentState
-        }
-      })
-    }, 500)
-
-    this.element.addEventListener('play', ev => {
-      currentState = 'playing'
-      this.channel.notify({ method: 'playbackStatusChange', params: 'playing' })
-    })
-
-    this.element.addEventListener('pause', ev => {
-      currentState = 'paused'
-      this.channel.notify({ method: 'playbackStatusChange', params: 'paused' })
-    })
-
-    // PeerTube specific capabilities
-
-    if (this.embed.player.webtorrent) {
-      this.embed.player.webtorrent().on('autoResolutionUpdate', () => this.loadWebTorrentResolutions())
-      this.embed.player.webtorrent().on('videoFileUpdate', () => this.loadWebTorrentResolutions())
-    }
-  }
-
-  private loadWebTorrentResolutions () {
-    const resolutions = []
-    const currentResolutionId = this.embed.player.webtorrent().getCurrentResolutionId()
-
-    for (const videoFile of this.embed.player.webtorrent().videoFiles) {
-      let label = videoFile.resolution.label
-      if (videoFile.fps && videoFile.fps >= 50) {
-        label += videoFile.fps
-      }
-
-      resolutions.push({
-        id: videoFile.resolution.id,
-        label,
-        src: videoFile.magnetUri,
-        active: videoFile.resolution.id === currentResolutionId
-      })
-    }
-
-    this.resolutions = resolutions
-    this.channel.notify({
-      method: 'resolutionUpdate',
-      params: this.resolutions
-    })
-  }
-}
-
-class PeerTubeEmbed {
+export class PeerTubeEmbed {
   videoElement: HTMLVideoElement
   player: any
   playerOptions: any
@@ -152,6 +25,12 @@ class PeerTubeEmbed {
   enableApi = false
   startTime: number | string = 0
   stopTime: number | string
+
+  title: boolean
+  warningTitle: boolean
+  bigPlayBackgroundColor: string
+  foregroundColor: string
+
   mode: PlayerMode
   scope = 'peertube'
 
@@ -245,13 +124,18 @@ class PeerTubeEmbed {
       this.controls = this.getParamToggle(params, 'controls', true)
       this.muted = this.getParamToggle(params, 'muted', false)
       this.loop = this.getParamToggle(params, 'loop', false)
+      this.title = this.getParamToggle(params, 'title', true)
       this.enableApi = this.getParamToggle(params, 'api', this.enableApi)
+      this.warningTitle = this.getParamToggle(params, 'warningTitle', true)
 
       this.scope = this.getParamString(params, 'scope', this.scope)
       this.subtitle = this.getParamString(params, 'subtitle')
       this.startTime = this.getParamString(params, 'start')
       this.stopTime = this.getParamString(params, 'stop')
 
+      this.bigPlayBackgroundColor = this.getParamString(params, 'bigPlayBackgroundColor')
+      this.foregroundColor = this.getParamString(params, 'foregroundColor')
+
       this.mode = this.getParamString(params, 'mode') === 'p2p-media-loader' ? 'p2p-media-loader' : 'webtorrent'
     } catch (err) {
       console.error('Cannot get params from URL.', err)
@@ -276,15 +160,7 @@ class PeerTubeEmbed {
     }
 
     const videoInfo: VideoDetails = await videoResponse.json()
-    let videoCaptions: VideoJSCaption[] = []
-    if (captionsResponse.ok) {
-      const { data } = (await captionsResponse.json()) as ResultList<VideoCaption>
-      videoCaptions = data.map(c => ({
-        label: peertubeTranslate(c.language.label, serverTranslations),
-        language: c.language.id,
-        src: window.location.origin + c.captionPath
-      }))
-    }
+    const videoCaptions = await this.buildCaptions(serverTranslations, captionsResponse)
 
     this.loadParams()
 
@@ -337,33 +213,66 @@ class PeerTubeEmbed {
     }
 
     this.player = await PeertubePlayerManager.initialize(this.mode, options)
-
     this.player.on('customError', (event: any, data: any) => this.handleError(data.err, serverTranslations))
 
     window[ 'videojsPlayer' ] = this.player
 
+    this.buildCSS()
+
+    await this.buildDock(videoInfo, configResponse)
+
+    this.initializeApi()
+  }
+
+  private handleError (err: Error, translations?: { [ id: string ]: string }) {
+    if (err.message.indexOf('from xs param') !== -1) {
+      this.player.dispose()
+      this.videoElement = null
+      this.displayError('This video is not available because the remote instance is not responding.', translations)
+      return
+    }
+  }
+
+  private async buildDock (videoInfo: VideoDetails, configResponse: Response) {
     if (this.controls) {
+      const title = this.title ? videoInfo.name : undefined
+
       const config: ServerConfig = await configResponse.json()
-      const description = config.tracker.enabled
+      const description = config.tracker.enabled && this.warningTitle
         ? '<span class="text">' + this.player.localize('Uses P2P, others may know your IP is downloading this video.') + '</span>'
         : undefined
 
       this.player.dock({
-        title: videoInfo.name,
+        title,
         description
       })
     }
+  }
 
-    this.initializeApi()
+  private buildCSS () {
+    const body = document.getElementById('custom-css')
+
+    if (this.bigPlayBackgroundColor) {
+      body.style.setProperty('--embedBigPlayBackgroundColor', this.bigPlayBackgroundColor)
+    }
+
+    if (this.foregroundColor) {
+      body.style.setProperty('--embedForegroundColor', this.foregroundColor)
+    }
   }
 
-  private handleError (err: Error, translations?: { [ id: string ]: string }) {
-    if (err.message.indexOf('from xs param') !== -1) {
-      this.player.dispose()
-      this.videoElement = null
-      this.displayError('This video is not available because the remote instance is not responding.', translations)
-      return
+  private async buildCaptions (serverTranslations: any, captionsResponse: Response): Promise<VideoJSCaption[]> {
+    if (captionsResponse.ok) {
+      const { data } = (await captionsResponse.json()) as ResultList<VideoCaption>
+
+      return data.map(c => ({
+        label: peertubeTranslate(c.language.label, serverTranslations),
+        language: c.language.id,
+        src: window.location.origin + c.captionPath
+      }))
     }
+
+    return []
   }
 }
 
index 3268f8c9011b7c2e944f5dc69d0bc831f1c3d5c5..2316033a194e1d629390d52f3002604af8bf917e 100644 (file)
@@ -379,8 +379,7 @@ describe('Test users API validators', function () {
     it('Should succeed without password change with the correct params', async function () {
       const fields = {
         nsfwPolicy: 'blur',
-        autoPlayVideo: false,
-        email: 'super_email@example.com'
+        autoPlayVideo: false
       }
 
       await makePutBodyRequest({ url: server.url, path: path + 'me', token: userAccessToken, fields, statusCodeExpected: 204 })
index b8fa1430b1a6dd75dddb05a483f9ed86fa56b7d7..7cd61f5395faa12aaf9a1b7b9c9c995c9902108f 100644 (file)
@@ -109,7 +109,8 @@ describe('Test users account verification', function () {
       await updateMyUser({
         url: server.url,
         accessToken: userAccessToken,
-        email: 'updated@example.com'
+        email: 'updated@example.com',
+        currentPassword: user1.password
       })
 
       await waitJobs(server)