refs #982 Add proxy configuration for all requests from main
This commit is contained in:
parent
296ec5c6c2
commit
a47fbbcf6a
|
@ -1,5 +1,5 @@
|
||||||
import { isEmpty } from 'lodash'
|
import { isEmpty } from 'lodash'
|
||||||
import Mastodon, { Account as RemoteAccount } from 'megalodon'
|
import Mastodon, { Account as RemoteAccount, ProxyConfig } from 'megalodon'
|
||||||
import Datastore from 'nedb'
|
import Datastore from 'nedb'
|
||||||
import log from 'electron-log'
|
import log from 'electron-log'
|
||||||
import { LocalAccount } from '~/src/types/localAccount'
|
import { LocalAccount } from '~/src/types/localAccount'
|
||||||
|
@ -275,14 +275,14 @@ export default class Account {
|
||||||
return updated
|
return updated
|
||||||
}
|
}
|
||||||
|
|
||||||
async refreshAccounts(): Promise<Array<LocalAccount>> {
|
async refreshAccounts(proxy: ProxyConfig | false): Promise<Array<LocalAccount>> {
|
||||||
const accounts = await this.listAccounts()
|
const accounts = await this.listAccounts()
|
||||||
if (accounts.length < 1) {
|
if (accounts.length < 1) {
|
||||||
return accounts
|
return accounts
|
||||||
}
|
}
|
||||||
const results = await Promise.all(
|
const results = await Promise.all(
|
||||||
accounts.map(async account => {
|
accounts.map(async account => {
|
||||||
const refresh = await this.refresh(account)
|
const refresh = await this.refresh(account, proxy)
|
||||||
return refresh
|
return refresh
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -294,8 +294,8 @@ export default class Account {
|
||||||
* @param {LocalAccount} account is an local account
|
* @param {LocalAccount} account is an local account
|
||||||
* @return {LocalAccount} updated account
|
* @return {LocalAccount} updated account
|
||||||
*/
|
*/
|
||||||
async refresh(account: LocalAccount): Promise<LocalAccount> {
|
async refresh(account: LocalAccount, proxy: ProxyConfig | false): Promise<LocalAccount> {
|
||||||
let client = new Mastodon(account.accessToken!, account.baseURL + '/api/v1')
|
let client = new Mastodon(account.accessToken!, account.baseURL + '/api/v1', 'Whalebird', proxy)
|
||||||
let json = {}
|
let json = {}
|
||||||
try {
|
try {
|
||||||
const res = await client.get<RemoteAccount>('/accounts/verify_credentials')
|
const res = await client.get<RemoteAccount>('/accounts/verify_credentials')
|
||||||
|
@ -311,8 +311,8 @@ export default class Account {
|
||||||
if (!account.refreshToken) {
|
if (!account.refreshToken) {
|
||||||
throw new RefreshTokenDoesNotExist()
|
throw new RefreshTokenDoesNotExist()
|
||||||
}
|
}
|
||||||
const token = await Mastodon.refreshToken(account.clientId, account.clientSecret, account.refreshToken, account.baseURL)
|
const token = await Mastodon.refreshToken(account.clientId, account.clientSecret, account.refreshToken, account.baseURL, proxy)
|
||||||
client = new Mastodon(token.access_token, account.baseURL + '/api/v1')
|
client = new Mastodon(token.access_token, account.baseURL + '/api/v1', 'Whalebird', proxy)
|
||||||
const res = await client.get<RemoteAccount>('/accounts/verify_credentials')
|
const res = await client.get<RemoteAccount>('/accounts/verify_credentials')
|
||||||
json = {
|
json = {
|
||||||
username: res.data.username,
|
username: res.data.username,
|
||||||
|
@ -326,8 +326,8 @@ export default class Account {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Confirm the access token, and check duplicate
|
// Confirm the access token, and check duplicate
|
||||||
async fetchAccount(account: LocalAccount, accessToken: string): Promise<RemoteAccount> {
|
async fetchAccount(account: LocalAccount, accessToken: string, proxy: ProxyConfig | false): Promise<RemoteAccount> {
|
||||||
const client = new Mastodon(accessToken, account.baseURL + '/api/v1')
|
const client = new Mastodon(accessToken, account.baseURL + '/api/v1', 'Whalebird', proxy)
|
||||||
const res = await client.get<RemoteAccount>('/accounts/verify_credentials')
|
const res = await client.get<RemoteAccount>('/accounts/verify_credentials')
|
||||||
const query = {
|
const query = {
|
||||||
baseURL: account.baseURL,
|
baseURL: account.baseURL,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Mastodon, { OAuth } from 'megalodon'
|
import Mastodon, { OAuth, ProxyConfig } from 'megalodon'
|
||||||
import Account from './account'
|
import Account from './account'
|
||||||
import { LocalAccount } from '~/src/types/localAccount'
|
import { LocalAccount } from '~/src/types/localAccount'
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ export default class Authentication {
|
||||||
this.clientSecret = ''
|
this.clientSecret = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAuthorizationUrl(domain = 'mastodon.social'): Promise<string> {
|
async getAuthorizationUrl(domain = 'mastodon.social', proxy: ProxyConfig | false): Promise<string> {
|
||||||
this.setOtherInstance(domain)
|
this.setOtherInstance(domain)
|
||||||
const res = await Mastodon.registerApp(
|
const res = await Mastodon.registerApp(
|
||||||
appName,
|
appName,
|
||||||
|
@ -38,7 +38,8 @@ export default class Authentication {
|
||||||
scopes: scope,
|
scopes: scope,
|
||||||
website: appURL
|
website: appURL
|
||||||
},
|
},
|
||||||
this.baseURL
|
this.baseURL,
|
||||||
|
proxy
|
||||||
)
|
)
|
||||||
this.clientId = res.clientId
|
this.clientId = res.clientId
|
||||||
this.clientSecret = res.clientSecret
|
this.clientSecret = res.clientSecret
|
||||||
|
@ -69,8 +70,15 @@ export default class Authentication {
|
||||||
return res.url
|
return res.url
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAccessToken(code: string): Promise<string> {
|
async getAccessToken(code: string, proxy: ProxyConfig | false): Promise<string> {
|
||||||
const tokenData: OAuth.TokenData = await Mastodon.fetchAccessToken(this.clientId, this.clientSecret, code, this.baseURL)
|
const tokenData: OAuth.TokenData = await Mastodon.fetchAccessToken(
|
||||||
|
this.clientId,
|
||||||
|
this.clientSecret,
|
||||||
|
code,
|
||||||
|
this.baseURL,
|
||||||
|
'urn:ietf:wg:oauth:2.0:oob',
|
||||||
|
proxy
|
||||||
|
)
|
||||||
const search = {
|
const search = {
|
||||||
baseURL: this.baseURL,
|
baseURL: this.baseURL,
|
||||||
domain: this.domain,
|
domain: this.domain,
|
||||||
|
@ -80,7 +88,7 @@ export default class Authentication {
|
||||||
const rec = await this.db.searchAccount(search)
|
const rec = await this.db.searchAccount(search)
|
||||||
const accessToken = tokenData.accessToken
|
const accessToken = tokenData.accessToken
|
||||||
const refreshToken = tokenData.refreshToken
|
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!, {
|
await this.db.updateAccount(rec._id!, {
|
||||||
username: data.username,
|
username: data.username,
|
||||||
accountId: data.id,
|
accountId: data.id,
|
||||||
|
|
|
@ -349,9 +349,10 @@ app.on('activate', () => {
|
||||||
|
|
||||||
let auth = new Authentication(accountManager)
|
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
|
auth
|
||||||
.getAuthorizationUrl(domain)
|
.getAuthorizationUrl(domain, proxy)
|
||||||
.then(url => {
|
.then(url => {
|
||||||
log.debug(url)
|
log.debug(url)
|
||||||
event.sender.send('response-get-auth-url', 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
|
auth
|
||||||
.getAccessToken(code)
|
.getAccessToken(code, proxy)
|
||||||
.then(token => {
|
.then(token => {
|
||||||
accountDB.findOne(
|
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
|
accountManager
|
||||||
.refresh(acct)
|
.refresh(acct, proxy)
|
||||||
.then(ac => {
|
.then(ac => {
|
||||||
event.sender.send('response-update-account', 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
|
accountManager
|
||||||
.refreshAccounts()
|
.refreshAccounts(proxy)
|
||||||
.then(accounts => {
|
.then(accounts => {
|
||||||
event.sender.send('response-refresh-accounts', accounts)
|
event.sender.send('response-refresh-accounts', accounts)
|
||||||
})
|
})
|
||||||
|
@ -523,7 +527,8 @@ ipcMain.on('start-all-user-streamings', (event: IpcMainEvent, accounts: Array<Lo
|
||||||
userStreamings[id]!.stop()
|
userStreamings[id]!.stop()
|
||||||
userStreamings[id] = null
|
userStreamings[id] = null
|
||||||
}
|
}
|
||||||
const url = await StreamingURL(acct)
|
const proxy = await proxyConfiguration.forMastodon()
|
||||||
|
const url = await StreamingURL(acct, proxy)
|
||||||
userStreamings[id] = new WebSocket(acct, url)
|
userStreamings[id] = new WebSocket(acct, url)
|
||||||
userStreamings[id]!.startUserStreaming(
|
userStreamings[id]!.startUserStreaming(
|
||||||
async (update: Status) => {
|
async (update: Status) => {
|
||||||
|
@ -633,8 +638,8 @@ ipcMain.on('start-directmessages-streaming', async (event: IpcMainEvent, obj: St
|
||||||
directMessagesStreaming.stop()
|
directMessagesStreaming.stop()
|
||||||
directMessagesStreaming = null
|
directMessagesStreaming = null
|
||||||
}
|
}
|
||||||
|
const proxy = await proxyConfiguration.forMastodon()
|
||||||
const url = await StreamingURL(acct)
|
const url = await StreamingURL(acct, proxy)
|
||||||
directMessagesStreaming = new WebSocket(acct, url)
|
directMessagesStreaming = new WebSocket(acct, url)
|
||||||
directMessagesStreaming.start(
|
directMessagesStreaming.start(
|
||||||
'direct',
|
'direct',
|
||||||
|
@ -682,8 +687,8 @@ ipcMain.on('start-local-streaming', async (event: IpcMainEvent, obj: StreamingSe
|
||||||
localStreaming.stop()
|
localStreaming.stop()
|
||||||
localStreaming = null
|
localStreaming = null
|
||||||
}
|
}
|
||||||
|
const proxy = await proxyConfiguration.forMastodon()
|
||||||
const url = await StreamingURL(acct)
|
const url = await StreamingURL(acct, proxy)
|
||||||
localStreaming = new WebSocket(acct, url)
|
localStreaming = new WebSocket(acct, url)
|
||||||
localStreaming.start(
|
localStreaming.start(
|
||||||
'public:local',
|
'public:local',
|
||||||
|
@ -731,8 +736,8 @@ ipcMain.on('start-public-streaming', async (event: IpcMainEvent, obj: StreamingS
|
||||||
publicStreaming.stop()
|
publicStreaming.stop()
|
||||||
publicStreaming = null
|
publicStreaming = null
|
||||||
}
|
}
|
||||||
|
const proxy = await proxyConfiguration.forMastodon()
|
||||||
const url = await StreamingURL(acct)
|
const url = await StreamingURL(acct, proxy)
|
||||||
publicStreaming = new WebSocket(acct, url)
|
publicStreaming = new WebSocket(acct, url)
|
||||||
publicStreaming.start(
|
publicStreaming.start(
|
||||||
'public',
|
'public',
|
||||||
|
@ -784,8 +789,8 @@ ipcMain.on('start-list-streaming', async (event: IpcMainEvent, obj: ListID & Str
|
||||||
listStreaming.stop()
|
listStreaming.stop()
|
||||||
listStreaming = null
|
listStreaming = null
|
||||||
}
|
}
|
||||||
|
const proxy = await proxyConfiguration.forMastodon()
|
||||||
const url = await StreamingURL(acct)
|
const url = await StreamingURL(acct, proxy)
|
||||||
listStreaming = new WebSocket(acct, url)
|
listStreaming = new WebSocket(acct, url)
|
||||||
listStreaming.start(
|
listStreaming.start(
|
||||||
`list&list=${listID}`,
|
`list&list=${listID}`,
|
||||||
|
@ -837,8 +842,8 @@ ipcMain.on('start-tag-streaming', async (event: IpcMainEvent, obj: Tag & Streami
|
||||||
tagStreaming.stop()
|
tagStreaming.stop()
|
||||||
tagStreaming = null
|
tagStreaming = null
|
||||||
}
|
}
|
||||||
|
const proxy = await proxyConfiguration.forMastodon()
|
||||||
const url = await StreamingURL(acct)
|
const url = await StreamingURL(acct, proxy)
|
||||||
tagStreaming = new WebSocket(acct, url)
|
tagStreaming = new WebSocket(acct, url)
|
||||||
tagStreaming.start(
|
tagStreaming.start(
|
||||||
`hashtag&tag=${tag}`,
|
`hashtag&tag=${tag}`,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { ProxyConfig } from 'megalodon'
|
||||||
import { ProxySource, ManualProxy, ProxyProtocol } from '~/src/types/proxy'
|
import { ProxySource, ManualProxy, ProxyProtocol } from '~/src/types/proxy'
|
||||||
import Preferences from './preferences'
|
import Preferences from './preferences'
|
||||||
|
|
||||||
|
@ -13,6 +14,35 @@ export default class ProxyConfiguration {
|
||||||
this.systemProxy = proxy
|
this.systemProxy = proxy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async forMastodon(): Promise<false | ProxyConfig> {
|
||||||
|
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<false | ManualProxy> {
|
public async getConfig(): Promise<false | ManualProxy> {
|
||||||
const conf = await this.preferences.get()
|
const conf = await this.preferences.get()
|
||||||
const source = conf.proxy.source as ProxySource
|
const source = conf.proxy.source as ProxySource
|
||||||
|
|
|
@ -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 log from 'electron-log'
|
||||||
import { LocalAccount } from '~/src/types/localAccount'
|
import { LocalAccount } from '~/src/types/localAccount'
|
||||||
|
|
||||||
const StreamingURL = async (account: LocalAccount): Promise<string> => {
|
const StreamingURL = async (account: LocalAccount, proxy: ProxyConfig | false): Promise<string> => {
|
||||||
if (!account.accessToken) {
|
if (!account.accessToken) {
|
||||||
throw new Error('access token is empty')
|
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<Instance> = await client.get<Instance>('/instance')
|
const res: Response<Instance> = await client.get<Instance>('/instance')
|
||||||
return res.data.urls.streaming_api
|
return res.data.urls.streaming_api
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,7 @@ const mutations: MutationTree<AppState> = {
|
||||||
state.hideAllAttachments = hideAllAttachments
|
state.hideAllAttachments = hideAllAttachments
|
||||||
},
|
},
|
||||||
[MUTATION_TYPES.UPDATE_PROXY_CONFIGURATION]: (state, proxy: ManualProxy | false) => {
|
[MUTATION_TYPES.UPDATE_PROXY_CONFIGURATION]: (state, proxy: ManualProxy | false) => {
|
||||||
|
// TODO: use src/main/proxy.ts#forMastodon
|
||||||
if (!proxy) {
|
if (!proxy) {
|
||||||
state.proxyConfiguration = false
|
state.proxyConfiguration = false
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue