commit: efc4fa1099024e0451fd7e0d271bd0a4a25aff5a
parent: 058238c3c631520d052327fcab47c997dfe23151
Author: Shpuld Shpludson <shp@cock.li>
Date: Thu, 28 Feb 2019 17:03:11 +0000
Merge branch 'feature/oauth-tokens-in-settings' into 'develop'
Add OAuth Tokens management to settings
See merge request pleroma/pleroma-fe!572
Diffstat:
24 files changed, 192 insertions(+), 2 deletions(-)
diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js
@@ -1,7 +1,6 @@
import { compose } from 'vue-compose'
import unescape from 'lodash/unescape'
import get from 'lodash/get'
-
import TabSwitcher from '../tab_switcher/tab_switcher.js'
import ImageCropper from '../image_cropper/image_cropper.vue'
import StyleSwitcher from '../style_switcher/style_switcher.vue'
@@ -62,6 +61,9 @@ const UserSettings = {
activeTab: 'profile'
}
},
+ created () {
+ this.$store.dispatch('fetchTokens')
+ },
components: {
StyleSwitcher,
TabSwitcher,
@@ -89,6 +91,15 @@ const UserSettings = {
},
currentSaveStateNotice () {
return this.$store.state.interface.settings.currentSaveStateNotice
+ },
+ oauthTokens () {
+ return this.$store.state.oauthTokens.tokens.map(oauthToken => {
+ return {
+ id: oauthToken.id,
+ appName: oauthToken.app_name,
+ validUntil: new Date(oauthToken.valid_until).toLocaleDateString()
+ }
+ })
}
},
methods: {
@@ -308,6 +319,11 @@ const UserSettings = {
logout () {
this.$store.dispatch('logout')
this.$router.replace('/')
+ },
+ revokeToken (id) {
+ if (window.confirm(`${this.$i18n.t('settings.revoke_token')}?`)) {
+ this.$store.dispatch('revokeToken', id)
+ }
}
}
}
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
@@ -122,6 +122,30 @@
</div>
<div class="setting-item">
+ <h2>{{$t('settings.oauth_tokens')}}</h2>
+ <table class="oauth-tokens">
+ <thead>
+ <tr>
+ <th>{{$t('settings.app_name')}}</th>
+ <th>{{$t('settings.valid_until')}}</th>
+ <th></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr v-for="oauthToken in oauthTokens" :key="oauthToken.id">
+ <td>{{oauthToken.appName}}</td>
+ <td>{{oauthToken.validUntil}}</td>
+ <td class="actions">
+ <button class="btn btn-default" @click="revokeToken(oauthToken.id)">
+ {{$t('settings.revoke_token')}}
+ </button>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+
+ <div class="setting-item">
<h2>{{$t('settings.delete_account')}}</h2>
<p v-if="!deletingAccount">{{$t('settings.delete_account_description')}}</p>
<div v-if="deletingAccount">
@@ -213,5 +237,17 @@
border-radius: $fallback--avatarRadius;
border-radius: var(--avatarRadius, $fallback--avatarRadius);
}
+
+ .oauth-tokens {
+ width: 100%;
+
+ th {
+ text-align: left;
+ }
+
+ .actions {
+ text-align: right;
+ }
+ }
}
</style>
diff --git a/src/i18n/ar.json b/src/i18n/ar.json
@@ -134,6 +134,11 @@
"notification_visibility_mentions": "الإشارات",
"notification_visibility_repeats": "",
"nsfw_clickthrough": "",
+ "oauth_tokens": "رموز OAuth",
+ "token": "رمز",
+ "refresh_token": "رمز التحديث",
+ "valid_until": "صالح حتى",
+ "revoke_token": "سحب",
"panelRadius": "",
"pause_on_unfocused": "",
"presets": "النماذج",
diff --git a/src/i18n/ca.json b/src/i18n/ca.json
@@ -132,6 +132,11 @@
"notification_visibility_repeats": "Republica una entrada meva",
"no_rich_text_description": "Neteja el formatat de text de totes les entrades",
"nsfw_clickthrough": "Amaga el contingut NSFW darrer d'una imatge clicable",
+ "oauth_tokens": "Llistats OAuth",
+ "token": "Token",
+ "refresh_token": "Actualitza el token",
+ "valid_until": "Vàlid fins",
+ "revoke_token": "Revocar",
"panelRadius": "Panells",
"pause_on_unfocused": "Pausa la reproducció en continu quan la pestanya perdi el focus",
"presets": "Temes",
diff --git a/src/i18n/de.json b/src/i18n/de.json
@@ -159,6 +159,11 @@
"hide_follows_description": "Zeige nicht, wem ich folge",
"hide_followers_description": "Zeige nicht, wer mir folgt",
"nsfw_clickthrough": "Aktiviere ausblendbares Overlay für Anhänge, die als NSFW markiert sind",
+ "oauth_tokens": "OAuth-Token",
+ "token": "Zeichen",
+ "refresh_token": "Token aktualisieren",
+ "valid_until": "Gültig bis",
+ "revoke_token": "Widerrufen",
"panelRadius": "Panel",
"pause_on_unfocused": "Streaming pausieren, wenn das Tab nicht fokussiert ist",
"presets": "Voreinstellungen",
diff --git a/src/i18n/en.json b/src/i18n/en.json
@@ -106,6 +106,7 @@
}
},
"settings": {
+ "app_name": "App name",
"attachmentRadius": "Attachments",
"attachments": "Attachments",
"autoload": "Enable automatic loading when scrolled to the bottom",
@@ -189,6 +190,11 @@
"show_admin_badge": "Show Admin badge in my profile",
"show_moderator_badge": "Show Moderator badge in my profile",
"nsfw_clickthrough": "Enable clickthrough NSFW attachment hiding",
+ "oauth_tokens": "OAuth tokens",
+ "token": "Token",
+ "refresh_token": "Refresh Token",
+ "valid_until": "Valid Until",
+ "revoke_token": "Revoke",
"panelRadius": "Panels",
"pause_on_unfocused": "Pause streaming when tab is not focused",
"presets": "Presets",
diff --git a/src/i18n/es.json b/src/i18n/es.json
@@ -171,6 +171,11 @@
"show_admin_badge": "Mostrar la placa de administrador en mi perfil",
"show_moderator_badge": "Mostrar la placa de moderador en mi perfil",
"nsfw_clickthrough": "Activar el clic para ocultar los adjuntos NSFW",
+ "oauth_tokens": "Tokens de OAuth",
+ "token": "Token",
+ "refresh_token": "Actualizar el token",
+ "valid_until": "Válido hasta",
+ "revoke_token": "Revocar",
"panelRadius": "Paneles",
"pause_on_unfocused": "Parar la transmisión cuando no estés en foco.",
"presets": "Por defecto",
diff --git a/src/i18n/fi.json b/src/i18n/fi.json
@@ -166,6 +166,11 @@
"no_rich_text_description": "Älä näytä tekstin muotoilua.",
"hide_network_description": "Älä näytä seurauksiani tai seuraajiani",
"nsfw_clickthrough": "Piilota NSFW liitteet klikkauksen taakse",
+ "oauth_tokens": "OAuth-merkit",
+ "token": "Token",
+ "refresh_token": "Päivitä token",
+ "valid_until": "Voimassa asti",
+ "revoke_token": "Peruuttaa",
"panelRadius": "Ruudut",
"pause_on_unfocused": "Pysäytä automaattinen viestien näyttö välilehden ollessa pois fokuksesta",
"presets": "Valmiit teemat",
diff --git a/src/i18n/fr.json b/src/i18n/fr.json
@@ -137,6 +137,11 @@
"notification_visibility_mentions": "Mentionnés",
"notification_visibility_repeats": "Partages",
"nsfw_clickthrough": "Masquer les images marquées comme contenu adulte ou sensible",
+ "oauth_tokens": "Jetons OAuth",
+ "token": "Jeton",
+ "refresh_token": "Refresh Token",
+ "valid_until": "Valable jusque",
+ "revoke_token": "Révoquer",
"panelRadius": "Fenêtres",
"pause_on_unfocused": "Suspendre le streaming lorsque l'onglet n'est pas centré",
"presets": "Thèmes prédéfinis",
diff --git a/src/i18n/ga.json b/src/i18n/ga.json
@@ -134,6 +134,11 @@
"notification_visibility_repeats": "Atphostáil",
"no_rich_text_description": "Bain formáidiú téacs saibhir ó gach post",
"nsfw_clickthrough": "Cumasaigh an ceangaltán NSFW cliceáil ar an gcnaipe",
+ "oauth_tokens": "Tocanna OAuth",
+ "token": "Token",
+ "refresh_token": "Athnuachan Comórtas",
+ "valid_until": "Bailí Go dtí",
+ "revoke_token": "Athghairm",
"panelRadius": "Painéil",
"pause_on_unfocused": "Sruthú ar sos nuair a bhíonn an fócas caillte",
"presets": "Réamhshocruithe",
diff --git a/src/i18n/he.json b/src/i18n/he.json
@@ -129,6 +129,11 @@
"notification_visibility_mentions": "אזכורים",
"notification_visibility_repeats": "חזרות",
"nsfw_clickthrough": "החל החבאת צירופים לא בטוחים לצפיה בעת עבודה בעזרת לחיצת עכבר",
+ "oauth_tokens": "אסימוני OAuth",
+ "token": "אסימון",
+ "refresh_token": "רענון האסימון",
+ "valid_until": "בתוקף עד",
+ "revoke_token": "בטל",
"panelRadius": "פאנלים",
"pause_on_unfocused": "השהה זרימת הודעות כשהחלון לא בפוקוס",
"presets": "ערכים קבועים מראש",
diff --git a/src/i18n/it.json b/src/i18n/it.json
@@ -93,6 +93,11 @@
"notification_visibility_mentions": "Menzioni",
"notification_visibility_repeats": "Condivisioni",
"no_rich_text_description": "Togli la formattazione del testo da tutti i post",
+ "oauth_tokens": "Token OAuth",
+ "token": "Token",
+ "refresh_token": "Aggiorna token",
+ "valid_until": "Valido fino a",
+ "revoke_token": "Revocare",
"panelRadius": "Pannelli",
"pause_on_unfocused": "Metti in pausa l'aggiornamento continuo quando la scheda non è in primo piano",
"presets": "Valori predefiniti",
diff --git a/src/i18n/ja.json b/src/i18n/ja.json
@@ -171,6 +171,11 @@
"show_admin_badge": "アドミンのしるしをみる",
"show_moderator_badge": "モデレーターのしるしをみる",
"nsfw_clickthrough": "NSFWなファイルをかくす",
+ "oauth_tokens": "OAuthトークン",
+ "token": "トークン",
+ "refresh_token": "トークンを更新",
+ "valid_until": "まで有効",
+ "revoke_token": "取り消す",
"panelRadius": "パネル",
"pause_on_unfocused": "タブにフォーカスがないときストリーミングをとめる",
"presets": "プリセット",
diff --git a/src/i18n/ko.json b/src/i18n/ko.json
@@ -159,6 +159,11 @@
"hide_follows_description": "내가 팔로우하는 사람을 표시하지 않음",
"hide_followers_description": "나를 따르는 사람을 보여주지 마라.",
"nsfw_clickthrough": "NSFW 이미지 \"클릭해서 보이기\"를 활성화",
+ "oauth_tokens": "OAuth 토큰",
+ "token": "토큰",
+ "refresh_token": "토큰 새로 고침",
+ "valid_until": "까지 유효하다",
+ "revoke_token": "취소",
"panelRadius": "패널",
"pause_on_unfocused": "탭이 활성 상태가 아닐 때 스트리밍 멈추기",
"presets": "프리셋",
diff --git a/src/i18n/nb.json b/src/i18n/nb.json
@@ -132,6 +132,11 @@
"notification_visibility_repeats": "Gjentakelser",
"no_rich_text_description": "Fjern all formatering fra statuser",
"nsfw_clickthrough": "Krev trykk for å vise statuser som kan være upassende",
+ "oauth_tokens": "OAuth Tokens",
+ "token": "Pollett",
+ "refresh_token": "Refresh Token",
+ "valid_until": "Gyldig til",
+ "revoke_token": "Tilbakekall",
"panelRadius": "Panel",
"pause_on_unfocused": "Stopp henting av poster når vinduet ikke er i fokus",
"presets": "Forhåndsdefinerte tema",
diff --git a/src/i18n/nl.json b/src/i18n/nl.json
@@ -159,6 +159,11 @@
"no_rich_text_description": "Strip rich text formattering van alle posts",
"hide_network_description": "Toon niet wie mij volgt en wie ik volg.",
"nsfw_clickthrough": "Schakel doorklikbaar verbergen van NSFW bijlages in",
+ "oauth_tokens": "OAuth-tokens",
+ "token": "Token",
+ "refresh_token": "Token vernieuwen",
+ "valid_until": "Geldig tot",
+ "revoke_token": "Intrekken",
"panelRadius": "Panelen",
"pause_on_unfocused": "Pauzeer streamen wanneer de tab niet gefocused is",
"presets": "Presets",
diff --git a/src/i18n/oc.json b/src/i18n/oc.json
@@ -142,6 +142,7 @@
"notification_visibility_mentions": "Mencions",
"notification_visibility_repeats": "Repeticions",
"no_rich_text_description": "Netejar lo format tèxte de totas las publicacions",
+ "oauth_tokens": "Llistats OAuth",
"pause_on_unfocused": "Pausar la difusion quand l’onglet es pas seleccionat",
"profile_tab": "Perfil",
"replies_in_timeline": "Responsas del flux",
diff --git a/src/i18n/pl.json b/src/i18n/pl.json
@@ -86,6 +86,11 @@
"name_bio": "Imię i bio",
"new_password": "Nowe hasło",
"nsfw_clickthrough": "Włącz domyślne ukrywanie załączników o treści nieprzyzwoitej (NSFW)",
+ "oauth_tokens": "Tokeny OAuth",
+ "token": "Token",
+ "refresh_token": "Odśwież token",
+ "valid_until": "Ważne do",
+ "revoke_token": "Odwołać",
"panelRadius": "Panele",
"presets": "Gotowe motywy",
"profile_background": "Tło profilu",
diff --git a/src/i18n/ru.json b/src/i18n/ru.json
@@ -132,6 +132,11 @@
"show_admin_badge": "Показывать значок администратора в моем профиле",
"show_moderator_badge": "Показывать значок модератора в моем профиле",
"nsfw_clickthrough": "Включить скрытие NSFW вложений",
+ "oauth_tokens": "OAuth токены",
+ "token": "Токен",
+ "refresh_token": "Рефреш токен",
+ "valid_until": "Годен до",
+ "revoke_token": "Удалить",
"panelRadius": "Панели",
"pause_on_unfocused": "Приостановить загрузку когда вкладка не в фокусе",
"presets": "Пресеты",
diff --git a/src/i18n/zh.json b/src/i18n/zh.json
@@ -134,6 +134,11 @@
"notification_visibility_repeats": "转发",
"no_rich_text_description": "不显示富文本格式",
"nsfw_clickthrough": "将不和谐附件隐藏,点击才能打开",
+ "oauth_tokens": "OAuth令牌",
+ "token": "代币",
+ "refresh_token": "刷新令牌",
+ "valid_until": "有效期至",
+ "revoke_token": "撤消",
"panelRadius": "面板",
"pause_on_unfocused": "在离开页面时暂停时间线推送",
"presets": "预置",
diff --git a/src/main.js b/src/main.js
@@ -11,6 +11,7 @@ import configModule from './modules/config.js'
import chatModule from './modules/chat.js'
import oauthModule from './modules/oauth.js'
import mediaViewerModule from './modules/media_viewer.js'
+import oauthTokensModule from './modules/oauth_tokens.js'
import VueTimeago from 'vue-timeago'
import VueI18n from 'vue-i18n'
@@ -64,7 +65,8 @@ createPersistedState(persistedStateOptions).then((persistedState) => {
config: configModule,
chat: chatModule,
oauth: oauthModule,
- mediaViewer: mediaViewerModule
+ mediaViewer: mediaViewerModule,
+ oauthTokens: oauthTokensModule
},
plugins: [persistedState, pushNotifications],
strict: false // Socket modifies itself, let's ignore this for now.
diff --git a/src/modules/oauth_tokens.js b/src/modules/oauth_tokens.js
@@ -0,0 +1,26 @@
+const oauthTokens = {
+ state: {
+ tokens: []
+ },
+ actions: {
+ fetchTokens ({rootState, commit}) {
+ rootState.api.backendInteractor.fetchOAuthTokens().then((tokens) => {
+ commit('swapTokens', tokens)
+ })
+ },
+ revokeToken ({rootState, commit, state}, id) {
+ rootState.api.backendInteractor.revokeOAuthToken(id).then((response) => {
+ if (response.status === 201) {
+ commit('swapTokens', state.tokens.filter(token => token.id !== id))
+ }
+ })
+ }
+ },
+ mutations: {
+ swapTokens (state, tokens) {
+ state.tokens = tokens
+ }
+ }
+}
+
+export default oauthTokens
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
@@ -531,6 +531,23 @@ const fetchBlocks = ({page, credentials}) => {
})
}
+const fetchOAuthTokens = ({credentials}) => {
+ const url = '/api/oauth_tokens.json'
+
+ return fetch(url, {
+ headers: authHeaders(credentials)
+ }).then((data) => data.json())
+}
+
+const revokeOAuthToken = ({id, credentials}) => {
+ const url = `/api/oauth_tokens/${id}`
+
+ return fetch(url, {
+ headers: authHeaders(credentials),
+ method: 'DELETE'
+ })
+}
+
const suggestions = ({credentials}) => {
return fetch(SUGGESTIONS_URL, {
headers: authHeaders(credentials)
@@ -573,6 +590,8 @@ const apiService = {
setUserMute,
fetchMutes,
fetchBlocks,
+ fetchOAuthTokens,
+ revokeOAuthToken,
register,
getCaptcha,
updateAvatar,
diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js
@@ -65,6 +65,8 @@ const backendInteractorService = (credentials) => {
const fetchMutes = () => apiService.fetchMutes({credentials})
const fetchBlocks = (params) => apiService.fetchBlocks({credentials, ...params})
const fetchFollowRequests = () => apiService.fetchFollowRequests({credentials})
+ const fetchOAuthTokens = () => apiService.fetchOAuthTokens({credentials})
+ const revokeOAuthToken = (id) => apiService.revokeOAuthToken({id, credentials})
const getCaptcha = () => apiService.getCaptcha()
const register = (params) => apiService.register(params)
@@ -96,6 +98,8 @@ const backendInteractorService = (credentials) => {
setUserMute,
fetchMutes,
fetchBlocks,
+ fetchOAuthTokens,
+ revokeOAuthToken,
register,
getCaptcha,
updateAvatar,