From 327b6fb5dcbabf5de61e1ce0fa6c65329a8ec45b Mon Sep 17 00:00:00 2001
From: Syldexia <syldexia@ofthewi.red>
Date: Sun, 13 May 2018 15:09:07 +0100
Subject: Added delete account section to user settings

---
 src/components/user_settings/user_settings.vue | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

(limited to 'src/components/user_settings/user_settings.vue')

diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index ed1864cc..fbfbef8a 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -66,6 +66,20 @@
           <p>{{$t('settings.follow_import_error')}}</p>
         </div>
       </div>
+      <hr>
+      <div class="setting-item">
+        <h3>{{$t('settings.delete_account')}}</h3>
+        <p v-if="!deletingAccount">{{$t('settings.delete_account_description')}}</p>
+        <div v-if="deletingAccount">
+          <p>{{$t('settings.delete_account_instructions')}}</p>
+          <p>{{$t('login.password')}}</p>
+          <input type="password" v-model="deleteAccountConfirmPasswordInput">
+          <button class="btn btn-default" @click="deleteAccount">{{$t('settings.delete_account')}}</button>
+        </div>
+        <p v-if="deleteAccountError !== false">{{$t('settings.delete_account_error')}}</p>
+        <p v-if="deleteAccountError">{{deleteAccountError}}</p>
+        <button class="btn btn-default" v-if="!deletingAccount" @click="confirmDelete">{{$t('general.submit')}}</button>
+      </div>
     </div>
   </div>
 </template>
-- 
cgit v1.2.3-70-g09d2


From fae7a40aebc4266260c8cb0dcac929ac03500590 Mon Sep 17 00:00:00 2001
From: aka <aka@social.sakamoto.gq>
Date: Sun, 13 May 2018 20:47:08 -0300
Subject: Adds an option to export follows

---
 src/components/user_settings/user_settings.js  | 29 ++++++++++++++++++++++++++
 src/components/user_settings/user_settings.vue |  7 +++++++
 src/i18n/messages.js                           |  5 ++++-
 3 files changed, 40 insertions(+), 1 deletion(-)

(limited to 'src/components/user_settings/user_settings.vue')

diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js
index 25ee1f35..602052ca 100644
--- a/src/components/user_settings/user_settings.js
+++ b/src/components/user_settings/user_settings.js
@@ -8,6 +8,7 @@ const UserSettings = {
       followList: null,
       followImportError: false,
       followsImported: false,
+      enableFollowsExport: true,
       uploading: [ false, false, false, false ],
       previews: [ null, null, null ]
     }
@@ -137,6 +138,34 @@ const UserSettings = {
           this.uploading[3] = false
         })
     },
+    /* This function takes an Array of Users
+     * and outputs a file with all the addresses for the user to download
+     */
+    exportPeople(Users) {
+      // Get all the friends addresses
+      var UserAddresses = Users.map(function(user) {
+	// check is it's a local user
+	if(user && user.is_local) {
+	  // append the instance address
+	  user.screen_name += '@' + location.hostname;
+	}
+	return user.screen_name;
+      }).join('\n');
+      // Make the user download the file
+      var fileToDownload = document.createElement('a');
+      fileToDownload.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(UserAddresses));
+      fileToDownload.setAttribute('download', 'friends.csv');
+      fileToDownload.style.display = 'none';
+      document.body.appendChild(fileToDownload);
+      fileToDownload.click();
+      document.body.removeChild(fileToDownload);
+    },
+    exportFollows() {
+      this.enableFollowsExport = false;
+      this.$store.state.api.backendInteractor
+	.fetchFriends({id: this.$store.state.users.currentUser.id})
+	.then(this.exportPeople);
+    },
     followListChange () {
       // eslint-disable-next-line no-undef
       let formData = new FormData()
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index ed1864cc..184d158d 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -66,6 +66,13 @@
           <p>{{$t('settings.follow_import_error')}}</p>
         </div>
       </div>
+      <div class="setting-item" v-if="enableFollowsExport">
+       <h3>{{$t('settings.follow_export')}}</h3>
+       <button class="btn btn-default" @click="exportFollows">{{$t('settings.follow_export_button')}}</button>
+     </div>
+     <div class="setting-item" v-else>
+       <h3>{{$t('settings.follow_export_processing')}}</h3>
+       </div>
     </div>
   </div>
 </template>
diff --git a/src/i18n/messages.js b/src/i18n/messages.js
index 168548cf..473fd9b1 100644
--- a/src/i18n/messages.js
+++ b/src/i18n/messages.js
@@ -288,7 +288,10 @@ const en = {
     follow_import: 'Follow import',
     import_followers_from_a_csv_file: 'Import follows from a csv file',
     follows_imported: 'Follows imported! Processing them will take a while.',
-    follow_import_error: 'Error importing followers'
+    follow_import_error: 'Error importing followers',
+    follow_export: 'Follow export',
+    follow_export_processing: 'Processing, you\'ll soon be aked to download your file',
+    follow_export_button: 'Export your follows to a csv file'
   },
   notifications: {
     notifications: 'Notifications',
-- 
cgit v1.2.3-70-g09d2


From e0ba6a587671c4e7d484152f35076c0fb1eb2996 Mon Sep 17 00:00:00 2001
From: Syldexia <syldexia@ofthewi.red>
Date: Mon, 21 May 2018 23:01:09 +0100
Subject: Added change password to user settings

---
 src/components/user_settings/user_settings.js      | 22 +++++++++++++++++++++-
 src/components/user_settings/user_settings.vue     | 21 ++++++++++++++++++++-
 src/i18n/messages.js                               | 10 ++++++++--
 src/services/api/api.service.js                    | 19 ++++++++++++++++++-
 .../backend_interactor_service.js                  |  4 +++-
 5 files changed, 70 insertions(+), 6 deletions(-)

(limited to 'src/components/user_settings/user_settings.vue')

diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js
index 1e7b9b12..b6026e18 100644
--- a/src/components/user_settings/user_settings.js
+++ b/src/components/user_settings/user_settings.js
@@ -13,7 +13,10 @@ const UserSettings = {
       previews: [ null, null, null ],
       deletingAccount: false,
       deleteAccountConfirmPasswordInput: '',
-      deleteAccountError: false
+      deleteAccountError: false,
+      changePasswordInputs: [ '', '', '' ],
+      changedPassword: false,
+      changePasswordError: false
     }
   },
   components: {
@@ -195,6 +198,23 @@ const UserSettings = {
             this.deleteAccountError = res.error
           }
         })
+    },
+    changePassword () {
+      const params = {
+        password: this.changePasswordInputs[0],
+        newPassword: this.changePasswordInputs[1],
+        newPasswordConfirmation: this.changePasswordInputs[2]
+      }
+      this.$store.state.api.backendInteractor.changePassword(params)
+        .then((res) => {
+          if (res.status === 'success') {
+            this.changedPassword = true
+            this.changePasswordError = false
+          } else {
+            this.changedPassword = false
+            this.changePasswordError = res.error
+          }
+        })
     }
   }
 }
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index ea9763f3..fbf3f651 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -49,6 +49,25 @@
         <i class=" icon-spin4 animate-spin uploading" v-if="uploading[2]"></i>
         <button class="btn btn-default" v-else-if="previews[2]" @click="submitBg">{{$t('general.submit')}}</button>
       </div>
+      <div class="setting-item">
+        <h3>{{$t('settings.change_password')}}</h3>
+        <div>
+          <p>{{$t('settings.current_password')}}</p>
+          <input type="password" v-model="changePasswordInputs[0]">
+        </div>
+        <div>
+          <p>{{$t('settings.new_password')}}</p>
+          <input type="password" v-model="changePasswordInputs[1]">
+        </div>
+        <div>
+          <p>{{$t('settings.confirm_new_password')}}</p>
+          <input type="password" v-model="changePasswordInputs[2]">
+        </div>
+        <button class="btn btn-default" @click="changePassword">{{$t('general.submit')}}</button>
+        <p v-if="changedPassword">{{$t('settings.changed_password')}}</p>
+        <p v-else-if="changePasswordError !== false">{{$t('settings.change_password_error')}}</p>
+        <p v-if="changePasswordError">{{changePasswordError}}</p>
+      </div>
       <div class="setting-item" v-if="pleromaBackend">
         <h3>{{$t('settings.follow_import')}}</h3>
         <p>{{$t('settings.import_followers_from_a_csv_file')}}</p>
@@ -62,7 +81,7 @@
           <p>{{$t('settings.follows_imported')}}</p>
         </div>
         <div v-else-if="followImportError">
-          <i class="icon-cross" @click="dismissImported"</i>
+          <i class="icon-cross" @click="dismissImported"></i>
           <p>{{$t('settings.follow_import_error')}}</p>
         </div>
       </div>
diff --git a/src/i18n/messages.js b/src/i18n/messages.js
index 19b50272..54a99b5a 100644
--- a/src/i18n/messages.js
+++ b/src/i18n/messages.js
@@ -291,12 +291,18 @@ const en = {
     follows_imported: 'Follows imported! Processing them will take a while.',
     follow_import_error: 'Error importing followers',
     delete_account: 'Delete Account',
-    delete_account_description: 'Permanantly delete your account and all your messages.',
+    delete_account_description: 'Permanently delete your account and all your messages.',
     delete_account_instructions: 'Type your password in the input below to confirm account deletion.',
     delete_account_error: 'There was an issue deleting your account. If this persists please contact your instance administrator.',
     follow_export: 'Follow export',
     follow_export_processing: 'Processing, you\'ll soon be asked to download your file',
-    follow_export_button: 'Export your follows to a csv file'
+    follow_export_button: 'Export your follows to a csv file',
+    change_password: 'Change Password',
+    current_password: 'Current password',
+    new_password: 'New password',
+    confirm_new_password: 'Confirm new password',
+    changed_password: 'Password changed successfully!',
+    change_password_error: 'There was an issue changing your password.'
   },
   notifications: {
     notifications: 'Notifications',
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index fd401068..65761aee 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -31,6 +31,7 @@ const UNBLOCKING_URL = '/api/blocks/destroy.json'
 const USER_URL = '/api/users/show.json'
 const FOLLOW_IMPORT_URL = '/api/pleroma/follow_import'
 const DELETE_ACCOUNT_URL = '/api/pleroma/delete_account'
+const CHANGE_PASSWORD_URL = '/api/pleroma/change_password'
 
 import { each, map } from 'lodash'
 import 'whatwg-fetch'
@@ -387,6 +388,21 @@ const deleteAccount = ({credentials, password}) => {
     .then((response) => response.json())
 }
 
+const changePassword = ({credentials, password, newPassword, newPasswordConfirmation}) => {
+  const form = new FormData()
+
+  form.append('password', password)
+  form.append('new_password', newPassword)
+  form.append('new_password_confirmation', newPasswordConfirmation)
+
+  return fetch(CHANGE_PASSWORD_URL, {
+    body: form,
+    method: 'POST',
+    headers: authHeaders(credentials)
+  })
+    .then((response) => response.json())
+}
+
 const fetchMutes = ({credentials}) => {
   const url = '/api/qvitter/mutes.json'
 
@@ -423,7 +439,8 @@ const apiService = {
   updateBanner,
   externalProfile,
   followImport,
-  deleteAccount
+  deleteAccount,
+  changePassword
 }
 
 export default apiService
diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js
index c5807bed..14173558 100644
--- a/src/services/backend_interactor_service/backend_interactor_service.js
+++ b/src/services/backend_interactor_service/backend_interactor_service.js
@@ -62,6 +62,7 @@ const backendInteractorService = (credentials) => {
   const followImport = ({params}) => apiService.followImport({params, credentials})
 
   const deleteAccount = ({password}) => apiService.deleteAccount({credentials, password})
+  const changePassword = ({password, newPassword, newPasswordConfirmation}) => apiService.changePassword({credentials, password, newPassword, newPasswordConfirmation})
 
   const backendInteractorServiceInstance = {
     fetchStatus,
@@ -85,7 +86,8 @@ const backendInteractorService = (credentials) => {
     updateProfile,
     externalProfile,
     followImport,
-    deleteAccount
+    deleteAccount,
+    changePassword
   }
 
   return backendInteractorServiceInstance
-- 
cgit v1.2.3-70-g09d2

