refactor
This commit is contained in:
parent
537071d00e
commit
94e06ca7f8
105
routes/settings/instances/_actions/add.js
Normal file
105
routes/settings/instances/_actions/add.js
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
import { getAccessTokenFromAuthCode, registerApplication, generateAuthLink } from '../../../_utils/mastodon/oauth'
|
||||||
|
import { getVerifyCredentials } from '../../../_utils/mastodon/user'
|
||||||
|
import { getInstanceInfo } from '../../../_utils/mastodon/instance'
|
||||||
|
import { goto } from 'sapper/runtime.js'
|
||||||
|
import { switchToTheme } from '../../../_utils/themeEngine'
|
||||||
|
import { database } from '../../../_utils/database/database'
|
||||||
|
import { store } from '../../../_utils/store'
|
||||||
|
|
||||||
|
const REDIRECT_URI = (typeof location !== 'undefined' ?
|
||||||
|
location.origin : 'https://pinafore.social') + '/settings/instances/add'
|
||||||
|
|
||||||
|
store.onchange((state, changed) => {
|
||||||
|
if (changed['instanceNameInSearch']) {
|
||||||
|
store.set({logInToInstanceError: false})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
async function redirectToOauth() {
|
||||||
|
let instanceName = store.get('instanceNameInSearch')
|
||||||
|
let loggedInInstances = store.get('loggedInInstances')
|
||||||
|
instanceName = instanceName.replace(/^https?:\/\//, '').replace('/$', '')
|
||||||
|
if (Object.keys(loggedInInstances).includes(instanceName)) {
|
||||||
|
store.set({logInToInstanceError: `You've already logged in to ${instanceName}`})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let registrationPromise = registerApplication(instanceName, REDIRECT_URI)
|
||||||
|
let instanceInfo = await getInstanceInfo(instanceName)
|
||||||
|
await database.setInstanceInfo(instanceName, instanceInfo) // cache for later
|
||||||
|
let instanceData = await registrationPromise
|
||||||
|
store.set({
|
||||||
|
currentRegisteredInstanceName: instanceName,
|
||||||
|
currentRegisteredInstance: instanceData
|
||||||
|
})
|
||||||
|
store.save()
|
||||||
|
let oauthUrl = generateAuthLink(
|
||||||
|
instanceName,
|
||||||
|
instanceData.client_id,
|
||||||
|
REDIRECT_URI
|
||||||
|
)
|
||||||
|
document.location.href = oauthUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function logInToInstance() {
|
||||||
|
store.set({logInToInstanceLoading: true})
|
||||||
|
try {
|
||||||
|
await redirectToOauth()
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
let error = `${err.message || err.name}. ` +
|
||||||
|
(navigator.onLine ?
|
||||||
|
`Is this a valid Mastodon instance?` :
|
||||||
|
`Are you offline?`)
|
||||||
|
store.set({logInToInstanceError: error})
|
||||||
|
} finally {
|
||||||
|
store.set({logInToInstanceLoading: false})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function registerNewInstance(code) {
|
||||||
|
let currentRegisteredInstanceName = store.get('currentRegisteredInstanceName')
|
||||||
|
let currentRegisteredInstance = store.get('currentRegisteredInstance')
|
||||||
|
let instanceData = await getAccessTokenFromAuthCode(
|
||||||
|
currentRegisteredInstanceName,
|
||||||
|
currentRegisteredInstance.client_id,
|
||||||
|
currentRegisteredInstance.client_secret,
|
||||||
|
code,
|
||||||
|
REDIRECT_URI
|
||||||
|
)
|
||||||
|
let loggedInInstances = store.get('loggedInInstances')
|
||||||
|
let loggedInInstancesInOrder = store.get('loggedInInstancesInOrder')
|
||||||
|
let instanceThemes = store.get('instanceThemes')
|
||||||
|
instanceThemes[currentRegisteredInstanceName] = 'default'
|
||||||
|
loggedInInstances[currentRegisteredInstanceName] = instanceData
|
||||||
|
if (!loggedInInstancesInOrder.includes(currentRegisteredInstanceName)) {
|
||||||
|
loggedInInstancesInOrder.push(currentRegisteredInstanceName)
|
||||||
|
}
|
||||||
|
store.set({
|
||||||
|
instanceNameInSearch: '',
|
||||||
|
currentRegisteredInstanceName: null,
|
||||||
|
currentRegisteredInstance: null,
|
||||||
|
loggedInInstances: loggedInInstances,
|
||||||
|
currentInstance: currentRegisteredInstanceName,
|
||||||
|
loggedInInstancesInOrder: loggedInInstancesInOrder,
|
||||||
|
instanceThemes: instanceThemes
|
||||||
|
})
|
||||||
|
store.save()
|
||||||
|
switchToTheme('default')
|
||||||
|
// fire off request for account so it's cached
|
||||||
|
getVerifyCredentials(currentRegisteredInstanceName, instanceData.access_token).then(verifyCredentials => {
|
||||||
|
database.setInstanceVerifyCredentials(currentRegisteredInstanceName, verifyCredentials)
|
||||||
|
})
|
||||||
|
goto('/')
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function handleOauthCode(code) {
|
||||||
|
try {
|
||||||
|
store.set({logInToInstanceLoading: true})
|
||||||
|
await registerNewInstance(code)
|
||||||
|
} catch (err) {
|
||||||
|
store.set({logInToInstanceError: `${err.message || err.name}. Failed to connect to instance.`})
|
||||||
|
} finally {
|
||||||
|
store.set({logInToInstanceLoading: false})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<SettingsLayout page='settings/instances/add' label="Add an Instance">
|
<SettingsLayout page='settings/instances/add' label="Add an Instance">
|
||||||
<h1 id="add-an-instance-h1">Add an Instance</h1>
|
<h1 id="add-an-instance-h1">Add an Instance</h1>
|
||||||
|
|
||||||
<LoadingMask show="{{loading}}"/>
|
<LoadingMask show="{{$logInToInstanceLoading}}"/>
|
||||||
|
|
||||||
{{#if $isUserLoggedIn}}
|
{{#if $isUserLoggedIn}}
|
||||||
<p>Connect to an instance to log in.</p>
|
<p>Connect to an instance to log in.</p>
|
||||||
|
@ -16,9 +16,9 @@
|
||||||
|
|
||||||
<form class="add-new-instance" on:submit='onSubmit(event)' aria-labelledby="add-an-instance-h1">
|
<form class="add-new-instance" on:submit='onSubmit(event)' aria-labelledby="add-an-instance-h1">
|
||||||
|
|
||||||
{{#if error}}
|
{{#if $logInToInstanceError}}
|
||||||
<div class="form-error" role="alert">
|
<div class="form-error" role="alert">
|
||||||
Error: {{error}}
|
Error: {{$logInToInstanceError}}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
@ -70,27 +70,16 @@
|
||||||
<script>
|
<script>
|
||||||
import Layout from '../../_components/Layout.html';
|
import Layout from '../../_components/Layout.html';
|
||||||
import SettingsLayout from '../_components/SettingsLayout.html'
|
import SettingsLayout from '../_components/SettingsLayout.html'
|
||||||
import { registerApplication, generateAuthLink, getAccessTokenFromAuthCode } from '../../_utils/mastodon/oauth'
|
|
||||||
import { getVerifyCredentials } from '../../_utils/mastodon/user'
|
|
||||||
import { getInstanceInfo } from '../../_utils/mastodon/instance'
|
|
||||||
import { store } from '../../_utils/store'
|
import { store } from '../../_utils/store'
|
||||||
import { goto } from 'sapper/runtime.js'
|
|
||||||
import { switchToTheme } from '../../_utils/themeEngine'
|
|
||||||
import LoadingMask from '../../_components/LoadingMask'
|
import LoadingMask from '../../_components/LoadingMask'
|
||||||
import { database } from '../../_utils/database/database'
|
import { logInToInstance, handleOauthCode } from './_actions/add'
|
||||||
|
|
||||||
const REDIRECT_URI = (typeof location !== 'undefined' ?
|
|
||||||
location.origin : 'https://pinafore.social') + '/settings/instances/add'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
async oncreate () {
|
async oncreate () {
|
||||||
let params = new URLSearchParams(location.search)
|
let params = new URLSearchParams(location.search)
|
||||||
if (params.has('code')) {
|
if (params.has('code')) {
|
||||||
this.onReceivedOauthCode(params.get('code'))
|
handleOauthCode(params.get('code'))
|
||||||
}
|
}
|
||||||
this.store.observe('instanceNameInSearch', () => {
|
|
||||||
this.set({error: false})
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Layout,
|
Layout,
|
||||||
|
@ -99,90 +88,9 @@
|
||||||
},
|
},
|
||||||
store: () => store,
|
store: () => store,
|
||||||
methods: {
|
methods: {
|
||||||
onSubmit: async function(event) {
|
onSubmit(event) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
this.set({loading: true})
|
logInToInstance()
|
||||||
try {
|
|
||||||
await this.redirectToOauth()
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err)
|
|
||||||
let error = `${err.message || err.name}. ` +
|
|
||||||
(navigator.onLine ?
|
|
||||||
`Is this a valid Mastodon instance?` :
|
|
||||||
`Are you offline?`)
|
|
||||||
this.set({error: error})
|
|
||||||
} finally {
|
|
||||||
this.set({loading: false})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
redirectToOauth: async function() {
|
|
||||||
let instanceName = this.store.get('instanceNameInSearch')
|
|
||||||
let loggedInInstances = this.store.get('loggedInInstances')
|
|
||||||
instanceName = instanceName.replace(/^https?:\/\//, '').replace('/$', '')
|
|
||||||
if (Object.keys(loggedInInstances).includes(instanceName)) {
|
|
||||||
this.set({error: `You've already logged in to ${instanceName}`})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let registrationPromise = registerApplication(instanceName, REDIRECT_URI)
|
|
||||||
let instanceInfo = await getInstanceInfo(instanceName)
|
|
||||||
await database.setInstanceInfo(instanceName, instanceInfo) // cache for later
|
|
||||||
let instanceData = await registrationPromise
|
|
||||||
this.store.set({
|
|
||||||
currentRegisteredInstanceName: instanceName,
|
|
||||||
currentRegisteredInstance: instanceData
|
|
||||||
})
|
|
||||||
this.store.save()
|
|
||||||
let oauthUrl = generateAuthLink(
|
|
||||||
instanceName,
|
|
||||||
instanceData.client_id,
|
|
||||||
REDIRECT_URI
|
|
||||||
)
|
|
||||||
document.location.href = oauthUrl
|
|
||||||
},
|
|
||||||
onReceivedOauthCode: async function(code) {
|
|
||||||
try {
|
|
||||||
this.set({loading: true})
|
|
||||||
await this.registerNewInstance(code)
|
|
||||||
} catch (err) {
|
|
||||||
this.set({error: `${err.message || err.name}. Failed to connect to instance.`})
|
|
||||||
} finally {
|
|
||||||
this.set({loading: false})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
registerNewInstance: async function (code) {
|
|
||||||
let currentRegisteredInstanceName = this.store.get('currentRegisteredInstanceName')
|
|
||||||
let currentRegisteredInstance = this.store.get('currentRegisteredInstance')
|
|
||||||
let instanceData = await getAccessTokenFromAuthCode(
|
|
||||||
currentRegisteredInstanceName,
|
|
||||||
currentRegisteredInstance.client_id,
|
|
||||||
currentRegisteredInstance.client_secret,
|
|
||||||
code,
|
|
||||||
REDIRECT_URI
|
|
||||||
)
|
|
||||||
let loggedInInstances = this.store.get('loggedInInstances')
|
|
||||||
let loggedInInstancesInOrder = this.store.get('loggedInInstancesInOrder')
|
|
||||||
let instanceThemes = this.store.get('instanceThemes')
|
|
||||||
instanceThemes[currentRegisteredInstanceName] = 'default'
|
|
||||||
loggedInInstances[currentRegisteredInstanceName] = instanceData
|
|
||||||
if (!loggedInInstancesInOrder.includes(currentRegisteredInstanceName)) {
|
|
||||||
loggedInInstancesInOrder.push(currentRegisteredInstanceName)
|
|
||||||
}
|
|
||||||
this.store.set({
|
|
||||||
instanceNameInSearch: '',
|
|
||||||
currentRegisteredInstanceName: null,
|
|
||||||
currentRegisteredInstance: null,
|
|
||||||
loggedInInstances: loggedInInstances,
|
|
||||||
currentInstance: currentRegisteredInstanceName,
|
|
||||||
loggedInInstancesInOrder: loggedInInstancesInOrder,
|
|
||||||
instanceThemes: instanceThemes
|
|
||||||
})
|
|
||||||
this.store.save()
|
|
||||||
switchToTheme('default')
|
|
||||||
// fire off request for account so it's cached
|
|
||||||
getVerifyCredentials(currentRegisteredInstanceName, instanceData.access_token).then(verifyCredentials => {
|
|
||||||
database.setInstanceVerifyCredentials(currentRegisteredInstanceName, verifyCredentials)
|
|
||||||
})
|
|
||||||
goto('/')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue