Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/charliehess/redux-persist-transform-passwords
Store parts of your state tree in keytar
https://github.com/charliehess/redux-persist-transform-passwords
Last synced: 7 days ago
JSON representation
Store parts of your state tree in keytar
- Host: GitHub
- URL: https://github.com/charliehess/redux-persist-transform-passwords
- Owner: CharlieHess
- Created: 2017-05-28T23:00:31.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2019-05-09T16:54:17.000Z (over 5 years ago)
- Last Synced: 2024-09-26T09:53:29.438Z (about 1 month ago)
- Language: JavaScript
- Size: 98.6 KB
- Stars: 2
- Watchers: 2
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
## redux-persist-transform-passwords
Store some parts of your state in the macOS Keychain, Credential Vault on Windows, or `libsecret` on Linux. Uses [`keytar`](https://github.com/atom/node-keytar). Adheres to the `redux-persist` [transform API](https://github.com/rt2zz/redux-persist#transforms), but [async transforms](https://github.com/rt2zz/redux-persist/pull/360) must be enabled.## Install
```
npm i redux-persist-transform-passwords --save
```## Usage
Given a state shape like:
``` js
{
credentials: {
username: 'charlie',
password: 'hunter42'
}
}
```Supply either a getter string (see Lodash [get](https://lodash.com/docs/4.17.4#get)) or a function that, given your input state, returns a getter string:
```js
import { persistStore } from 'redux-persist';
import createPasswordTransform from 'redux-persist-transform-passwords';const passwordTransform = createPasswordTransform({
serviceName: 'com.mySecretCompany.mySecretApp',
passwordPaths: 'credentials.password',
whitelist: ['authReducer']
});persistStore(store, {
transforms: [passwordTransform],
asyncTransforms: true
});
```Before serialization, the values at `passwordPaths` will be removed from your state and written into `keytar`. When the store is rehydrated, the secrets are read in from `keytar` and reapplied to your state.
You can find more usage examples by reading the tests.
## API
### `createPasswordTransform(config)` - Creates a new transform instance.
#### `config (Object)` - Configuration parameters
* `serviceName (String)` - The top-level identifier for your app to store items in the keychain.
* `accountName (String)` - (Optional) A sub-identifier for individual entries. If not provided, strings taken from `passwordPaths` will be used.
* `passwordPaths (String|Array|((state) => String|Array)` - (Optional) Lodash getter path(s) to passwords in your state, or a function that, given your state, returns path(s). Leave empty to write the entire reducer.
* `clearPasswords (Boolean)` - (Optional) Whether or not to clear the properties from `passwordPaths` before the state is persisted. Defaults to `true`.
* `serialize (Boolean)` - (Optional) Whether or not to serialize password properties as JSON strings. Defaults to `false`.
* `logger ((message, ...args) => void)` - (Optional) An optional logging method. Defaults to `noop`.### `clearKeychain(serviceName, accountName): Promise` - Remove an entry from the keychain.
### `accessKeychain(serviceName, accountName): Promise` - Test for access to the keychain.
Since we don't want to throw any errors during the state transform, we'll catch & log any exceptions in the keychain operation. To give consumers a way to check access beforehand (and to control the time at which the OS keychain prompt appears), we provide the `accessKeychain` method. You'll need to call this method _before_ your Redux store is rehydrated, since the rehydrate will attempt to read from the keychain:
``` js
import createPasswordTransform, {
accessKeychain
} from 'redux-persist-transform-passwords';
import createEncryptor from 'redux-persist-transform-encrypt';async createAndPersistStore() {
// Check if we can access the keychain first
// On some platforms this will pop an OS permissions dialog!
const canAccess = await accessKeychain();// If we don't have access, fallback to encrypting the passwords
const passwordTransform = canAccess ? createPasswordTransform({
serviceName: 'MyApp',
accountName: 'Passwords',
whitelist: ['passwords']
}) : createEncryptor({
secretKey,
whitelist: ['passwords']
});// Business as usual for redux-persist
persistStore(yourStore, {
asyncTransforms: true,
transforms: [passwordTransform]
...
});
}
```