2020-03-15 09:47:40 +01:00
|
|
|
import generator, { ProxyConfig, detector } from 'megalodon'
|
2019-04-16 14:19:15 +02:00
|
|
|
import Account from './account'
|
2019-06-06 16:44:50 +02:00
|
|
|
import { LocalAccount } from '~/src/types/localAccount'
|
2018-03-08 09:41:39 +01:00
|
|
|
|
2018-05-15 16:13:52 +02:00
|
|
|
const appName = 'Whalebird'
|
2018-05-19 09:41:44 +02:00
|
|
|
const appURL = 'https://whalebird.org'
|
2020-03-15 09:47:40 +01:00
|
|
|
const scopes = ['read', 'write', 'follow']
|
2018-03-08 09:41:39 +01:00
|
|
|
|
|
|
|
export default class Authentication {
|
2019-04-16 14:19:15 +02:00
|
|
|
private db: Account
|
|
|
|
private baseURL: string
|
|
|
|
private domain: string
|
|
|
|
private clientId: string
|
|
|
|
private clientSecret: string
|
|
|
|
private protocol: 'http' | 'https'
|
|
|
|
|
2019-05-22 15:12:19 +02:00
|
|
|
constructor(accountDB: Account) {
|
2018-04-01 14:43:23 +02:00
|
|
|
this.db = accountDB
|
2018-03-08 16:24:18 +01:00
|
|
|
this.baseURL = ''
|
2018-03-10 16:48:40 +01:00
|
|
|
this.domain = ''
|
2018-03-08 09:41:39 +01:00
|
|
|
this.clientId = ''
|
|
|
|
this.clientSecret = ''
|
2018-03-10 16:48:40 +01:00
|
|
|
this.protocol = 'https'
|
2018-03-08 09:41:39 +01:00
|
|
|
}
|
|
|
|
|
2019-05-22 15:12:19 +02:00
|
|
|
setOtherInstance(domain: string) {
|
2018-03-10 16:48:40 +01:00
|
|
|
this.baseURL = `${this.protocol}://${domain}`
|
|
|
|
this.domain = domain
|
2018-03-08 16:24:18 +01:00
|
|
|
this.clientId = ''
|
|
|
|
this.clientSecret = ''
|
2018-03-08 16:33:43 +01:00
|
|
|
}
|
|
|
|
|
2019-10-27 09:22:44 +01:00
|
|
|
async getAuthorizationUrl(domain = 'mastodon.social', proxy: ProxyConfig | false): Promise<string> {
|
2018-03-10 16:48:40 +01:00
|
|
|
this.setOtherInstance(domain)
|
2020-03-15 09:47:40 +01:00
|
|
|
const sns = await detector(this.baseURL, proxy)
|
|
|
|
const client = generator(sns, this.baseURL, null, 'Whalebird', proxy)
|
|
|
|
const res = await client.registerApp(appName, {
|
|
|
|
scopes: scopes,
|
|
|
|
website: appURL
|
|
|
|
})
|
2018-06-09 13:42:12 +02:00
|
|
|
this.clientId = res.clientId
|
|
|
|
this.clientSecret = res.clientSecret
|
2018-03-08 09:41:39 +01:00
|
|
|
|
2019-05-22 15:12:19 +02:00
|
|
|
const order = await this.db
|
|
|
|
.lastAccount()
|
2018-10-11 16:12:22 +02:00
|
|
|
.then(account => account.order + 1)
|
2019-05-22 15:12:19 +02:00
|
|
|
.catch(err => {
|
2018-10-11 16:12:22 +02:00
|
|
|
console.log(err)
|
|
|
|
return 1
|
|
|
|
})
|
2019-04-16 14:19:15 +02:00
|
|
|
const local: LocalAccount = {
|
2018-04-01 14:58:57 +02:00
|
|
|
baseURL: this.baseURL,
|
|
|
|
domain: this.domain,
|
|
|
|
clientId: this.clientId,
|
|
|
|
clientSecret: this.clientSecret,
|
|
|
|
accessToken: '',
|
2019-05-22 15:52:40 +02:00
|
|
|
refreshToken: null,
|
2018-04-01 14:58:57 +02:00
|
|
|
username: '',
|
2019-04-16 14:19:15 +02:00
|
|
|
accountId: null,
|
2018-04-22 08:48:20 +02:00
|
|
|
avatar: '',
|
2018-10-11 16:12:22 +02:00
|
|
|
order: order
|
2018-04-01 14:58:57 +02:00
|
|
|
}
|
2019-04-16 14:19:15 +02:00
|
|
|
await this.db.insertAccount(local)
|
|
|
|
if (res.url === null) {
|
|
|
|
throw new AuthenticationURLError('Can not get url')
|
|
|
|
}
|
2018-06-09 13:42:12 +02:00
|
|
|
return res.url
|
2018-03-08 09:41:39 +01:00
|
|
|
}
|
|
|
|
|
2019-10-27 09:22:44 +01:00
|
|
|
async getAccessToken(code: string, proxy: ProxyConfig | false): Promise<string> {
|
2020-03-15 09:47:40 +01:00
|
|
|
const sns = await detector(this.baseURL, proxy)
|
|
|
|
const client = generator(sns, this.baseURL, null, 'Whalebird', proxy)
|
|
|
|
const tokenData = await client.fetchAccessToken(this.clientId, this.clientSecret, code, 'urn:ietf:wg:oauth:2.0:oob')
|
2018-04-01 14:58:57 +02:00
|
|
|
const search = {
|
|
|
|
baseURL: this.baseURL,
|
|
|
|
domain: this.domain,
|
|
|
|
clientId: this.clientId,
|
|
|
|
clientSecret: this.clientSecret
|
|
|
|
}
|
|
|
|
const rec = await this.db.searchAccount(search)
|
2018-10-20 13:38:38 +02:00
|
|
|
const accessToken = tokenData.accessToken
|
|
|
|
const refreshToken = tokenData.refreshToken
|
2020-03-15 09:47:40 +01:00
|
|
|
const data = await this.db.fetchAccount(sns, rec, accessToken, proxy)
|
2019-04-16 14:19:15 +02:00
|
|
|
await this.db.updateAccount(rec._id!, {
|
2018-06-12 01:48:01 +02:00
|
|
|
username: data.username,
|
|
|
|
accountId: data.id,
|
|
|
|
avatar: data.avatar,
|
2018-10-20 13:38:38 +02:00
|
|
|
accessToken: accessToken,
|
|
|
|
refreshToken: refreshToken
|
2018-06-12 01:48:01 +02:00
|
|
|
})
|
2018-06-09 13:42:12 +02:00
|
|
|
return accessToken
|
2018-03-08 09:41:39 +01:00
|
|
|
}
|
|
|
|
}
|
2019-04-16 14:19:15 +02:00
|
|
|
|
|
|
|
class AuthenticationURLError extends Error {}
|