Merge pull request #175 from h3poteto/iss-174
closes #174 Save account username in local db
This commit is contained in:
commit
9ed309ec1b
@ -5,6 +5,16 @@ export default class Account {
|
|||||||
this.db = db
|
this.db = db
|
||||||
}
|
}
|
||||||
|
|
||||||
|
insertAccount (obj) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.db.insert(obj, (err, doc) => {
|
||||||
|
if (err) return reject(err)
|
||||||
|
if (empty(doc)) return reject(new EmptyRecordError('empty'))
|
||||||
|
resolve(doc)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
listAccounts () {
|
listAccounts () {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.db.find({accessToken: { $ne: '' }}, (err, docs) => {
|
this.db.find({accessToken: { $ne: '' }}, (err, docs) => {
|
||||||
@ -29,6 +39,42 @@ export default class Account {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
searchAccount (obj) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.db.findOne(
|
||||||
|
obj,
|
||||||
|
(err, doc) => {
|
||||||
|
if (err) return reject(err)
|
||||||
|
if (empty(doc)) return reject(new EmptyRecordError('empty'))
|
||||||
|
resolve(doc)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
updateAccount (id, obj) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.db.update(
|
||||||
|
{
|
||||||
|
_id: id
|
||||||
|
},
|
||||||
|
{ $set: Object.assign(obj, { _id: id }) },
|
||||||
|
{ multi: true },
|
||||||
|
(err, numReplaced) => {
|
||||||
|
if (err) return reject(err)
|
||||||
|
this.db.findOne(
|
||||||
|
{
|
||||||
|
_id: id
|
||||||
|
},
|
||||||
|
(err, doc) => {
|
||||||
|
if (err) return reject(err)
|
||||||
|
if (empty(doc)) return reject(new EmptyRecordError('empty'))
|
||||||
|
resolve(doc)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EmptyRecordError {
|
class EmptyRecordError {
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import Mastodon from 'mastodon-api'
|
import Mastodon from 'mastodon-api'
|
||||||
import log from 'electron-log'
|
|
||||||
|
|
||||||
const appName = 'whalebird'
|
const appName = 'whalebird'
|
||||||
const scope = 'read write follow'
|
const scope = 'read write follow'
|
||||||
|
|
||||||
export default class Authentication {
|
export default class Authentication {
|
||||||
constructor (db) {
|
constructor (accountDB) {
|
||||||
this.db = db
|
this.db = accountDB
|
||||||
this.baseURL = ''
|
this.baseURL = ''
|
||||||
this.domain = ''
|
this.domain = ''
|
||||||
this.clientId = ''
|
this.clientId = ''
|
||||||
@ -21,46 +20,38 @@ export default class Authentication {
|
|||||||
this.clientSecret = ''
|
this.clientSecret = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
getAuthorizationUrl (domain = 'mastodon.social') {
|
async getAuthorizationUrl (domain = 'mastodon.social') {
|
||||||
this.setOtherInstance(domain)
|
this.setOtherInstance(domain)
|
||||||
return Mastodon.createOAuthApp(this.baseURL + '/api/v1/apps', appName, scope)
|
const res = await Mastodon.createOAuthApp(this.baseURL + '/api/v1/apps', appName, scope)
|
||||||
.catch(err => log.error(err))
|
|
||||||
.then((res) => {
|
|
||||||
this.clientId = res.client_id
|
this.clientId = res.client_id
|
||||||
this.clientSecret = res.client_secret
|
this.clientSecret = res.client_secret
|
||||||
|
|
||||||
|
// TODO: Save order number
|
||||||
const json = {
|
const json = {
|
||||||
baseURL: this.baseURL,
|
baseURL: this.baseURL,
|
||||||
domain: this.domain,
|
domain: this.domain,
|
||||||
clientId: this.clientId,
|
clientId: this.clientId,
|
||||||
clientSecret: this.clientSecret,
|
clientSecret: this.clientSecret,
|
||||||
accessToken: ''
|
accessToken: '',
|
||||||
|
username: '',
|
||||||
|
accountId: ''
|
||||||
}
|
}
|
||||||
this.db.insert(json, (err, _) => {
|
await this.db.insertAccount(json)
|
||||||
if (err) throw err
|
const url = await Mastodon.getAuthorizationUrl(this.clientId, this.clientSecret, this.baseURL)
|
||||||
})
|
return url
|
||||||
|
|
||||||
return Mastodon.getAuthorizationUrl(this.clientId, this.clientSecret, this.baseURL)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getAccessToken (code) {
|
async getAccessToken (code) {
|
||||||
return new Promise((resolve, reject) => {
|
const token = await Mastodon.getAccessToken(this.clientId, this.clientSecret, code, this.baseURL)
|
||||||
Mastodon.getAccessToken(this.clientId, this.clientSecret, code, this.baseURL)
|
|
||||||
.catch(err => reject(err))
|
|
||||||
.then((token) => {
|
|
||||||
const search = {
|
const search = {
|
||||||
baseURL: this.baseURL,
|
baseURL: this.baseURL,
|
||||||
domain: this.domain,
|
domain: this.domain,
|
||||||
clientId: this.clientId,
|
clientId: this.clientId,
|
||||||
clientSecret: this.clientSecret
|
clientSecret: this.clientSecret
|
||||||
}
|
}
|
||||||
this.db.update(search, {$set: { accessToken: token }}, {}, (err, num) => {
|
const rec = await this.db.searchAccount(search)
|
||||||
if (err) return reject(err)
|
await this.db.updateAccount(rec._id, { accessToken: token })
|
||||||
resolve(token)
|
return token
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
// TODO: Refresh access token when expired
|
// TODO: Refresh access token when expired
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,8 @@ const winURL = process.env.NODE_ENV === 'development'
|
|||||||
// https://github.com/louischatriot/nedb/issues/459
|
// https://github.com/louischatriot/nedb/issues/459
|
||||||
const userData = app.getPath('userData')
|
const userData = app.getPath('userData')
|
||||||
const databasePath = process.env.NODE_ENV === 'production'
|
const databasePath = process.env.NODE_ENV === 'production'
|
||||||
? userData + '/db/whalebird.db'
|
? userData + '/db/account.db'
|
||||||
: 'whalebird.db'
|
: 'account.db'
|
||||||
let db = new Datastore({
|
let db = new Datastore({
|
||||||
filename: databasePath,
|
filename: databasePath,
|
||||||
autoload: true
|
autoload: true
|
||||||
@ -208,20 +208,20 @@ app.on('activate', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
let auth = new Authentication(db)
|
let auth = new Authentication(new Account(db))
|
||||||
|
|
||||||
ipcMain.on('get-auth-url', (event, domain) => {
|
ipcMain.on('get-auth-url', (event, domain) => {
|
||||||
auth.getAuthorizationUrl(domain)
|
auth.getAuthorizationUrl(domain)
|
||||||
.catch((err) => {
|
|
||||||
log.error(err)
|
|
||||||
event.sender.send('error-get-auth-url', err)
|
|
||||||
})
|
|
||||||
.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)
|
||||||
// Open authorize url in default browser.
|
// Open authorize url in default browser.
|
||||||
shell.openExternal(url)
|
shell.openExternal(url)
|
||||||
})
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
log.error(err)
|
||||||
|
event.sender.send('error-get-auth-url', err)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.on('get-access-token', (event, code) => {
|
ipcMain.on('get-access-token', (event, code) => {
|
||||||
@ -275,6 +275,19 @@ ipcMain.on('get-local-account', (event, id) => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ipcMain.on('update-account', (event, acct) => {
|
||||||
|
const account = new Account(db)
|
||||||
|
const id = acct._id
|
||||||
|
delete acct._id
|
||||||
|
account.updateAccount(id, acct)
|
||||||
|
.then((ac) => {
|
||||||
|
event.sender.send('response-update-account', ac)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
event.sender.send('error-update-account', err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
// streaming
|
// streaming
|
||||||
let userStreaming = null
|
let userStreaming = null
|
||||||
|
|
||||||
|
@ -41,7 +41,6 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
async clear () {
|
async clear () {
|
||||||
await this.$store.dispatch('TimelineSpace/clearAccount')
|
await this.$store.dispatch('TimelineSpace/clearAccount')
|
||||||
await this.$store.dispatch('TimelineSpace/clearUsername')
|
|
||||||
await this.$store.dispatch('TimelineSpace/clearTimeline')
|
await this.$store.dispatch('TimelineSpace/clearTimeline')
|
||||||
await this.$store.dispatch('TimelineSpace/clearNotifications')
|
await this.$store.dispatch('TimelineSpace/clearNotifications')
|
||||||
await this.$store.dispatch('TimelineSpace/removeShortcutEvents')
|
await this.$store.dispatch('TimelineSpace/removeShortcutEvents')
|
||||||
@ -52,7 +51,7 @@ export default {
|
|||||||
|
|
||||||
this.$store.dispatch('TimelineSpace/watchShortcutEvents')
|
this.$store.dispatch('TimelineSpace/watchShortcutEvents')
|
||||||
try {
|
try {
|
||||||
const account = await this.$store.dispatch('TimelineSpace/fetchAccount', this.$route.params.id)
|
const account = await this.$store.dispatch('TimelineSpace/localAccount', this.$route.params.id)
|
||||||
try {
|
try {
|
||||||
await this.$store.dispatch('TimelineSpace/fetchHomeTimeline', account)
|
await this.$store.dispatch('TimelineSpace/fetchHomeTimeline', account)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -61,14 +60,6 @@ export default {
|
|||||||
type: 'error'
|
type: 'error'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
await this.$store.dispatch('TimelineSpace/username', account)
|
|
||||||
} catch (err) {
|
|
||||||
this.$message({
|
|
||||||
message: 'Could not fetch username',
|
|
||||||
type: 'error'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
await this.$store.dispatch('TimelineSpace/fetchNotifications', account)
|
await this.$store.dispatch('TimelineSpace/fetchNotifications', account)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div id="side_menu">
|
<div id="side_menu">
|
||||||
<div class="profile-wrapper" style="-webkit-app-region: drag;">
|
<div class="profile-wrapper" style="-webkit-app-region: drag;">
|
||||||
<div class="profile">
|
<div class="profile">
|
||||||
<div>@{{ username }}</div>
|
<div>@{{ account.username }}</div>
|
||||||
<span>{{ account.domain }}</span>
|
<span>{{ account.domain }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -49,7 +49,6 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
account: state => state.TimelineSpace.account,
|
account: state => state.TimelineSpace.account,
|
||||||
username: state => state.TimelineSpace.username,
|
|
||||||
unreadHomeTimeline: state => state.TimelineSpace.SideMenu.unreadHomeTimeline,
|
unreadHomeTimeline: state => state.TimelineSpace.SideMenu.unreadHomeTimeline,
|
||||||
unreadNotifications: state => state.TimelineSpace.SideMenu.unreadNotifications
|
unreadNotifications: state => state.TimelineSpace.SideMenu.unreadNotifications
|
||||||
})
|
})
|
||||||
|
@ -15,9 +15,9 @@ const TimelineSpace = {
|
|||||||
state: {
|
state: {
|
||||||
account: {
|
account: {
|
||||||
domain: '',
|
domain: '',
|
||||||
_id: ''
|
_id: '',
|
||||||
|
username: ''
|
||||||
},
|
},
|
||||||
username: '',
|
|
||||||
homeTimeline: [],
|
homeTimeline: [],
|
||||||
notifications: []
|
notifications: []
|
||||||
},
|
},
|
||||||
@ -25,9 +25,6 @@ const TimelineSpace = {
|
|||||||
updateAccount (state, account) {
|
updateAccount (state, account) {
|
||||||
state.account = account
|
state.account = account
|
||||||
},
|
},
|
||||||
updateUsername (state, username) {
|
|
||||||
state.username = username
|
|
||||||
},
|
|
||||||
appendHomeTimeline (state, update) {
|
appendHomeTimeline (state, update) {
|
||||||
state.homeTimeline = [update].concat(state.homeTimeline)
|
state.homeTimeline = [update].concat(state.homeTimeline)
|
||||||
},
|
},
|
||||||
@ -90,7 +87,7 @@ const TimelineSpace = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
fetchAccount ({ commit }, id) {
|
localAccount ({ dispatch, commit }, id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
ipcRenderer.send('get-local-account', id)
|
ipcRenderer.send('get-local-account', id)
|
||||||
ipcRenderer.once('error-get-local-account', (event, err) => {
|
ipcRenderer.once('error-get-local-account', (event, err) => {
|
||||||
@ -99,12 +96,24 @@ const TimelineSpace = {
|
|||||||
})
|
})
|
||||||
ipcRenderer.once('response-get-local-account', (event, account) => {
|
ipcRenderer.once('response-get-local-account', (event, account) => {
|
||||||
ipcRenderer.removeAllListeners('error-get-local-account')
|
ipcRenderer.removeAllListeners('error-get-local-account')
|
||||||
|
|
||||||
|
if (account.username === undefined || account.username === null || account.username === '') {
|
||||||
|
dispatch('fetchAccount', account)
|
||||||
|
.then((acct) => {
|
||||||
|
commit('updateAccount', acct)
|
||||||
|
resolve(acct)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
commit('updateAccount', account)
|
commit('updateAccount', account)
|
||||||
resolve(account)
|
resolve(account)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
username ({ commit }, account) {
|
fetchAccount ({ commit }, account) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const client = new Mastodon(
|
const client = new Mastodon(
|
||||||
{
|
{
|
||||||
@ -113,8 +122,18 @@ const TimelineSpace = {
|
|||||||
})
|
})
|
||||||
client.get('/accounts/verify_credentials', (err, data, res) => {
|
client.get('/accounts/verify_credentials', (err, data, res) => {
|
||||||
if (err) return reject(err)
|
if (err) return reject(err)
|
||||||
commit('updateUsername', data.username)
|
ipcRenderer.send('update-account', Object.assign(account, {
|
||||||
resolve(res)
|
username: data.username,
|
||||||
|
accountId: data.id
|
||||||
|
}))
|
||||||
|
ipcRenderer.once('error-update-account', (event, err) => {
|
||||||
|
ipcRenderer.removeAllListeners('response-update-account')
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
ipcRenderer.once('response-update-account', (event, account) => {
|
||||||
|
ipcRenderer.removeAllListeners('error-update-account')
|
||||||
|
resolve(account)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -202,14 +221,11 @@ const TimelineSpace = {
|
|||||||
'updateAccount',
|
'updateAccount',
|
||||||
{
|
{
|
||||||
domain: '',
|
domain: '',
|
||||||
_id: ''
|
_id: '',
|
||||||
|
username: ''
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return 'clearAccount'
|
return 'clearAccount'
|
||||||
},
|
|
||||||
async clearUsername ({ commit }) {
|
|
||||||
commit('updateUsername', '')
|
|
||||||
return 'clearUsername'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user