diff --git a/package-lock.json b/package-lock.json index 0109487..b368a84 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "mailgun": "^0.5.0", "nanoid": "^3.3.6", "nanoid-dictionary": "^4.3.0", + "p-map": "^4.0.0", "passport": "^0.7.0", "passport-google-oauth20": "^2.0.0", "passport-google-web": "^1.1.0", @@ -2146,6 +2147,18 @@ "node": ">=0.4.0" } }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2619,6 +2632,14 @@ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "engines": { + "node": ">=6" + } + }, "node_modules/cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", @@ -4283,6 +4304,14 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -5251,6 +5280,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", diff --git a/package.json b/package.json index da672af..46103e3 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "mailgun": "^0.5.0", "nanoid": "^3.3.6", "nanoid-dictionary": "^4.3.0", + "p-map": "^4.0.0", "passport": "^0.7.0", "passport-google-oauth20": "^2.0.0", "passport-google-web": "^1.1.0", diff --git a/src/server/managers/account.ts b/src/server/managers/account.ts index 94f8b5a..174f942 100644 --- a/src/server/managers/account.ts +++ b/src/server/managers/account.ts @@ -2,42 +2,62 @@ // Account Manager // --------------------------------------------------------------------------------------------------------------------- +import pMap from 'p-map'; + // Models import { Account, NewAccount } from '../../common/interfaces/models/account'; // Resource Access import * as accountRA from '../resource-access/account'; +import * as roleRA from '../resource-access/role'; // --------------------------------------------------------------------------------------------------------------------- export async function list(filters : accountRA.AccountFilters) : Promise { - return accountRA.list(filters); -} - -export async function getGroups(accountID : string) : Promise -{ - return accountRA.getGroups(accountID); + const accounts = await accountRA.list(filters); + return pMap(accounts, async (account) => + { + const roles = await roleRA.getRoles(account.id); + return { + ...account, + groups: roles + }; + }, { concurrency: 10 }); } export async function get(accountID : string) : Promise { - return accountRA.get(accountID); + const account = await accountRA.get(accountID); + const roles = await roleRA.getRoles(accountID); + + return { + ...account, + groups: roles + }; } export async function getByEmail(email : string) : Promise { - return accountRA.getByEmail(email); + const account = await accountRA.getByEmail(email); + const roles = await roleRA.getRoles(account.id); + + return { + ...account, + groups: roles + }; } export async function add(newAccount : NewAccount) : Promise { - return accountRA.add(newAccount); + const accountID = await accountRA.add(newAccount); + return get(accountID); } export async function update(accountID : string, accountUpdate : Partial) : Promise { - return accountRA.update(accountID, accountUpdate); + await accountRA.update(accountID, accountUpdate); + return get(accountID); } export async function remove(accountID : string) : Promise<{ status : 'ok' }> diff --git a/src/server/resource-access/account.ts b/src/server/resource-access/account.ts index 2e1f438..ac65929 100644 --- a/src/server/resource-access/account.ts +++ b/src/server/resource-access/account.ts @@ -77,20 +77,6 @@ export async function list(filters : AccountFilters) : Promise return (await query).map(AccountTransforms.fromDB); } -export async function getGroups(accountID : string) : Promise -{ - const db = await getDB(); - const roles = await db('account as ac') - .select('r.name as name', 'r.role_id as id') - .join('account_role as ar', 'ac.account_id', '=', 'ar.account_id') - .join('role as r', 'ar.role_id', '=', 'r.role_id') - .where({ - 'ac.account_id': accountID - }); - - return roles.map((role) => role.name); -} - export async function get(accountID : string) : Promise { const db = await getDB(); @@ -117,8 +103,7 @@ export async function get(accountID : string) : Promise } else { - const groups = await getGroups(accountID); - return AccountTransforms.fromDB({ ...accounts[0], groups }); + return AccountTransforms.fromDB(accounts[0]); } } @@ -146,22 +131,21 @@ export async function getByEmail(email : string) : Promise } else { - const groups = await getGroups(accounts[0].account_id); - return AccountTransforms.fromDB({ ...accounts[0], groups }); + return AccountTransforms.fromDB(accounts[0]); } } -export async function add(newAccount : NewAccount) : Promise +export async function add(newAccount : NewAccount) : Promise { - const account = AccountTransforms.toDB(newAccount); + const account = AccountTransforms.toDB({ ...newAccount, id: shortID() }); const db = await getDB(); await db('account') - .insert({ ...account, id: shortID(), created: db.fn.now() }); + .insert({ ...account, created: db.fn.now() }); - return get(account.account_id); + return account.account_id; } -export async function update(accountID : string, accountUpdate : Partial) : Promise +export async function update(accountID : string, accountUpdate : Partial) : Promise { // Get the current account const account = await get(accountID); @@ -179,9 +163,6 @@ export async function update(accountID : string, accountUpdate : Partial diff --git a/src/server/resource-access/role.ts b/src/server/resource-access/role.ts new file mode 100644 index 0000000..a8cb48a --- /dev/null +++ b/src/server/resource-access/role.ts @@ -0,0 +1,23 @@ +// --------------------------------------------------------------------------------------------------------------------- +// Role Resource Access Layer +// --------------------------------------------------------------------------------------------------------------------- + +import { getDB } from '../utils/database'; + +// --------------------------------------------------------------------------------------------------------------------- + +export async function getRoles(accountID : string) : Promise +{ + const db = await getDB(); + const roles = await db('account as ac') + .select('r.name as name', 'r.role_id as id') + .join('account_role as ar', 'ac.account_id', '=', 'ar.account_id') + .join('role as r', 'ar.role_id', '=', 'r.role_id') + .where({ + 'ac.account_id': accountID + }); + + return roles.map((role) => role.name); +} + +// --------------------------------------------------------------------------------------------------------------------- diff --git a/src/server/routes/characters.ts b/src/server/routes/characters.ts index 045e10f..4b62918 100644 --- a/src/server/routes/characters.ts +++ b/src/server/routes/characters.ts @@ -50,9 +50,6 @@ router.get('/', async(req, resp) => } const filters = parseQuery(query); - - console.log('filters:', filters); - resp.json(await charMan.list(filters)); }); });