diff --git a/.travis.yml b/.travis.yml index 3a73e4fc0..d252ae625 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,12 +48,12 @@ matrix: - env: TEST_SUITE=jest script: - - travis_retry npm run travis -- "$TEST_SUITE" + - NODE_PENDING_JOB_WAIT=1000 travis_retry npm run travis -- "$TEST_SUITE" after_failure: - - cat test1/logs/all-logs.log - - cat test2/logs/all-logs.log - - cat test3/logs/all-logs.log - - cat test4/logs/all-logs.log - - cat test5/logs/all-logs.log - - cat test6/logs/all-logs.log + - cat test1/logs/peertube.log + - cat test2/logs/peertube.log + - cat test3/logs/peertube.log + - cat test4/logs/peertube.log + - cat test5/logs/peertube.log + - cat test6/logs/peertube.log diff --git a/CHANGELOG.md b/CHANGELOG.md index cce6e7402..13bec7535 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,101 @@ # Changelog +## v1.2.0 + +### BREAKING CHANGES + + * **Docker:** `PEERTUBE_TRUST_PROXY` env variable is now an array ([LecygneNoir](https://github.com/LecygneNoir)) + * **Docker:** Check you have all the storage fields in your `/config/production.yaml` file: https://github.com/Chocobozzz/PeerTube/blob/develop/support/docker/production/config/production.yaml#L34 + * **nginx:** Add redundancy endpoint in static file. **You should add it in your nginx configuration: https://github.com/Chocobozzz/PeerTube/blob/develop/support/doc/production.md#nginx** + * **nginx:** Add socket io endpoint. **You should add it in your nginx configuration: https://github.com/Chocobozzz/PeerTube/blob/develop/support/doc/production.md#nginx** + * Moderators can manage users now (add/delete/update/block) + * Add `tmp` and `redundancy` directories in configuration file. **You should configure them in your production.yaml** + +### Maintenance + + * Check free storage before upgrading in upgrade script ([@Nutomic](https://github.com/nutomic)) + * Explain that PeerTube must be stopped in prune storage script + * Add some security directives in the systemd unit configuration file ([@rigelk](https://github.com/rigelk) & [@mkoppmann](https://github.com/mkoppmann)) + * Update FreeBSD startup script ([@gegeweb](https://github.com/gegeweb)) + +### Docker + + * Patch docker entrypoint to speed up the chown at startup ([LecygneNoir](https://github.com/LecygneNoir)) + +### Features + + * Add Russian, Polish and Italian languages + * Add user notifications: + * Notification types: + * Comment on my video + * New video from my subscriptions + * New video abuses (for moderators) + * Blacklist/Unblacklist on my video + * Video import finished (error or success) + * Pending video published (after transcoding or a scheduled update) + * My account or one of my channel has a new follower + * Someone (except muted accounts) mentioned me in comments + * A user registered on the instance (for moderators) + * Notification actions: + * Add a web notification + * Send an english email + * Add contact form in about page (**enabled by default**) + * Add ability to unfederate a local video in blacklist modal (**checkbox checked by default**) + * Support additional video extensions if transcoding is enabled (**enabled by default**) + * Redirect to the last url on login + * Add ability to automatically set the video caption in URL. Example: https://peertube2.cpy.re/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d?subtitle=ru + * Automatically enable the last selected caption when watching a video + * Add ability to disable, clear and list user videos history + * Add a button to help to translate peertube + * Add text in the report modal to explain to whom the report will be sent + * Open my account menu entries on hover + * Explain what features are enabled on the instance in the about page + * Add an error message in the forgot password modal if the instance email system is not configured + * Add sitemap + * Add well known url to change password ([@rigelk](https://github.com/rigelk)) + * Remove 8GB video upload limit on client side. There may still be such limit depending on the reverse proxy configuration ([@scanlime](https://github.com/scanlime)) + * Add CSP ([@rigelk](https://github.com/rigelk) & [@Nutomic](https://github.com/nutomic)) + * Update title and description HTML tags when rendering video HTML page + * Add webfinger support for remote follows ([@acid-chicken](https://github.com/acid-chicken)) + * Add tooltip to explain how the trending algorithm works ([@auberanger](https://github.com/auberanger)) + * Warn users when they want to delete a channel because they will not be able to create another channel with the same name + * Warn users when they leave the video upload/update (on page refresh/tab close) + * Set max user name, user display name, channel name and channel display name lengths to 50 characters ([@McFlat](https://github.com/mcflat)) + * Increase video abuse length to 3000 characters + * Add totalLocalVideoFilesSize in the stats endpoint + +## Bug fixes + + * Fix the addition of captions to a video + * Fix federation of some videos + * Fix NSFW blur on search + * Add error message when trying to upload .ass subtitles + * Fix default homepage in the progressive web application + * Don't crash on queue error + * Fix EXDEV errors if you have multiple mount points + * Fix broken audio in transcoding with some videos + * Fix crash on getVideoFileStream issue + * Fix followers search + * Remove trailing `/` in CLI import script ([@HesioZ](https://github.com/HesioZ/)) + * Use origin video url in canonical tag + * Fix captions in HTTP fallback + * Automatically refresh remote actors to fix deleted remote actors that are still displayed on some instances + * Add missing translations in video embed page + * Fix some styling issues in dark mode + * Fix transcoding issues with some videos + * Fix Mac OS mkv/avi upload + * Fix menu overflow on mobile + * Fix ownership button icons ([@joshmorel](https://github.com/joshmorel)) + + ## v1.1.0 ***Since v1.0.1*** +### BREAKING CHANGES + + * **Docker:** `PEERTUBE_TRUST_PROXY` env variable is now an array ([LecygneNoir](https://github.com/LecygneNoir)) + ### Maintenance * Improve REST API documentation: https://docs.joinpeertube.org/api.html ([@rigelk](https://github.com/rigelk)) @@ -26,7 +118,6 @@ * Add postfix image * Redirect HTTP -> HTTPS * Disable Træfik web UI - * Add ability to set an array in `PEERTUBE_TRUST_PROXY` ([LecygneNoir](https://github.com/LecygneNoir)) ### Features diff --git a/CREDITS.md b/CREDITS.md index ad5125227..509f9800d 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -6,25 +6,27 @@ * [Nutomic](https://github.com/Nutomic) * [Jorropo](https://github.com/Jorropo) * [BO41](https://github.com/BO41) + * [joshmorel](https://github.com/joshmorel) + * [buoyantair](https://github.com/buoyantair) * [bnjbvr](https://github.com/bnjbvr) * [DavidLibeau](https://github.com/DavidLibeau) * [jankeromnes](https://github.com/jankeromnes) - * [joshmorel](https://github.com/joshmorel) * [JohnXLivingston](https://github.com/JohnXLivingston) * [kaiyou](https://github.com/kaiyou) + * [McFlat](https://github.com/McFlat) * [DimitriGilbert](https://github.com/DimitriGilbert) * [floSoX](https://github.com/floSoX) * [Green-Star](https://github.com/Green-Star) + * [thomaskuntzz](https://github.com/thomaskuntzz) * [rezonant](https://github.com/rezonant) * [ldidry](https://github.com/ldidry) - * [McFlat](https://github.com/McFlat) * [okhin](https://github.com/okhin) * [daftaupe](https://github.com/daftaupe) - * [thomaskuntzz](https://github.com/thomaskuntzz) * [LecygneNoir](https://github.com/LecygneNoir) * [fflorent](https://github.com/fflorent) * [dedesite](https://github.com/dedesite) * [Nautigsam](https://github.com/Nautigsam) + * [scanlime](https://github.com/scanlime) * [tcitworld](https://github.com/tcitworld) * [am97](https://github.com/am97) * [dadall](https://github.com/dadall) @@ -35,7 +37,6 @@ * [jocelynj](https://github.com/jocelynj) * [lucas-dclrcq](https://github.com/lucas-dclrcq) * [lucaspontoexe](https://github.com/lucaspontoexe) - * [scanlime](https://github.com/scanlime) * [flyingrub](https://github.com/flyingrub) * [SerCom-KC](https://github.com/SerCom-KC) * [valvin1](https://github.com/valvin1) @@ -43,6 +44,7 @@ * [sticmac](https://github.com/sticmac) * [barbeque](https://github.com/barbeque) * [luzpaz](https://github.com/luzpaz) + * [acid-chicken](https://github.com/acid-chicken) * [louistio](https://github.com/louistio) * [qsypoq](https://github.com/qsypoq) * [daker](https://github.com/daker) @@ -65,6 +67,7 @@ * [grizio](https://github.com/grizio) * [Glandos](https://github.com/Glandos) * [lanodan](https://github.com/lanodan) + * [HesioZ](https://github.com/HesioZ) * [jagannathBhat](https://github.com/jagannathBhat) * [jlebras](https://github.com/jlebras) * [alcalyn](https://github.com/alcalyn) @@ -73,7 +76,9 @@ * [zapashcanon](https://github.com/zapashcanon) * [mart-e](https://github.com/mart-e) * [0mp](https://github.com/0mp) + * [mkoppmann](https://github.com/mkoppmann) * [1000i100](https://github.com/1000i100) + * [roipoussiere](https://github.com/roipoussiere) * [zeograd](https://github.com/zeograd) * [PhieF](https://github.com/PhieF) * [Quenty31](https://github.com/Quenty31) @@ -125,11 +130,14 @@ * [h3zjp](https://trad.framasoft.org/zanata/profile/view/h3zjp) * [jfblanc](https://trad.framasoft.org/zanata/profile/view/jfblanc) * [jhertel](https://trad.framasoft.org/zanata/profile/view/jhertel) + * [jmf](https://trad.framasoft.org/zanata/profile/view/jmf) * [jorropo](https://trad.framasoft.org/zanata/profile/view/jorropo) + * [kairozen](https://trad.framasoft.org/zanata/profile/view/kairozen) * [kedemferre](https://trad.framasoft.org/zanata/profile/view/kedemferre) * [kousha](https://trad.framasoft.org/zanata/profile/view/kousha) * [krkk](https://trad.framasoft.org/zanata/profile/view/krkk) * [landrok](https://trad.framasoft.org/zanata/profile/view/landrok) + * [leeroyepold48](https://trad.framasoft.org/zanata/profile/view/leeroyepold48) * [m4sk1n](https://trad.framasoft.org/zanata/profile/view/m4sk1n) * [matograine](https://trad.framasoft.org/zanata/profile/view/matograine) * [medow](https://trad.framasoft.org/zanata/profile/view/medow) @@ -167,6 +175,10 @@ * [xinayder](https://trad.framasoft.org/zanata/profile/view/xinayder) * [xosem](https://trad.framasoft.org/zanata/profile/view/xosem) * [zveryok](https://trad.framasoft.org/zanata/profile/view/zveryok) + * [aditoo](https://trad.framasoft.org/zanata/profile/view/aditoo) + * [autom](https://trad.framasoft.org/zanata/profile/view/autom) + * [curupira](https://trad.framasoft.org/zanata/profile/view/curupira) + * [leeroyepold48](https://trad.framasoft.org/zanata/profile/view/leeroyepold48) # Design diff --git a/FAQ.md b/FAQ.md index 1e586161c..e335868f8 100644 --- a/FAQ.md +++ b/FAQ.md @@ -13,6 +13,8 @@ - [Will an index of all the videos of servers you follow be too large for small servers?](#will-an-index-of-all-the-videos-of-servers-you-follow-be-too-large-for-small-servers) - [Which container formats can I use for the videos I want to upload?](#which-container-formats-can-i-use-for-the-videos-i-want-to-upload) - [I want to change my domain name, how can I do that?](#i-want-to-change-my-domain-name-how-can-i-do-that) +- [Why do we have to put our Twitter username in PeerTube configuration?](#why-do-we-have-to-put-our-twitter-username-in-peertube-configuration) +- [How video views are calculated?](#how-video-views-are-calculated) - [Should I have a big server to run PeerTube?](#should-i-have-a-big-server-to-run-peertube) - [Can I seed videos with my classic BitTorrent client (Transmission, rTorrent...)?](#can-i-seed-videos-with-my-classic-bittorrent-client-transmission-rtorrent) - [Why host on GitHub and Framagit?](#why-host-on-github-and-framagit) @@ -89,6 +91,18 @@ WEBM, MP4 or OGV videos. You can't. You'll need to reinstall an instance and reupload your videos. +## Why do we have to put our Twitter username in PeerTube configuration? + +You don't have to: we set a default value if you don't have a Twitter account. +We need this information because Twitter requires an account for links share/videos embed on their platform. + + +## How video views are calculated? + +Your web browser sends a view to the server after 30 seconds of playback. Then, the IP cannot send another view in the next hour. +Views are buffered, so don't panic if the view counter stays the same after you watched a video. + + ## Should I have a big server to run PeerTube? Not really. For instance, the demonstration server [https://peertube.cpy.re](https://peertube.cpy.re) has 2 vCore and 2GB of RAM and consumes on average: diff --git a/README.md b/README.md index a3669353b..a9b4eb54a 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,16 @@ Be part of a network of multiple small federated, interoperable video hosting providers. Follow video creators and create videos. No vendor lock-in. All on a platform that is community-owned and ad-free.
++ Developed with ❤ by Framasoft +
+ ++ + + +
+
Client
@@ -123,7 +133,7 @@ You can also join the cheerful bunch that makes our community:
* Chat:
* IRC : **[#peertube on chat.freenode.net:6697](https://kiwiirc.com/client/irc.freenode.net/#peertube)**
- * Matrix (bridged on the IRC channel) : **[#peertube:matrix.org](https://matrix.to/#/#peertube:matrix.org)**
+ * Matrix (bridged on IRC and [Discord](https://discord.gg/wj8DDUT)) : **[#peertube:matrix.org](https://matrix.to/#/#peertube:matrix.org)**
* Forum:
* Framacolibri: [https://framacolibri.org/c/peertube](https://framacolibri.org/c/peertube)
diff --git a/client/package.json b/client/package.json
index 3761a641a..31fc77887 100644
--- a/client/package.json
+++ b/client/package.json
@@ -1,6 +1,6 @@
{
"name": "peertube-client",
- "version": "1.1.0",
+ "version": "1.2.0",
"private": true,
"licence": "GPLv3",
"author": {
@@ -63,26 +63,26 @@
"setupTestFrameworkScriptFile": "Contact {{ instanceName }} administrator
+
- #custom-css .logged-in-email {{ '{' }}
- color: red;
- {{ '}' }}
-
- "
- >
-
- Moderation comment
-
+
+
-
@@ -51,15 +51,15 @@
-
Video name
Sensitive
+ Unfederated
Date
@@ -26,20 +27,21 @@
- {{ videoBlacklist.video.nsfw }}
+ {{ booleanToText(videoBlacklist.video.nsfw) }}
+ {{ booleanToText(videoBlacklist.unfederated) }}
{{ videoBlacklist.createdAt }}
-
-
+
-
+
{{ user.email }}
+
? {{ user.email }}
@@ -76,6 +78,7 @@
{{ user.videoQuotaUsed }} / {{ user.videoQuota }}
{{ user.roleLabel }}
{{ user.createdAt }}
diff --git a/client/src/app/+admin/users/user-list/user-list.component.scss b/client/src/app/+admin/users/user-list/user-list.component.scss
index f235769f0..5274be01c 100644
--- a/client/src/app/+admin/users/user-list/user-list.component.scss
+++ b/client/src/app/+admin/users/user-list/user-list.component.scss
@@ -2,7 +2,7 @@
@import '_mixins';
.add-button {
- @include create-button('../../../../assets/images/global/add.svg');
+ @include create-button;
}
tr.banned {
@@ -23,4 +23,4 @@ tr.banned {
input {
@include peertube-input-text(250px);
}
-}
\ No newline at end of file
+}
diff --git a/client/src/app/+admin/users/user-list/user-list.component.ts b/client/src/app/+admin/users/user-list/user-list.component.ts
index fb085c133..66ab796f9 100644
--- a/client/src/app/+admin/users/user-list/user-list.component.ts
+++ b/client/src/app/+admin/users/user-list/user-list.component.ts
@@ -1,5 +1,5 @@
import { Component, OnInit, ViewChild } from '@angular/core'
-import { NotificationsService } from 'angular2-notifications'
+import { Notifier } from '@app/core'
import { SortMeta } from 'primeng/components/common/sortmeta'
import { ConfirmService, ServerService } from '../../../core'
import { RestPagination, RestTable, UserService } from '../../../shared'
@@ -26,7 +26,7 @@ export class UserListComponent extends RestTable implements OnInit {
bulkUserActions: DropdownActionAccept ownership
-
+
+
diff --git a/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.ts b/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.ts
index 0b51ac13c..77857c4fd 100644
--- a/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.ts
+++ b/client/src/app/+my-account/my-account-ownership/my-account-ownership.component.ts
@@ -1,13 +1,11 @@
import { Component, OnInit, ViewChild } from '@angular/core'
-import { NotificationsService } from 'angular2-notifications'
-import { I18n } from '@ngx-translate/i18n-polyfill'
+import { Notifier } from '@app/core'
import { RestPagination, RestTable } from '@app/shared'
import { SortMeta } from 'primeng/components/common/sortmeta'
import { VideoChangeOwnership } from '../../../../../shared'
import { VideoOwnershipService } from '@app/shared/video-ownership'
import { Account } from '@app/shared/account/account.model'
-import { MyAccountAcceptOwnershipComponent }
-from '@app/+my-account/my-account-ownership/my-account-accept-ownership/my-account-accept-ownership.component'
+import { MyAccountAcceptOwnershipComponent } from './my-account-accept-ownership/my-account-accept-ownership.component'
@Component({
selector: 'my-account-ownership',
@@ -23,9 +21,8 @@ export class MyAccountOwnershipComponent extends RestTable implements OnInit {
@ViewChild('myAccountAcceptOwnershipComponent') myAccountAcceptOwnershipComponent: MyAccountAcceptOwnershipComponent
constructor (
- private notificationsService: NotificationsService,
- private videoOwnershipService: VideoOwnershipService,
- private i18n: I18n
+ private notifier: Notifier,
+ private videoOwnershipService: VideoOwnershipService
) {
super()
}
@@ -50,7 +47,7 @@ export class MyAccountOwnershipComponent extends RestTable implements OnInit {
this.videoOwnershipService.refuseOwnership(videoChangeOwnership.id)
.subscribe(
() => this.loadData(),
- err => this.notificationsService.error(this.i18n('Error'), err.message)
+ err => this.notifier.error(err.message)
)
}
@@ -62,7 +59,7 @@ export class MyAccountOwnershipComponent extends RestTable implements OnInit {
this.totalRecords = resultList.total
},
- err => this.notificationsService.error(this.i18n('Error'), err.message)
+ err => this.notifier.error(err.message)
)
}
}
diff --git a/client/src/app/+my-account/my-account-routing.module.ts b/client/src/app/+my-account/my-account-routing.module.ts
index 601e517b4..9996218ca 100644
--- a/client/src/app/+my-account/my-account-routing.module.ts
+++ b/client/src/app/+my-account/my-account-routing.module.ts
@@ -13,6 +13,8 @@ import { MyAccountSubscriptionsComponent } from '@app/+my-account/my-account-sub
import { MyAccountOwnershipComponent } from '@app/+my-account/my-account-ownership/my-account-ownership.component'
import { MyAccountBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-blocklist.component'
import { MyAccountServerBlocklistComponent } from '@app/+my-account/my-account-blocklist/my-account-server-blocklist.component'
+import { MyAccountHistoryComponent } from '@app/+my-account/my-account-history/my-account-history.component'
+import { MyAccountNotificationsComponent } from '@app/+my-account/my-account-notifications/my-account-notifications.component'
const myAccountRoutes: Routes = [
{
@@ -114,6 +116,24 @@ const myAccountRoutes: Routes = [
title: 'Muted instances'
}
}
+ },
+ {
+ path: 'history/videos',
+ component: MyAccountHistoryComponent,
+ data: {
+ meta: {
+ title: 'Videos history'
+ }
+ }
+ },
+ {
+ path: 'notifications',
+ component: MyAccountNotificationsComponent,
+ data: {
+ meta: {
+ title: 'Notifications'
+ }
+ }
}
]
}
diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts
index e5343b33d..cbb068c7c 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-change-password/my-account-change-password.component.ts
@@ -1,11 +1,10 @@
import { Component, OnInit } from '@angular/core'
-import { NotificationsService } from 'angular2-notifications'
+import { AuthService, Notifier } from '@app/core'
import { FormReactive, UserService } from '../../../shared'
import { I18n } from '@ngx-translate/i18n-polyfill'
import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
import { UserValidatorsService } from '@app/shared/forms/form-validators/user-validators.service'
import { filter } from 'rxjs/operators'
-import { AuthService } from '@app/core'
import { User } from '../../../../../../shared'
@Component({
@@ -20,7 +19,7 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On
constructor (
protected formValidatorService: FormValidatorService,
private userValidatorsService: UserValidatorsService,
- private notificationsService: NotificationsService,
+ private notifier: Notifier,
private authService: AuthService,
private userService: UserService,
private i18n: I18n
@@ -50,7 +49,7 @@ export class MyAccountChangePasswordComponent extends FormReactive implements On
this.userService.changePassword(currentPassword, newPassword).subscribe(
() => {
- this.notificationsService.success(this.i18n('Success'), this.i18n('Password updated.'))
+ this.notifier.success(this.i18n('Password updated.'))
this.form.reset()
this.error = null
diff --git a/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts b/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts
index 63a121f64..3f79efe20 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-danger-zone/my-account-danger-zone.component.ts
@@ -1,5 +1,5 @@
import { Component, Input } from '@angular/core'
-import { NotificationsService } from 'angular2-notifications'
+import { Notifier } from '@app/core'
import { AuthService, ConfirmService, RedirectService } from '../../../core'
import { UserService } from '../../../shared'
import { I18n } from '@ngx-translate/i18n-polyfill'
@@ -15,7 +15,7 @@ export class MyAccountDangerZoneComponent {
constructor (
private authService: AuthService,
- private notificationsService: NotificationsService,
+ private notifier: Notifier,
private userService: UserService,
private confirmService: ConfirmService,
private redirectService: RedirectService,
@@ -34,13 +34,13 @@ export class MyAccountDangerZoneComponent {
this.userService.deleteMe().subscribe(
() => {
- this.notificationsService.success(this.i18n('Success'), this.i18n('Your account is deleted.'))
+ this.notifier.success(this.i18n('Your account is deleted.'))
this.authService.logout()
this.redirectService.redirectToHomepage()
},
- err => this.notificationsService.error(this.i18n('Error'), err.message)
+ err => this.notifier.error(err.message)
)
}
}
diff --git a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/index.ts b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/index.ts
new file mode 100644
index 000000000..5e1d51339
--- /dev/null
+++ b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/index.ts
@@ -0,0 +1 @@
+export * from './my-account-notification-preferences.component'
diff --git a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.html b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.html
new file mode 100644
index 000000000..59422d682
--- /dev/null
+++ b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.html
@@ -0,0 +1,19 @@
+Change ownership
-
+
+ Forgot your password
-
+
+ Change the language
-
+