mirror of
https://github.com/desktop/desktop
synced 2024-10-31 11:07:25 +00:00
Decouple storage, both secure and general.
This commit is contained in:
parent
ccaf0aa41f
commit
3928ddc72d
5 changed files with 42 additions and 30 deletions
13
src/auth.ts
13
src/auth.ts
|
@ -1,5 +1,4 @@
|
||||||
import {shell} from 'electron'
|
import {shell} from 'electron'
|
||||||
import * as keytar from 'keytar'
|
|
||||||
|
|
||||||
import guid from './lib/guid'
|
import guid from './lib/guid'
|
||||||
import User from './user'
|
import User from './user'
|
||||||
|
@ -49,16 +48,6 @@ export function askUserToAuth(endpoint: string) {
|
||||||
shell.openExternal(getOAuthURL(authState))
|
shell.openExternal(getOAuthURL(authState))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getToken(login: string, endpoint: string): string {
|
export function getKeyForUser(user: User): string {
|
||||||
const serviceName = getServiceNameForUser(new User(login, endpoint, ''))
|
|
||||||
return keytar.getPassword(serviceName, login)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function setToken(user: User, token: string) {
|
|
||||||
const serviceName = getServiceNameForUser(user)
|
|
||||||
keytar.addPassword(serviceName, user.getLogin(), token)
|
|
||||||
}
|
|
||||||
|
|
||||||
function getServiceNameForUser(user: User): string {
|
|
||||||
return `GitHub – ${user.getEndpoint()}`
|
return `GitHub – ${user.getEndpoint()}`
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {requestToken, getDotComEndpoint} from './auth'
|
||||||
import {URLActionType, OAuthAction} from './lib/parse-url'
|
import {URLActionType, OAuthAction} from './lib/parse-url'
|
||||||
import UsersStore from './users-store'
|
import UsersStore from './users-store'
|
||||||
import User from './user'
|
import User from './user'
|
||||||
|
import tokenStore from './token-store'
|
||||||
|
|
||||||
const Octokat = require('octokat')
|
const Octokat = require('octokat')
|
||||||
|
|
||||||
|
@ -27,8 +28,8 @@ const style = {
|
||||||
paddingTop: process.platform === 'darwin' ? 20 : 0
|
paddingTop: process.platform === 'darwin' ? 20 : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const usersStore = new UsersStore()
|
const usersStore = new UsersStore(localStorage, tokenStore)
|
||||||
usersStore.loadFromDisk()
|
usersStore.loadFromStore()
|
||||||
|
|
||||||
ReactDOM.render(<App style={style} usersStore={usersStore}/>, document.getElementById('content'))
|
ReactDOM.render(<App style={style} usersStore={usersStore}/>, document.getElementById('content'))
|
||||||
|
|
||||||
|
|
9
src/stores.ts
Normal file
9
src/stores.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
export interface SecureStore {
|
||||||
|
setItem(key: string, login: string, value: string): void
|
||||||
|
getItem(key: string, login: string): string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DataStore {
|
||||||
|
setItem(key: string, value: string): void
|
||||||
|
getItem(key: string): string
|
||||||
|
}
|
11
src/token-store.ts
Normal file
11
src/token-store.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import * as keytar from 'keytar'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setItem: function (key: string, login: string, value: string) {
|
||||||
|
keytar.addPassword(key, login, value)
|
||||||
|
},
|
||||||
|
|
||||||
|
getItem: function (key: string, login: string): string {
|
||||||
|
return keytar.getPassword(key, login)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,18 +1,21 @@
|
||||||
import {Emitter, Disposable} from 'event-kit'
|
import {Emitter, Disposable} from 'event-kit'
|
||||||
|
|
||||||
import {setToken, getToken} from './auth'
|
import {DataStore, SecureStore} from './stores'
|
||||||
|
import {getKeyForUser} from './auth'
|
||||||
import User from './user'
|
import User from './user'
|
||||||
|
|
||||||
export default class UsersStore {
|
export default class UsersStore {
|
||||||
|
private dataStore: DataStore
|
||||||
|
private secureStore: SecureStore
|
||||||
|
|
||||||
private emitter: Emitter
|
private emitter: Emitter
|
||||||
private users: User[]
|
private users: User[]
|
||||||
|
|
||||||
private persisted: boolean
|
public constructor(dataStore: DataStore, secureStore: SecureStore) {
|
||||||
|
this.dataStore = dataStore
|
||||||
public constructor() {
|
this.secureStore = secureStore
|
||||||
this.emitter = new Emitter()
|
this.emitter = new Emitter()
|
||||||
this.users = []
|
this.users = []
|
||||||
this.persisted = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public onUsersChanged(fn: (users: User[]) => void): Disposable {
|
public onUsersChanged(fn: (users: User[]) => void): Disposable {
|
||||||
|
@ -28,33 +31,32 @@ export default class UsersStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
public addUser(user: User) {
|
public addUser(user: User) {
|
||||||
setToken(user, user.getToken())
|
this.secureStore.setItem(getKeyForUser(user), user.getLogin(), user.getToken())
|
||||||
|
|
||||||
this.users.push(user)
|
this.users.push(user)
|
||||||
this.usersDidChange()
|
this.usersDidChange()
|
||||||
|
|
||||||
if (this.persisted) {
|
this.save()
|
||||||
this.saveToDisk()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public loadFromDisk() {
|
public loadFromStore() {
|
||||||
this.persisted = true
|
const raw = this.dataStore.getItem('users')
|
||||||
|
|
||||||
const raw = localStorage.getItem('users')
|
|
||||||
if (!raw || !raw.length) {
|
if (!raw || !raw.length) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const rawUsers: any[] = JSON.parse(raw)
|
const rawUsers: any[] = JSON.parse(raw)
|
||||||
const usersWithTokens = rawUsers.map(user => new User(user.login, user.endpoint, getToken(user.login, user.endpoint)))
|
const usersWithTokens = rawUsers.map(user => {
|
||||||
|
const userWithoutToken = new User(user.login, user.endpoint, '')
|
||||||
|
return userWithoutToken.userWithToken(this.secureStore.getItem(getKeyForUser(userWithoutToken), user.login))
|
||||||
|
})
|
||||||
this.users = usersWithTokens
|
this.users = usersWithTokens
|
||||||
|
|
||||||
this.usersDidChange()
|
this.usersDidChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
private saveToDisk() {
|
private save() {
|
||||||
const usersWithoutTokens = this.users.map(user => user.userWithToken(''))
|
const usersWithoutTokens = this.users.map(user => user.userWithToken(''))
|
||||||
localStorage.setItem('users', JSON.stringify(usersWithoutTokens))
|
this.dataStore.setItem('users', JSON.stringify(usersWithoutTokens))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue