bedrock-account-http
Advanced tools
Comparing version
# bedrock-account-http ChangeLog | ||
## 4.0.0 - 2022-03-07 | ||
### Changed | ||
- **BREAKING**: Update peer deps: | ||
- `bedrock@4.4` | ||
- `bedrock-validation@5.5` | ||
- `bedrock-mongodb@8.4` | ||
- `bedrock-passport@8` | ||
- **BREAKING**: Disable cors on get account route to avoid CSRF attacks. | ||
- **BREAKING**: Remove `schemas` directory from configured schemas, load | ||
locally only using the new `bedrock-validation@5` model. | ||
### Removed | ||
- **BREAKING**: Remove all usage of `bedrock-permission` including | ||
roles (e.g., `sysResourceRole`), `actor`, etc. All authz should | ||
be managed via HTTP (or other) APIs and technologies such as | ||
zcaps, meters, and oauth2. | ||
## 3.1.0 - 2021-06-08 | ||
@@ -4,0 +22,0 @@ |
/*! | ||
* Copyright (c) 2019-2021 Digital Bazaar, Inc. All rights reserved. | ||
* Copyright (c) 2019-2022 Digital Bazaar, Inc. All rights reserved. | ||
*/ | ||
@@ -4,0 +4,0 @@ 'use strict'; |
158
lib/index.js
/*! | ||
* Copyright (c) 2019-2021 Digital Bazaar, Inc. All rights reserved. | ||
* Copyright (c) 2019-2022 Digital Bazaar, Inc. All rights reserved. | ||
*/ | ||
@@ -9,3 +9,2 @@ 'use strict'; | ||
const {config, util: {uuid, BedrockError}} = bedrock; | ||
const cors = require('cors'); | ||
const brAccount = require('bedrock-account'); | ||
@@ -17,6 +16,6 @@ const brPassport = require('bedrock-passport'); | ||
} = brPassport; | ||
const {validate} = require('bedrock-validation'); | ||
// FIXME add an implementation in bedrock-express | ||
const {createValidateMiddleware} = require('bedrock-validation'); | ||
const boolParser = require('express-query-boolean'); | ||
const intParser = require('express-query-int'); | ||
const validators = require('../schemas/bedrock-account-http'); | ||
@@ -26,8 +25,2 @@ // load config defaults | ||
// module API | ||
const api = {}; | ||
module.exports = api; | ||
// const logger = bedrock.loggers.get('app').child('bedrock-account-http'); | ||
bedrock.events.on('bedrock-session-http.session.get', (req, session) => { | ||
@@ -48,4 +41,6 @@ // if user is authenticated, include account ID in session | ||
basePath, | ||
// only check authn to establish whether to auto-login or not; anyone can | ||
// create a new account | ||
optionallyAuthenticated, | ||
validate('account.create'), | ||
createValidateMiddleware({bodySchema: validators.create()}), | ||
asyncHandler(async (req, res, next) => { | ||
@@ -56,21 +51,20 @@ const account = { | ||
}; | ||
const meta = { | ||
sysResourceRole: [{ | ||
sysRole: 'account.registered', | ||
resource: [account.id] | ||
}] | ||
}; | ||
// actor is not required, but passed through if given | ||
let {actor = null} = req.user || {}; | ||
await brAccount.insert({actor, account, meta}); | ||
const meta = {}; | ||
if(actor || !cfg.autoLoginNewAccounts) { | ||
// actor given or auto-login disabled, do not auto-login the new account | ||
res.status(201).location(baseUri + '/' + account.id).json(account); | ||
// anyone may create a new account; must be rate limited via another | ||
// means if necessary | ||
await brAccount.insert({account, meta}); | ||
// get location for new account | ||
const location = `${baseUri}/${encodeURIComponent(account.id)}`; | ||
if(req.user || !cfg.autoLoginNewAccounts) { | ||
// if user already logged into another account or auto-login disabled, | ||
// do not auto-login the new account | ||
res.status(201).location(location).json(account); | ||
return; | ||
} | ||
// no actor given, so auto-login | ||
actor = await brAccount.getCapabilities({id: account.id}); | ||
const user = {account, actor}; | ||
// auto-login | ||
const user = {account}; | ||
// TODO: if passport supports promises or this can be safely promisified | ||
@@ -89,4 +83,3 @@ // then do that in the future; (note that passport's `logIn` signature | ||
}).then( | ||
() => res.status(201).location(baseUri + '/' + account.id) | ||
.json(account), | ||
() => res.status(201).location(location).json(account), | ||
next); | ||
@@ -98,7 +91,6 @@ }); | ||
basePath, | ||
optionallyAuthenticated, | ||
// FIXME add an implementation in bedrock-express | ||
boolParser(), | ||
intParser(), | ||
validate({query: 'account.get'}), | ||
optionallyAuthenticated, | ||
createValidateMiddleware({querySchema: validators.get()}), | ||
asyncHandler(async (req, res) => { | ||
@@ -115,3 +107,4 @@ /** | ||
* Visitors (not logged in) can confirm an email exists | ||
* Admins (logged in) can list accounts by email | ||
* Authenticated account can get its own account info via email | ||
* ZCAP-authorized can list accounts by email (Not implemented) | ||
*/ | ||
@@ -121,7 +114,6 @@ if(req.query.exists === true) { | ||
const {email} = req.query; | ||
const exists = await brAccount.exists({actor: null, email}); | ||
const exists = await brAccount.exists({email}); | ||
if(exists) { | ||
return res.status(200).end(); | ||
} | ||
// TODO: improve error details | ||
throw new BedrockError( | ||
@@ -133,17 +125,31 @@ 'Account does not exist.', 'NotFoundError', { | ||
} | ||
const {email, after = null} = req.query; | ||
const {actor} = req.user || {}; | ||
// unauthenticated users must pass `exists` param | ||
if(!(req.user && req.user.account)) { | ||
throw new BedrockError( | ||
'The "exists" query parameter must be passed.', | ||
'NotAllowedError', { | ||
httpStatusCode: 403, | ||
public: true | ||
}); | ||
} | ||
const {email/*, after = null*/} = req.query; | ||
const query = {'account.email': email}; | ||
if(after) { | ||
// only support searches on authenticated account | ||
query['account.id'] = req.user.account.id; | ||
/*if(after) { | ||
query['account.id'] = {$gt: after}; | ||
} | ||
const fields = { | ||
account: 1, | ||
'meta.created': 1, | ||
'meta.sequence': 1, | ||
'meta.status': 1, | ||
'meta.sysResourceRole': 1 | ||
}*/ | ||
const options = { | ||
sort: {'account.id': -1}, | ||
projection: { | ||
_id: 0, | ||
account: 1, | ||
'meta.created': 1, | ||
'meta.sequence': 1, | ||
'meta.status': 1 | ||
} | ||
}; | ||
const options = {sort: {'account.id': -1}}; | ||
const records = await brAccount.getAll({actor, query, fields, options}); | ||
const records = await brAccount.getAll({query, options}); | ||
res.json(records); | ||
@@ -155,3 +161,3 @@ })); | ||
ensureAuthenticated, | ||
validate('account.setStatus'), | ||
createValidateMiddleware({bodySchema: validators.setStatus()}), | ||
asyncHandler(async (req, res) => { | ||
@@ -165,9 +171,9 @@ /** | ||
* changes that status in the account's meta | ||
* possible statuses are active and deleted | ||
* possible statuses are active, disabled, and deleted | ||
* @route /:account/status | ||
*/ | ||
const {account: id} = req.params; | ||
const {actor} = req.user || {}; | ||
_checkAccount({req, id}); | ||
const {status} = req.body; | ||
await brAccount.setStatus({actor, status, id}); | ||
await brAccount.setStatus({status, id}); | ||
res.status(204).send(); | ||
@@ -181,3 +187,3 @@ }) | ||
intParser(), | ||
validate('account.update'), | ||
createValidateMiddleware({bodySchema: validators.update()}), | ||
asyncHandler(async (req, res) => { | ||
@@ -196,5 +202,5 @@ /** | ||
*/ | ||
const {actor} = req.user || {}; | ||
const {account: id} = req.params; | ||
const updater = {actor, id, ...req.body}; | ||
_checkAccount({req, id}); | ||
const updater = {id, ...req.body}; | ||
await brAccount.update(updater); | ||
@@ -204,40 +210,32 @@ res.status(204).send(); | ||
app.options(accountPath, cors()); | ||
app.get( | ||
`${accountPath}/roles`, | ||
accountPath, | ||
ensureAuthenticated, | ||
cors(), | ||
asyncHandler(async (req, res) => { | ||
/** | ||
* @func getCapabilitiesForAnAccount | ||
* @param {Request} req | ||
* @param {Response} res | ||
* @description uses the account param to get | ||
* all the capabilities for an account | ||
* @route /:account/roles | ||
*/ | ||
const {account: id} = req.params; | ||
const record = await brAccount.getCapabilities({id}); | ||
_checkAccount({req, id}); | ||
const record = await brAccount.get({id}); | ||
res.json(record); | ||
})); | ||
app.get( | ||
app.delete( | ||
accountPath, | ||
optionallyAuthenticated, | ||
cors(), | ||
ensureAuthenticated, | ||
asyncHandler(async (req, res) => { | ||
const {account: id} = req.params; | ||
const {actor} = req.user || {}; | ||
const record = await brAccount.get({actor, id}); | ||
res.json(record); | ||
_checkAccount({req, id}); | ||
await brAccount.setStatus({status: 'deleted', id}); | ||
res.status(204).send(); | ||
})); | ||
}); | ||
app.delete( | ||
accountPath, | ||
ensureAuthenticated, | ||
asyncHandler(async (req, res, next) => { | ||
// TODO: next | ||
next(); | ||
})); | ||
}); | ||
function _checkAccount({req, id}) { | ||
if(!(req.user && req.user.account && req.user.account.id === id)) { | ||
throw new BedrockError( | ||
'The authenticated account does not match the target account.', | ||
'NotAllowedError', { | ||
httpStatusCode: 403, | ||
public: true | ||
}); | ||
} | ||
} |
{ | ||
"name": "bedrock-account-http", | ||
"version": "3.1.0", | ||
"version": "4.0.0", | ||
"description": "HTTP API for Bedrock User Accounts", | ||
@@ -27,3 +27,2 @@ "license": "SEE LICENSE IN LICENSE.md", | ||
"dependencies": { | ||
"cors": "^2.8.4", | ||
"express-query-boolean": "^2.0.0", | ||
@@ -33,7 +32,7 @@ "express-query-int": "^3.0.0" | ||
"peerDependencies": { | ||
"bedrock": "1.12.1 - 3.x", | ||
"bedrock-account": "^5.0.0", | ||
"bedrock-express": "2.0.8 - 3.x", | ||
"bedrock-passport": "5.x - 6.x", | ||
"bedrock-validation": "^5.0.0" | ||
"bedrock": "^4.4.3", | ||
"bedrock-account": "^6.0.0", | ||
"bedrock-express": "^6.2.2", | ||
"bedrock-passport": "^8.0.2", | ||
"bedrock-validation": "^5.5.0" | ||
}, | ||
@@ -40,0 +39,0 @@ "directories": { |
@@ -1,3 +0,3 @@ | ||
/* | ||
* Copyright (c) 2019-2021 Digital Bazaar, Inc. All rights reserved. | ||
/*! | ||
* Copyright (c) 2019-2022 Digital Bazaar, Inc. All rights reserved. | ||
*/ | ||
@@ -8,3 +8,2 @@ 'use strict'; | ||
const database = require('bedrock-mongodb'); | ||
const {promisify} = require('util'); | ||
const {util: {uuid}} = require('bedrock'); | ||
@@ -23,12 +22,3 @@ | ||
//called in before | ||
api.getActors = async mockData => { | ||
const actors = {}; | ||
for(const [key, record] of Object.entries(mockData.accounts)) { | ||
actors[key] = await brAccount.getCapabilities({id: record.account.id}); | ||
} | ||
return actors; | ||
}; | ||
//called in test before hook | ||
// called in test before hook | ||
api.prepareDatabase = async mockData => { | ||
@@ -41,3 +31,3 @@ await api.removeCollections(); | ||
api.removeCollections = async (collectionNames = ['account']) => { | ||
await promisify(database.openCollections)(collectionNames); | ||
await database.openCollections(collectionNames); | ||
for(const collectionName of collectionNames) { | ||
@@ -56,4 +46,5 @@ await database.collections[collectionName].deleteMany({}); | ||
try { | ||
await brAccount.insert( | ||
{actor: null, account: record.account, meta: record.meta || {}}); | ||
await brAccount.insert({ | ||
account: record.account, meta: record.meta || {} | ||
}); | ||
} catch(e) { | ||
@@ -60,0 +51,0 @@ if(e.name === 'DuplicateError') { |
/*! | ||
* Copyright (c) 2019-2021 Digital Bazaar, Inc. All rights reserved. | ||
* Copyright (c) 2019-2022 Digital Bazaar, Inc. All rights reserved. | ||
*/ | ||
'use strict'; | ||
@@ -14,5 +13,6 @@ | ||
const mockData = require('../mock.data'); | ||
const {util: {uuid}} = require('bedrock'); | ||
const {_deserializeUser} = require('bedrock-passport'); | ||
const Emails = { | ||
admin: 'admin@example.com', | ||
const emails = { | ||
alpha: 'alpha@example.com', | ||
@@ -25,3 +25,2 @@ multi: 'multi@example.com', | ||
let api; | ||
let actors; | ||
@@ -32,3 +31,2 @@ const baseURL = | ||
// simple quick func to check validation errors | ||
// TODO extend mocha should with this | ||
function validationError( | ||
@@ -57,7 +55,15 @@ result, errorMethod, | ||
function stubPassportStub(email) { | ||
passportStub.callsFake((req, res, next) => { | ||
req.user = { | ||
actor: actors[email], | ||
account: accounts[email].account | ||
}; | ||
passportStub.callsFake(async (req, res, next) => { | ||
if(!email) { | ||
req.user = null; | ||
return next(); | ||
} | ||
try { | ||
req.user = await _deserializeUser({ | ||
accountId: accounts[email].account.id | ||
}); | ||
} catch(e) { | ||
return next(e); | ||
} | ||
next(); | ||
@@ -70,4 +76,3 @@ }); | ||
await helpers.prepareDatabase(mockData); | ||
actors = await helpers.getActors(mockData); | ||
accounts = mockData.accounts; | ||
accounts = {...mockData.accounts}; | ||
api = create({ | ||
@@ -78,2 +83,5 @@ baseURL, | ||
}); | ||
afterEach(function() { | ||
stubPassportStub(null); | ||
}); | ||
after(async function() { | ||
@@ -116,3 +124,2 @@ passportStub.restore(); | ||
}); | ||
}); | ||
@@ -123,3 +130,3 @@ | ||
const {account: {id}} = accounts['alpha@example.com']; | ||
stubPassportStub(Emails.admin); | ||
stubPassportStub(emails.alpha); | ||
const result = await api.get(`/${id}`); | ||
@@ -133,5 +140,5 @@ result.status.should.equal(200); | ||
it('should return 403 if actor does not have permission', async function() { | ||
it('should return 403', async function() { | ||
const {account: {id}} = accounts['alpha@example.com']; | ||
stubPassportStub(Emails.multi); | ||
stubPassportStub(emails.multi); | ||
const result = await api.get(`/${id}`); | ||
@@ -145,7 +152,7 @@ result.status.should.equal(403); | ||
it('should return 404 if not account for id', async function() { | ||
it('should return 403 if no account exists for id', async function() { | ||
const id = 'does-not-exist'; | ||
stubPassportStub(Emails.admin); | ||
stubPassportStub(emails.alpha); | ||
const result = await api.get(`/${id}`); | ||
result.status.should.equal(404); | ||
result.status.should.equal(403); | ||
const {data} = result; | ||
@@ -160,4 +167,7 @@ data.should.be.an('object'); | ||
it('should change the status to deleted', async function() { | ||
const {account: {id}} = accounts['alpha@example.com']; | ||
stubPassportStub(Emails.admin); | ||
const email = `${uuid()}@digitalbazaar.com`; | ||
const {data} = await api.post('/', {email}); | ||
accounts[email] = {account: data, meta: {}}; | ||
const {id} = data; | ||
stubPassportStub(email); | ||
const status = 'deleted'; | ||
@@ -167,10 +177,11 @@ const result = await api.post(`/${id}/status`, {status}); | ||
const nextResult = await api.get(`/${id}`); | ||
nextResult.data.should.have.property('meta'); | ||
nextResult.data.meta.should.have.property('status'); | ||
nextResult.data.meta.status.should.equal(status); | ||
nextResult.status.should.equal(404); | ||
}); | ||
it('should change the status to disabled', async function() { | ||
const {account: {id}} = accounts['alpha@example.com']; | ||
stubPassportStub(Emails.admin); | ||
const email = `${uuid()}@digitalbazaar.com`; | ||
const {data} = await api.post('/', {email}); | ||
accounts[email] = {account: data, meta: {}}; | ||
const {id} = data; | ||
stubPassportStub(email); | ||
const status = 'disabled'; | ||
@@ -180,10 +191,11 @@ const result = await api.post(`/${id}/status`, {status}); | ||
const nextResult = await api.get(`/${id}`); | ||
nextResult.data.should.have.property('meta'); | ||
nextResult.data.meta.should.have.property('status'); | ||
nextResult.data.meta.status.should.equal(status); | ||
nextResult.status.should.equal(403); | ||
}); | ||
it('should change the status to active', async function() { | ||
const {account: {id}} = accounts['alpha@example.com']; | ||
stubPassportStub(Emails.admin); | ||
it('should keep status at active', async function() { | ||
const email = `${uuid()}@digitalbazaar.com`; | ||
const {data} = await api.post('/', {email}); | ||
accounts[email] = {account: data, meta: {}}; | ||
const {id} = data; | ||
stubPassportStub(email); | ||
const status = 'active'; | ||
@@ -198,5 +210,33 @@ const result = await api.post(`/${id}/status`, {status}); | ||
it('should fail to reactivate disabled account', async function() { | ||
const email = `${uuid()}@digitalbazaar.com`; | ||
const {data} = await api.post('/', {email}); | ||
accounts[email] = {account: data, meta: {}}; | ||
const {id} = data; | ||
stubPassportStub(email); | ||
const status = 'disabled'; | ||
const result = await api.post(`/${id}/status`, {status}); | ||
result.status.should.equal(204); | ||
const nextResult = await api.post(`/${id}/status`, {status: 'active'}); | ||
nextResult.status.should.equal(403); | ||
}); | ||
it('should fail to reactivate deleted account', async function() { | ||
const email = `${uuid()}@digitalbazaar.com`; | ||
const {data} = await api.post('/', {email}); | ||
accounts[email] = {account: data, meta: {}}; | ||
const {id} = data; | ||
stubPassportStub(email); | ||
const status = 'deleted'; | ||
const result = await api.post(`/${id}/status`, {status}); | ||
result.status.should.equal(204); | ||
const nextResult = await api.post(`/${id}/status`, {status: 'active'}); | ||
nextResult.status.should.equal(404); | ||
}); | ||
it('should return 403', async function() { | ||
const {account: {id}} = accounts['alpha@example.com']; | ||
stubPassportStub(Emails.multi); | ||
stubPassportStub(emails.multi); | ||
const status = 'deleted'; | ||
@@ -209,3 +249,3 @@ const result = await api.post(`/${id}/status`, {status}); | ||
const {account: {id}} = accounts['alpha@example.com']; | ||
stubPassportStub(Emails.multi); | ||
stubPassportStub(emails.multi); | ||
const result = await api.post(`/${id}/status`); | ||
@@ -215,26 +255,7 @@ validationError(result, 'patch', /status/i); | ||
}); | ||
describe('get /:account/roles', function() { | ||
it('should return an account', async function() { | ||
const {account: {id}} = accounts['alpha@example.com']; | ||
const result = await api.get(`/${id}/roles`); | ||
result.status.should.equal(200); | ||
const {data} = result; | ||
data.should.be.an('object'); | ||
data.should.have.property('id'); | ||
data.should.have.property('sysResourceRole'); | ||
data.sysResourceRole.should.be.an('array'); | ||
data.sysResourceRole.forEach(role => { | ||
role.should.have.property('sysRole'); | ||
role.sysRole.should.be.an('string'); | ||
role.should.have.property('resource'); | ||
role.resource.should.be.an('array'); | ||
}); | ||
}); | ||
}); | ||
describe('patch /:account', function() { | ||
it('should update an account', async function() { | ||
const {account: {id}} = accounts[Emails.updated]; | ||
stubPassportStub(Emails.admin); | ||
const {account: {id}} = accounts[emails.updated]; | ||
stubPassportStub(emails.updated); | ||
const value = 'updated@tester.org'; | ||
@@ -253,3 +274,3 @@ const patch = [{op: 'replace', path: '/email', value}]; | ||
account.email.should.equal(value); | ||
account.email.should.not.contain(Emails.updated); | ||
account.email.should.not.contain(emails.updated); | ||
}); | ||
@@ -259,3 +280,3 @@ | ||
const {account: {id}} = accounts['alpha@example.com']; | ||
stubPassportStub(Emails.admin); | ||
stubPassportStub(emails.alpha); | ||
const result = await api.patch(`/${id}`, {sequence: 10, patch: []}); | ||
@@ -267,3 +288,3 @@ validationError(result, 'update', /items/i); | ||
const {account: {id}} = accounts['alpha@example.com']; | ||
stubPassportStub(Emails.admin); | ||
stubPassportStub(emails.alpha); | ||
const value = 'fail@extras.org'; | ||
@@ -278,3 +299,3 @@ const patch = [{op: 'replace', path: '/email', value}]; | ||
const {account: {id}} = accounts['alpha@example.com']; | ||
stubPassportStub(Emails.admin); | ||
stubPassportStub(emails.alpha); | ||
const value = 'updated@tester.org'; | ||
@@ -294,3 +315,3 @@ const patch = [{op: 'replace', path: '/email', value}]; | ||
it('return 200 if the email is found', async function returnAccount() { | ||
const email = 'admin@example.com'; | ||
const email = 'alpha@example.com'; | ||
const result = await api.get('/', {exists: true, email}); | ||
@@ -314,3 +335,3 @@ const {status} = result; | ||
const email = 'multi@example.com'; | ||
stubPassportStub(Emails.admin); | ||
stubPassportStub(emails.multi); | ||
const result = await api.get('/', {email}); | ||
@@ -331,3 +352,3 @@ result.data.should.be.an('array'); | ||
const email = null; | ||
stubPassportStub(Emails.admin); | ||
stubPassportStub(emails.alpha); | ||
const result = await api.get('/', {email}); | ||
@@ -339,3 +360,3 @@ validationError(result, 'accounts', /email/i); | ||
const email = 'tomany@params.org'; | ||
stubPassportStub(Emails.admin); | ||
stubPassportStub(emails.alpha); | ||
const result = await api.get('/', {email, extra: true}); | ||
@@ -345,13 +366,12 @@ validationError(result, 'accounts', /additional/i); | ||
it('should return 403 due to permission', async function() { | ||
const email = 'admin@example.com'; | ||
stubPassportStub(Emails.multi); | ||
it('should return no results for non-matching account', async function() { | ||
const email = 'multi@example.com'; | ||
stubPassportStub(emails.alpha); | ||
const result = await api.get('/', {email}); | ||
result.status.should.equal(403); | ||
result.status.should.equal(200); | ||
const {data} = result; | ||
data.should.be.an('object'); | ||
data.should.not.have.property('meta'); | ||
data.should.not.have.property('account'); | ||
data.should.be.an('array'); | ||
data.length.should.equal(0); | ||
}); | ||
}); | ||
}); |
@@ -1,3 +0,3 @@ | ||
/* | ||
* Copyright (c) 2019-2021 Digital Bazaar, Inc. All rights reserved. | ||
/*! | ||
* Copyright (c) 2019-2022 Digital Bazaar, Inc. All rights reserved. | ||
*/ | ||
@@ -18,8 +18,3 @@ 'use strict'; | ||
accounts[email].meta = {}; | ||
accounts[email].meta.sysResourceRole = [{ | ||
sysRole: 'bedrock-account.regular', | ||
generateResource: 'id' | ||
}]; | ||
// regular permissions | ||
email = 'alpha@example.com'; | ||
@@ -29,16 +24,3 @@ accounts[email] = {}; | ||
accounts[email].meta = {}; | ||
accounts[email].meta.sysResourceRole = [{ | ||
sysRole: 'bedrock-account.regular', | ||
generateResource: 'id' | ||
}]; | ||
// admin permissions | ||
email = 'admin@example.com'; | ||
accounts[email] = {}; | ||
accounts[email].account = helpers.createAccount(email); | ||
accounts[email].meta = {}; | ||
accounts[email].meta.sysResourceRole = [{ | ||
sysRole: 'bedrock-account.admin' | ||
}]; | ||
// multiple accounts one email | ||
@@ -45,0 +27,0 @@ email = 'multi@example.com'; |
@@ -29,13 +29,11 @@ { | ||
"apisauce": "^2.0.0", | ||
"bedrock": "^3.1.1", | ||
"bedrock-account": "^5.0.0", | ||
"bedrock": "^4.4.3", | ||
"bedrock-account": "^6.0.0", | ||
"bedrock-account-http": "file:..", | ||
"bedrock-express": "^3.2.0", | ||
"bedrock-mongodb": "^7.1.0", | ||
"bedrock-passport": "^6.0.0", | ||
"bedrock-permission": "^3.0.0", | ||
"bedrock-rest": "^3.0.0", | ||
"bedrock-server": "^2.6.0", | ||
"bedrock-test": "^5.3.0", | ||
"bedrock-validation": "^5.0.0", | ||
"bedrock-express": "^6.2.2", | ||
"bedrock-mongodb": "^8.4.0", | ||
"bedrock-passport": "^8.0.2", | ||
"bedrock-server": "^3.1.0", | ||
"bedrock-test": "^6.0.0", | ||
"bedrock-validation": "^5.5.0", | ||
"cross-env": "^7.0.2", | ||
@@ -42,0 +40,0 @@ "grunt": "^1.1.0", |
/*! | ||
* Copyright (c) 2012-2021 Digital Bazaar, Inc. All rights reserved. | ||
* Copyright (c) 2012-2022 Digital Bazaar, Inc. All rights reserved. | ||
*/ | ||
@@ -8,5 +8,5 @@ 'use strict'; | ||
const path = require('path'); | ||
require('bedrock-mongodb'); | ||
require('bedrock-express'); | ||
const {permissions, roles} = config.permission; | ||
config.mocha.tests.push(path.join(__dirname, 'mocha')); | ||
@@ -16,3 +16,2 @@ | ||
config.mongodb.name = 'bedrock_account_http_test'; | ||
config.mongodb.local.collection = 'bedrock_account_http_test'; | ||
config.mongodb.dropCollections = {}; | ||
@@ -22,24 +21,3 @@ config.mongodb.dropCollections.onInit = true; | ||
roles['bedrock-account.regular'] = { | ||
id: 'bedrock-account.regular', | ||
label: 'Account Test Role', | ||
comment: 'Role for Test User', | ||
sysPermission: [ | ||
permissions.ACCOUNT_ACCESS.id, | ||
permissions.ACCOUNT_UPDATE.id, | ||
permissions.ACCOUNT_INSERT.id | ||
] | ||
}; | ||
roles['bedrock-account.admin'] = { | ||
id: 'bedrock-account.admin', | ||
label: 'Account Test Role', | ||
comment: 'Role for Admin User', | ||
sysPermission: [ | ||
permissions.ACCOUNT_ACCESS.id, | ||
permissions.ACCOUNT_UPDATE.id, | ||
permissions.ACCOUNT_INSERT.id, | ||
permissions.ACCOUNT_REMOVE.id, | ||
permissions.ACCOUNT_META_UPDATE.id | ||
] | ||
}; | ||
// enable sessions | ||
config.express.useSession = true; |
@@ -10,5 +10,7 @@ /*! | ||
const bedrock = require('bedrock'); | ||
require('bedrock-account'); | ||
require('bedrock-account-http'); | ||
require('bedrock-mongodb'); | ||
require('bedrock-test'); | ||
bedrock.start(); |
7
-12.5%36797
-0.51%724
-4.23%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed