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 * as keytar from 'keytar'
|
||||
|
||||
import guid from './lib/guid'
|
||||
import User from './user'
|
||||
|
@ -49,16 +48,6 @@ export function askUserToAuth(endpoint: string) {
|
|||
shell.openExternal(getOAuthURL(authState))
|
||||
}
|
||||
|
||||
export function getToken(login: string, endpoint: string): 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 {
|
||||
export function getKeyForUser(user: User): string {
|
||||
return `GitHub – ${user.getEndpoint()}`
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import {requestToken, getDotComEndpoint} from './auth'
|
|||
import {URLActionType, OAuthAction} from './lib/parse-url'
|
||||
import UsersStore from './users-store'
|
||||
import User from './user'
|
||||
import tokenStore from './token-store'
|
||||
|
||||
const Octokat = require('octokat')
|
||||
|
||||
|
@ -27,8 +28,8 @@ const style = {
|
|||
paddingTop: process.platform === 'darwin' ? 20 : 0
|
||||
}
|
||||
|
||||
const usersStore = new UsersStore()
|
||||
usersStore.loadFromDisk()
|
||||
const usersStore = new UsersStore(localStorage, tokenStore)
|
||||
usersStore.loadFromStore()
|
||||
|
||||
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 {setToken, getToken} from './auth'
|
||||
import {DataStore, SecureStore} from './stores'
|
||||
import {getKeyForUser} from './auth'
|
||||
import User from './user'
|
||||
|
||||
export default class UsersStore {
|
||||
private dataStore: DataStore
|
||||
private secureStore: SecureStore
|
||||
|
||||
private emitter: Emitter
|
||||
private users: User[]
|
||||
|
||||
private persisted: boolean
|
||||
|
||||
public constructor() {
|
||||
public constructor(dataStore: DataStore, secureStore: SecureStore) {
|
||||
this.dataStore = dataStore
|
||||
this.secureStore = secureStore
|
||||
this.emitter = new Emitter()
|
||||
this.users = []
|
||||
this.persisted = false
|
||||
}
|
||||
|
||||
public onUsersChanged(fn: (users: User[]) => void): Disposable {
|
||||
|
@ -28,33 +31,32 @@ export default class UsersStore {
|
|||
}
|
||||
|
||||
public addUser(user: User) {
|
||||
setToken(user, user.getToken())
|
||||
this.secureStore.setItem(getKeyForUser(user), user.getLogin(), user.getToken())
|
||||
|
||||
this.users.push(user)
|
||||
this.usersDidChange()
|
||||
|
||||
if (this.persisted) {
|
||||
this.saveToDisk()
|
||||
}
|
||||
this.save()
|
||||
}
|
||||
|
||||
public loadFromDisk() {
|
||||
this.persisted = true
|
||||
|
||||
const raw = localStorage.getItem('users')
|
||||
public loadFromStore() {
|
||||
const raw = this.dataStore.getItem('users')
|
||||
if (!raw || !raw.length) {
|
||||
return
|
||||
}
|
||||
|
||||
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.usersDidChange()
|
||||
}
|
||||
|
||||
private saveToDisk() {
|
||||
private save() {
|
||||
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