-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* login test * regular user * crud databases * list test, add pouch * crud docs * fix: getDatabase * fix: switch to remote couch api * fix: use api more * fix: remove goofy withParams HOC * no fetcher: setup couch container * fix: admin container * no fetcher: config container * deletedatabasemodal not container * no fetcher: doc container * no fetcher: docs container * no fetcher edit doc container * new database modal not container * footer test container * security doc save * no fetcher search * remove fetcher * fix: comment * fix: standard * fix: remove axios
- Loading branch information
Showing
34 changed files
with
1,009 additions
and
510 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* global btoa */ | ||
const isomorphicFetch = require('isomorphic-fetch') | ||
|
||
function getFetch ({url, username, password, fetch = isomorphicFetch}) { | ||
if (!url) { | ||
throw new Error(`getFetch URL required`) | ||
} | ||
|
||
async function fetcher (endpoint, params) { | ||
const config = { | ||
credentials: 'include', | ||
headers: { | ||
'Accept': 'application/json', | ||
'Content-Type': 'application/json' | ||
}, | ||
...params | ||
} | ||
if (username && password) { | ||
config.headers['Authorization'] = `Basic ${btoa(`${username}:${password}`)}` | ||
delete config.credentials | ||
} | ||
|
||
const urlWithSlash = url.endsWith('/') | ||
? url | ||
: `${url}/` | ||
|
||
const response = await fetch(`${urlWithSlash}${endpoint}`, config) | ||
let body | ||
try { | ||
body = await response.json() | ||
} catch (e) { | ||
console.warn('error caught in fetch parsing body') | ||
} | ||
if (!response.ok) { | ||
const error = new Error() | ||
Object.assign(error, {status: response.status, statusText: response.statusText}, body) | ||
throw error | ||
} | ||
return body | ||
} | ||
|
||
return fetcher | ||
} | ||
|
||
module.exports = {getFetch} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
const {RemoteCouchApi} = require('./remote-couch-api') | ||
|
||
module.exports = {RemoteCouchApi} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// see note in webpack config about this goofy movie. | ||
const PouchDB = pickModule(require('pouchdb-core')) | ||
const idbAdapter = pickModule(require('pouchdb-adapter-idb')) | ||
const memoryAdapter = pickModule(require('pouchdb-adapter-memory')) | ||
const httpAdapter = pickModule(require('pouchdb-adapter-http')) | ||
const replication = pickModule(require('pouchdb-replication')) | ||
const find = pickModule(require('pouchdb-find')) | ||
const mapReduce = pickModule(require('pouchdb-mapreduce')) | ||
|
||
PouchDB | ||
.plugin(idbAdapter) | ||
.plugin(httpAdapter) | ||
.plugin(replication) | ||
.plugin(mapReduce) | ||
.plugin(memoryAdapter) | ||
.plugin(find) | ||
|
||
// pouch exports modules in a way that you cannot simply "require" these in | ||
// node as well as in webpack, which is why we need this workaround: | ||
// https://github.com/pouchdb-community/pouchdb-authentication/issues/164#issuecomment-357697828 | ||
function pickModule (mod) { | ||
return 'default' in mod ? mod.default : mod | ||
} | ||
|
||
module.exports = {PouchDB} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
const {getFetch} = require('./get-fetch') | ||
const {PouchDB} = require('./pouchdb') | ||
|
||
class RemoteCouchApi { | ||
constructor (url) { | ||
url = url.endsWith('/') ? url : `${url}/` | ||
|
||
this.url = url | ||
this.fetcher = getFetch({url}) | ||
// this will probably change to support node | ||
// will have to deal with setDatabase & username/passwords | ||
this.PouchDBConstructor = PouchDB.defaults({prefix: url}) | ||
this.GenericPouchDB = PouchDB | ||
this.databases = {} | ||
} | ||
|
||
async logout () { | ||
await this.fetcher('_session', {method: 'DELETE'}) | ||
this.user = null | ||
} | ||
|
||
async getCurrentUser () { | ||
const session = await this.getCurrentSession() | ||
if (!session) return null | ||
|
||
return this.getUserFromSession(session) | ||
} | ||
|
||
async getCurrentSession () { | ||
const {userCtx} = await this.fetcher('_session') | ||
// this is couch telling us there's no session | ||
if (!userCtx.name) return null | ||
return userCtx | ||
} | ||
|
||
async getUserFromSession (session) { | ||
// couchdb's way of saying admin user, usually does not have a user doc | ||
if (session.roles && session.roles.includes('_admin')) { | ||
delete session.ok | ||
this.user = session | ||
return session | ||
} | ||
|
||
const user = await this.fetcher(`_users/org.couchdb.user:${session.name}`) | ||
this.user = user | ||
return user | ||
} | ||
|
||
async login (username = '', password = '') { | ||
const session = await this.fetcher( | ||
'_session', {method: 'POST', body: JSON.stringify({username, password})} | ||
) | ||
return this.getUserFromSession(session) | ||
} | ||
|
||
getConfigUrl () { | ||
const isLocal = this.url.includes('://localhost:') || this.url.includes('://127.0.0.1:') | ||
return isLocal | ||
? `_node/couchdb@localhost/_config` | ||
: `_node/nonode@nohost/_config` | ||
} | ||
|
||
async getConfig () { | ||
return this.fetcher(`${this.getConfigUrl()}`) | ||
} | ||
|
||
async getAdminConfig () { | ||
return this.fetcher(`${this.getConfigUrl()}/admins`) | ||
} | ||
|
||
async updateAdmin (username, password) { | ||
const url = `${this.getConfigUrl()}/admins/${username}` | ||
return this.fetcher(url, {method: 'PUT', body: `"${password}"`}) | ||
} | ||
|
||
getPouchInstance (databaseName) { | ||
if (!this.databases[databaseName]) { | ||
this.databases[databaseName] = new this.PouchDBConstructor(databaseName) | ||
} | ||
|
||
return this.databases[databaseName] | ||
} | ||
|
||
async listDatabases () { | ||
return this.fetcher('_all_dbs') | ||
} | ||
|
||
async listInfos (keys) { | ||
try { | ||
const response = await this.fetcher('_dbs_info', {method: 'POST', body: JSON.stringify({keys})}) | ||
return response | ||
} catch (error) { | ||
if (error.status !== 404) throw error | ||
|
||
const promises = keys.map(dbName => this.getDatabase(dbName)) | ||
const response = await Promise.all(promises) | ||
// make same shape as _dbs_info | ||
return response.map((info, index) => ({key: keys[index], info})) | ||
} | ||
} | ||
|
||
async createDatabase (databaseName) { | ||
return this.fetcher(databaseName, {method: 'PUT'}) | ||
} | ||
|
||
async getDatabase (databaseName) { | ||
return this.fetcher(databaseName) | ||
} | ||
|
||
async destroyDatabase (databaseName) { | ||
return this.fetcher(databaseName, {method: 'DELETE'}) | ||
} | ||
} | ||
|
||
module.exports = {RemoteCouchApi} |
Oops, something went wrong.