From 73d6469a281b812345ce39e1959642d9fc3d2abc Mon Sep 17 00:00:00 2001 From: Mergan Date: Tue, 11 Apr 2023 17:29:10 -0700 Subject: [PATCH] Allow user to generate their access token from frontend #296 --- .../tabs/security_tab/security_tab.js | 54 ++++++++++++++++++- .../tabs/security_tab/security_tab.vue | 49 +++++++++++++++++ src/i18n/en.json | 7 +++ 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/src/components/settings_modal/tabs/security_tab/security_tab.js b/src/components/settings_modal/tabs/security_tab/security_tab.js index fc732936..8306af96 100644 --- a/src/components/settings_modal/tabs/security_tab/security_tab.js +++ b/src/components/settings_modal/tabs/security_tab/security_tab.js @@ -2,6 +2,7 @@ import ProgressButton from 'src/components/progress_button/progress_button.vue' import Checkbox from 'src/components/checkbox/checkbox.vue' import Mfa from './mfa.vue' import localeService from 'src/services/locale/locale.service.js' +import oauth from 'src/services/new_api/oauth.js' const SecurityTab = { data () { @@ -24,7 +25,15 @@ const SecurityTab = { listAliasesError: false, addAliasTarget: '', addedAlias: false, - addAliasError: false + addAliasError: false, + scopes: { + read: true, + write: false, + follow: false + }, + clientId: '', + clientSecret: '', + accessToken: '', } }, created () { @@ -149,6 +158,49 @@ const SecurityTab = { this.$store.dispatch('logout') this.$router.replace('/') }, + generateAuthentication () { + const url = `${this.$store.state.instance.server}/api/v1/apps` + const form = new window.FormData() + + form.append('client_name', this.generateTokenAppName) + form.append('redirect_uris', 'urn:ietf:wg:oauth:2.0:oob') + form.append('scopes', Object.keys(this.scopes) + .filter((key) => this.scopes[key] === true) + .join(' ') + ) + + return window.fetch(url, { + method: 'POST', + body: form + }) + .then((data) => data.json()) + .then((app) => ({ clientId: app.client_id, clientSecret: app.client_secret })) + .then((app) => this.$store.commit('setClientData', app) || app) + .then((app) => { + const authUrl = `${this.$store.state.instance.server}/oauth/authorize?client_id=${app.clientId}&response_type=code&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=${encodeURIComponent( + form.get('scopes') + )}`; + window.open(authUrl, '_blank', 'width=500,height=800'); + + this.clientId = app.clientId + this.clientSecret = app.clientSecret + }); + }, + generateToken () { + if (!this.clientId || !this.clientSecret) { + return + } + + oauth.getToken({ + clientId: this.clientId, + clientSecret: this.clientSecret, + instance: this.$store.state.instance.server, + code: this.inputToken + }).then((tokenData) => { + this.$store.dispatch('fetchTokens') + this.accessToken = tokenData.access_token + }) + }, revokeToken (id) { if (window.confirm(`${this.$i18n.t('settings.revoke_token')}?`)) { this.$store.dispatch('revokeToken', id) diff --git a/src/components/settings_modal/tabs/security_tab/security_tab.vue b/src/components/settings_modal/tabs/security_tab/security_tab.vue index c74a0c67..896880c1 100644 --- a/src/components/settings_modal/tabs/security_tab/security_tab.vue +++ b/src/components/settings_modal/tabs/security_tab/security_tab.vue @@ -101,6 +101,55 @@ +

{{ $t('settings.generate_authentication') }}

+
+

{{ $t('settings.client_name') }}

+ +
+
+

{{ $t('settings.scopes') }}

+
+ + {{ scope }} + +
+
+ +
+

{{ $t('settings.input_token') }}

+ +
+ +
+

{{ $t('settings.access_token') }}

+ +
diff --git a/src/i18n/en.json b/src/i18n/en.json index 92618047..6bbbf10b 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -455,6 +455,7 @@ }, "settings": { "accent": "Accent", + "access_token": "Access token", "account_alias": "Account aliases", "account_alias_table_head": "Alias", "account_backup": "Account backup", @@ -471,6 +472,7 @@ "app_name": "App name", "attachmentRadius": "Attachments", "attachments": "Attachments", + "authenticate": "Generate authentication token", "autohide_floating_post_button": "Automatically hide New Post button (mobile)", "avatar": "Avatar", "avatarAltRadius": "Avatars (notifications)", @@ -499,6 +501,7 @@ "changed_password": "Password changed successfully!", "chatMessageRadius": "Chat message", "checkboxRadius": "Checkboxes", + "client_name": "App name", "collapse_subject": "Collapse posts with content warnings", "columns": "Columns", "composing": "Composing", @@ -561,6 +564,8 @@ "foreground": "Foreground", "fun": "Fun", "general": "General", + "generate_authentication": "Generate authentication token", + "generate_token": "Generate token", "greentext": "Meme arrows", "hide_all_muted_posts": "Hide muted posts", "hide_attachments_in_convo": "Hide attachments in conversations", @@ -590,6 +595,7 @@ "import_mutes_from_a_csv_file": "Import mutes from a csv file", "import_theme": "Load preset", "inputRadius": "Input fields", + "input_token": "Enter the generated Token Code after authentication", "instance_default": "(default: {value})", "instance_default_simple": "(default)", "interface": "Interface", @@ -717,6 +723,7 @@ "save": "Save changes", "saving_err": "Error saving settings", "saving_ok": "Settings saved", + "scopes": "Scope permissions", "scope_copy": "Copy scope when replying (DMs are always copied)", "search_user_to_block": "Search whom you want to block", "search_user_to_mute": "Search whom you want to mute",