diff --git a/src/main/account.ts b/src/main/account.ts index 058665a8..849db67c 100644 --- a/src/main/account.ts +++ b/src/main/account.ts @@ -1,5 +1,5 @@ import { isEmpty } from 'lodash' -import Mastodon, { Account as RemoteAccount } from 'megalodon' +import Mastodon, { Account as RemoteAccount, ProxyConfig } from 'megalodon' import Datastore from 'nedb' import log from 'electron-log' import { LocalAccount } from '~/src/types/localAccount' @@ -275,14 +275,14 @@ export default class Account { return updated } - async refreshAccounts(): Promise> { + async refreshAccounts(proxy: ProxyConfig | false): Promise> { const accounts = await this.listAccounts() if (accounts.length < 1) { return accounts } const results = await Promise.all( accounts.map(async account => { - const refresh = await this.refresh(account) + const refresh = await this.refresh(account, proxy) return refresh }) ) @@ -294,8 +294,8 @@ export default class Account { * @param {LocalAccount} account is an local account * @return {LocalAccount} updated account */ - async refresh(account: LocalAccount): Promise { - let client = new Mastodon(account.accessToken!, account.baseURL + '/api/v1') + async refresh(account: LocalAccount, proxy: ProxyConfig | false): Promise { + let client = new Mastodon(account.accessToken!, account.baseURL + '/api/v1', 'Whalebird', proxy) let json = {} try { const res = await client.get('/accounts/verify_credentials') @@ -311,8 +311,8 @@ export default class Account { if (!account.refreshToken) { throw new RefreshTokenDoesNotExist() } - const token = await Mastodon.refreshToken(account.clientId, account.clientSecret, account.refreshToken, account.baseURL) - client = new Mastodon(token.access_token, account.baseURL + '/api/v1') + const token = await Mastodon.refreshToken(account.clientId, account.clientSecret, account.refreshToken, account.baseURL, proxy) + client = new Mastodon(token.access_token, account.baseURL + '/api/v1', 'Whalebird', proxy) const res = await client.get('/accounts/verify_credentials') json = { username: res.data.username, @@ -326,8 +326,8 @@ export default class Account { } // Confirm the access token, and check duplicate - async fetchAccount(account: LocalAccount, accessToken: string): Promise { - const client = new Mastodon(accessToken, account.baseURL + '/api/v1') + async fetchAccount(account: LocalAccount, accessToken: string, proxy: ProxyConfig | false): Promise { + const client = new Mastodon(accessToken, account.baseURL + '/api/v1', 'Whalebird', proxy) const res = await client.get('/accounts/verify_credentials') const query = { baseURL: account.baseURL, diff --git a/src/main/auth.ts b/src/main/auth.ts index 9fcbb64b..918ee667 100644 --- a/src/main/auth.ts +++ b/src/main/auth.ts @@ -1,4 +1,4 @@ -import Mastodon, { OAuth } from 'megalodon' +import Mastodon, { OAuth, ProxyConfig } from 'megalodon' import Account from './account' import { LocalAccount } from '~/src/types/localAccount' @@ -30,7 +30,7 @@ export default class Authentication { this.clientSecret = '' } - async getAuthorizationUrl(domain = 'mastodon.social'): Promise { + async getAuthorizationUrl(domain = 'mastodon.social', proxy: ProxyConfig | false): Promise { this.setOtherInstance(domain) const res = await Mastodon.registerApp( appName, @@ -38,7 +38,8 @@ export default class Authentication { scopes: scope, website: appURL }, - this.baseURL + this.baseURL, + proxy ) this.clientId = res.clientId this.clientSecret = res.clientSecret @@ -69,8 +70,15 @@ export default class Authentication { return res.url } - async getAccessToken(code: string): Promise { - const tokenData: OAuth.TokenData = await Mastodon.fetchAccessToken(this.clientId, this.clientSecret, code, this.baseURL) + async getAccessToken(code: string, proxy: ProxyConfig | false): Promise { + const tokenData: OAuth.TokenData = await Mastodon.fetchAccessToken( + this.clientId, + this.clientSecret, + code, + this.baseURL, + 'urn:ietf:wg:oauth:2.0:oob', + proxy + ) const search = { baseURL: this.baseURL, domain: this.domain, @@ -80,7 +88,7 @@ export default class Authentication { const rec = await this.db.searchAccount(search) const accessToken = tokenData.accessToken const refreshToken = tokenData.refreshToken - const data = await this.db.fetchAccount(rec, accessToken) + const data = await this.db.fetchAccount(rec, accessToken, proxy) await this.db.updateAccount(rec._id!, { username: data.username, accountId: data.id, diff --git a/src/main/index.ts b/src/main/index.ts index 646c574f..fbb77ca3 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -349,9 +349,10 @@ app.on('activate', () => { let auth = new Authentication(accountManager) -ipcMain.on('get-auth-url', (event: IpcMainEvent, domain: string) => { +ipcMain.on('get-auth-url', async (event: IpcMainEvent, domain: string) => { + const proxy = await proxyConfiguration.forMastodon() auth - .getAuthorizationUrl(domain) + .getAuthorizationUrl(domain, proxy) .then(url => { log.debug(url) event.sender.send('response-get-auth-url', url) @@ -364,9 +365,10 @@ ipcMain.on('get-auth-url', (event: IpcMainEvent, domain: string) => { }) }) -ipcMain.on('get-access-token', (event: IpcMainEvent, code: string) => { +ipcMain.on('get-access-token', async (event: IpcMainEvent, code: string) => { + const proxy = await proxyConfiguration.forMastodon() auth - .getAccessToken(code) + .getAccessToken(code, proxy) .then(token => { accountDB.findOne( { @@ -419,9 +421,10 @@ ipcMain.on('get-local-account', (event: IpcMainEvent, id: string) => { }) }) -ipcMain.on('update-account', (event: IpcMainEvent, acct: LocalAccount) => { +ipcMain.on('update-account', async (event: IpcMainEvent, acct: LocalAccount) => { + const proxy = await proxyConfiguration.forMastodon() accountManager - .refresh(acct) + .refresh(acct, proxy) .then(ac => { event.sender.send('response-update-account', ac) }) @@ -465,9 +468,10 @@ ipcMain.on('backward-account', (event: IpcMainEvent, acct: LocalAccount) => { }) }) -ipcMain.on('refresh-accounts', (event: IpcMainEvent) => { +ipcMain.on('refresh-accounts', async (event: IpcMainEvent) => { + const proxy = await proxyConfiguration.forMastodon() accountManager - .refreshAccounts() + .refreshAccounts(proxy) .then(accounts => { event.sender.send('response-refresh-accounts', accounts) }) @@ -523,7 +527,8 @@ ipcMain.on('start-all-user-streamings', (event: IpcMainEvent, accounts: Array { @@ -633,8 +638,8 @@ ipcMain.on('start-directmessages-streaming', async (event: IpcMainEvent, obj: St directMessagesStreaming.stop() directMessagesStreaming = null } - - const url = await StreamingURL(acct) + const proxy = await proxyConfiguration.forMastodon() + const url = await StreamingURL(acct, proxy) directMessagesStreaming = new WebSocket(acct, url) directMessagesStreaming.start( 'direct', @@ -682,8 +687,8 @@ ipcMain.on('start-local-streaming', async (event: IpcMainEvent, obj: StreamingSe localStreaming.stop() localStreaming = null } - - const url = await StreamingURL(acct) + const proxy = await proxyConfiguration.forMastodon() + const url = await StreamingURL(acct, proxy) localStreaming = new WebSocket(acct, url) localStreaming.start( 'public:local', @@ -731,8 +736,8 @@ ipcMain.on('start-public-streaming', async (event: IpcMainEvent, obj: StreamingS publicStreaming.stop() publicStreaming = null } - - const url = await StreamingURL(acct) + const proxy = await proxyConfiguration.forMastodon() + const url = await StreamingURL(acct, proxy) publicStreaming = new WebSocket(acct, url) publicStreaming.start( 'public', @@ -784,8 +789,8 @@ ipcMain.on('start-list-streaming', async (event: IpcMainEvent, obj: ListID & Str listStreaming.stop() listStreaming = null } - - const url = await StreamingURL(acct) + const proxy = await proxyConfiguration.forMastodon() + const url = await StreamingURL(acct, proxy) listStreaming = new WebSocket(acct, url) listStreaming.start( `list&list=${listID}`, @@ -837,8 +842,8 @@ ipcMain.on('start-tag-streaming', async (event: IpcMainEvent, obj: Tag & Streami tagStreaming.stop() tagStreaming = null } - - const url = await StreamingURL(acct) + const proxy = await proxyConfiguration.forMastodon() + const url = await StreamingURL(acct, proxy) tagStreaming = new WebSocket(acct, url) tagStreaming.start( `hashtag&tag=${tag}`, diff --git a/src/main/proxy.ts b/src/main/proxy.ts index 2d5c4f7e..19eaa842 100644 --- a/src/main/proxy.ts +++ b/src/main/proxy.ts @@ -1,3 +1,4 @@ +import { ProxyConfig } from 'megalodon' import { ProxySource, ManualProxy, ProxyProtocol } from '~/src/types/proxy' import Preferences from './preferences' @@ -13,6 +14,35 @@ export default class ProxyConfiguration { this.systemProxy = proxy } + public async forMastodon(): Promise { + const proxy = await this.getConfig() + if (!proxy) { + return false + } else { + let protocol = ProxyProtocol.http + if (proxy.protocol !== '') { + protocol = proxy.protocol + } + if (proxy.username.length > 0) { + return { + host: proxy.host, + port: parseInt(proxy.port, 10), + protocol: protocol, + auth: { + username: proxy.username, + password: proxy.password + } + } + } else { + return { + host: proxy.host, + port: parseInt(proxy.port, 10), + protocol: protocol + } + } + } + } + public async getConfig(): Promise { const conf = await this.preferences.get() const source = conf.proxy.source as ProxySource diff --git a/src/main/websocket.ts b/src/main/websocket.ts index 42f035d3..1837f1a7 100644 --- a/src/main/websocket.ts +++ b/src/main/websocket.ts @@ -1,12 +1,12 @@ -import Mastodon, { WebSocket as SocketListener, Status, Notification, Instance, Response } from 'megalodon' +import Mastodon, { WebSocket as SocketListener, Status, Notification, Instance, Response, ProxyConfig } from 'megalodon' import log from 'electron-log' import { LocalAccount } from '~/src/types/localAccount' -const StreamingURL = async (account: LocalAccount): Promise => { +const StreamingURL = async (account: LocalAccount, proxy: ProxyConfig | false): Promise => { if (!account.accessToken) { throw new Error('access token is empty') } - const client = new Mastodon(account.accessToken, account.baseURL + '/api/v1') + const client = new Mastodon(account.accessToken, account.baseURL + '/api/v1', 'Whalebird', proxy) const res: Response = await client.get('/instance') return res.data.urls.streaming_api } diff --git a/src/renderer/store/App.ts b/src/renderer/store/App.ts index a690f376..7b9127d0 100644 --- a/src/renderer/store/App.ts +++ b/src/renderer/store/App.ts @@ -102,6 +102,7 @@ const mutations: MutationTree = { state.hideAllAttachments = hideAllAttachments }, [MUTATION_TYPES.UPDATE_PROXY_CONFIGURATION]: (state, proxy: ManualProxy | false) => { + // TODO: use src/main/proxy.ts#forMastodon if (!proxy) { state.proxyConfiguration = false } else {