Allow user to generate their access token from frontend #296
All checks were successful
ci/woodpecker/pr/woodpecker Pipeline was successful

This commit is contained in:
Mergan 2023-04-11 17:29:10 -07:00
parent 14cedc5ed1
commit 73d6469a28
3 changed files with 109 additions and 1 deletions

View file

@ -2,6 +2,7 @@ import ProgressButton from 'src/components/progress_button/progress_button.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue' import Checkbox from 'src/components/checkbox/checkbox.vue'
import Mfa from './mfa.vue' import Mfa from './mfa.vue'
import localeService from 'src/services/locale/locale.service.js' import localeService from 'src/services/locale/locale.service.js'
import oauth from 'src/services/new_api/oauth.js'
const SecurityTab = { const SecurityTab = {
data () { data () {
@ -24,7 +25,15 @@ const SecurityTab = {
listAliasesError: false, listAliasesError: false,
addAliasTarget: '', addAliasTarget: '',
addedAlias: false, addedAlias: false,
addAliasError: false addAliasError: false,
scopes: {
read: true,
write: false,
follow: false
},
clientId: '',
clientSecret: '',
accessToken: '',
} }
}, },
created () { created () {
@ -149,6 +158,49 @@ const SecurityTab = {
this.$store.dispatch('logout') this.$store.dispatch('logout')
this.$router.replace('/') 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) { revokeToken (id) {
if (window.confirm(`${this.$i18n.t('settings.revoke_token')}?`)) { if (window.confirm(`${this.$i18n.t('settings.revoke_token')}?`)) {
this.$store.dispatch('revokeToken', id) this.$store.dispatch('revokeToken', id)

View file

@ -101,6 +101,55 @@
</tr> </tr>
</tbody> </tbody>
</table> </table>
<h3>{{ $t('settings.generate_authentication') }}</h3>
<div>
<p>{{ $t('settings.client_name') }}</p>
<input
v-model="generateTokenAppName"
type="text"
>
</div>
<div>
<p>{{ $t('settings.scopes') }}</p>
<div
v-for="scope in Object.keys(scopes)"
:key="scope"
>
<Checkbox
:model-value="scopes[scope]"
@update:modelValue="scopes[scope] = $event"
>
{{ scope }}
</Checkbox>
</div>
</div>
<button
class="btn button-default"
@click="generateAuthentication"
>
{{ $t('settings.authenticate') }}
</button>
<div>
<p>{{ $t('settings.input_token') }}</p>
<input
v-model="inputToken"
type="text"
>
</div>
<button
class="btn button-default"
@click="generateToken"
>
{{ $t('settings.generate_token') }}
</button>
<div>
<p>{{ $t('settings.access_token') }}</p>
<input
v-model="accessToken"
type="text"
readonly
>
</div>
</div> </div>
<mfa /> <mfa />

View file

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