import { getAccessTokenFromAuthCode, registerApplication, generateAuthLink } from '../_api/oauth' import { getInstanceInfo } from '../_api/instance' import { goto } from 'sapper/runtime.js' import { switchToTheme } from '../_utils/themeEngine' import { store } from '../_store/store' import { updateVerifyCredentialsForInstance } from './instances' import { updateCustomEmojiForInstance } from './emoji' import { setInstanceInfo as setInstanceInfoInDatabase } from '../_database/meta' const REDIRECT_URI = (typeof location !== 'undefined' ? location.origin : 'https://pinafore.social') + '/settings/instances/add' async function redirectToOauth () { let instanceName = store.get('instanceNameInSearch') let loggedInInstances = store.get('loggedInInstances') instanceName = instanceName.replace(/^https?:\/\//, '').replace(/\/$/, '').replace('/$', '').toLowerCase() 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 setInstanceInfoInDatabase(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, logInToInstanceError: null }) try { await redirectToOauth() } catch (err) { console.error(err) let error = `${err.message || err.name}. ` + (navigator.onLine ? `Is this a valid Mastodon instance? Is a browser extension blocking the request?` : `Are you offline?`) store.set({ logInToInstanceError: error, logInToInstanceErrorForText: store.get('instanceNameInSearch') }) } 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 these requests so they're cached /* no await */ updateVerifyCredentialsForInstance(currentRegisteredInstanceName) /* no await */ updateCustomEmojiForInstance(currentRegisteredInstanceName) 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}) } }