Various fixes to address issues in app

This commit is contained in:
rijkvanzanten
2020-07-03 16:41:53 -04:00
parent afa38fbe8a
commit 2b50baa13d
8 changed files with 66 additions and 139 deletions

View File

@@ -3,133 +3,6 @@ import { uniq } from 'lodash';
import database from './index';
import { Query } from '../types/query';
// const testAST: AST = {
// type: 'collection',
// name: 'articles',
// query: {},
// children: [
// {
// type: 'field',
// name: 'id'
// },
// {
// type: 'field',
// name: 'title',
// },
// {
// type: 'collection',
// name: 'authors',
// fieldKey: 'author_id',
// parentKey: 'id',
// relation: {
// id: 2,
// collection_many: 'articles',
// field_many: 'author_id',
// collection_one: 'authors',
// primary_one: 'id',
// field_one: null
// },
// query: {},
// children: [
// {
// type: 'field',
// name: 'id'
// },
// {
// type: 'field',
// name: 'name'
// },
// {
// type: 'collection',
// name: 'movies',
// fieldKey: 'movies',
// parentKey: 'id',
// relation: {
// id: 3,
// collection_many: 'movies',
// field_many: 'author_id',
// collection_one: 'authors',
// primary_one: 'id',
// field_one: 'movies'
// },
// query: {},
// children: [
// {
// type: 'field',
// name: 'id',
// },
// {
// type: 'field',
// name: 'title'
// },
// {
// type: 'collection',
// name: 'authors',
// fieldKey: 'author_id',
// parentKey: 'id',
// relation: {
// id: 4,
// collection_many: 'movies',
// field_many: 'author_id',
// collection_one: 'authors',
// primary_one: 'id',
// field_one: 'movies',
// },
// query: {},
// children: [
// {
// type: 'field',
// name: 'id',
// },
// {
// type: 'field',
// name: 'name',
// },
// {
// type: 'collection',
// name: 'movies',
// fieldKey: 'movies',
// parentKey: 'id',
// relation: {
// id: 6,
// collection_many: 'movies',
// field_many: 'author_id',
// collection_one: 'authors',
// primary_one: 'id',
// field_one: 'movies'
// },
// query: {
// sort: [
// {
// column: 'title',
// order: 'asc'
// }
// ]
// },
// children: [
// {
// type: 'field',
// name: 'id'
// },
// {
// type: 'field',
// name: 'title'
// },
// {
// type: 'field',
// name: 'author_id'
// }
// ]
// }
// ]
// }
// ]
// }
// ]
// }
// ]
// }
export default async function runAST(ast: AST, query = ast.query) {
const toplevelFields: string[] = [];
const nestedCollections: NestedCollectionAST[] = [];
@@ -210,7 +83,10 @@ export default async function runAST(ast: AST, query = ast.query) {
{
column: 'id',
operator: 'in',
value: uniq(results.map((res) => res[batch.relation.field_many])),
// filter removes null / undefined
value: uniq(results.map((res) => res[batch.relation.field_many])).filter(
(id) => id
),
},
],
};
@@ -222,7 +98,8 @@ export default async function runAST(ast: AST, query = ast.query) {
{
column: batch.relation.field_many,
operator: 'in',
value: uniq(results.map((res) => res[batch.parentKey])),
// filter removes null / undefined
value: uniq(results.map((res) => res[batch.parentKey])).filter((id) => id),
},
],
};
@@ -234,9 +111,12 @@ export default async function runAST(ast: AST, query = ast.query) {
if (m2o) {
return {
...record,
[batch.fieldKey]: nestedResults.find((nestedRecord) => {
return nestedRecord[batch.relation.primary_one] === record[batch.fieldKey];
}),
[batch.fieldKey]:
nestedResults.find((nestedRecord) => {
return (
nestedRecord[batch.relation.primary_one] === record[batch.fieldKey]
);
}) || null,
};
}

View File

@@ -18,8 +18,8 @@ const validateQuery: RequestHandler = asyncHandler(async (req, res, next) => {
const query: Query = req.sanitizedQuery;
await Promise.all([
validateParams(req.params.collection, query),
validateFields(req.params.collection, query),
validateParams(req.collection, query),
validateFields(req.collection, query),
validateMeta(query),
]);

View File

@@ -14,6 +14,7 @@ const router = Router();
const loginSchema = Joi.object({
email: Joi.string().email().required(),
password: Joi.string().required(),
mode: Joi.string().valid('cookie', 'json'),
});
router.post(

View File

@@ -4,7 +4,7 @@ import sanitizeQuery from '../middleware/sanitize-query';
import validateQuery from '../middleware/validate-query';
import * as UsersService from '../services/users';
import Joi from '@hapi/joi';
import { InvalidPayloadException } from '../exceptions';
import { InvalidPayloadException, InvalidCredentialsException } from '../exceptions';
import useCollection from '../middleware/use-collection';
import * as ActivityService from '../services/activity';
@@ -41,6 +41,21 @@ router.get(
})
);
router.get(
'/me',
useCollection('directus_users'),
sanitizeQuery,
validateQuery,
asyncHandler(async (req, res) => {
if (!req.user) {
throw new InvalidCredentialsException();
}
const item = await UsersService.readUser(req.user, req.sanitizedQuery);
return res.json({ data: item });
})
);
router.get(
'/:pk',
useCollection('directus_users'),
@@ -52,6 +67,31 @@ router.get(
})
);
router.patch(
'/me',
useCollection('directus_users'),
sanitizeQuery,
validateQuery,
asyncHandler(async (req, res) => {
if (!req.user) {
throw new InvalidCredentialsException();
}
const item = await UsersService.updateUser(req.user, req.body, req.sanitizedQuery);
ActivityService.createActivity({
action: ActivityService.Action.UPDATE,
collection: req.collection,
item: item.id,
ip: req.ip,
user_agent: req.get('user-agent'),
action_by: req.user,
});
return res.json({ data: item });
})
);
router.patch(
'/:pk',
useCollection('directus_users'),

View File

@@ -21,7 +21,7 @@ export const authenticate = async (email: string, password?: string) => {
* email to leak anywhere else.. We might have to make a dedicated "copy" of this function to
* signal the difference
*/
if (password !== undefined && (await argon2.verify(password, user.password)) === false) {
if (password !== undefined && (await argon2.verify(user.password, password)) === false) {
throw new InvalidCredentialsException();
}

View File

@@ -32,7 +32,7 @@ export const readItem = async <T = any>(
query = {
...query,
filter: [
...query.filter,
...(query.filter || []),
{
column: primaryKeyField,
operator: 'eq',

View File

@@ -2,8 +2,12 @@ import { Query } from '../types/query';
import * as ItemsService from './items';
export const readSettings = async (pk: string | number, query: Query) => {
/** @TODO only fetch the one item that exists, or default to default values if it doesn't */
return await ItemsService.readItem('directus_settings', pk, query);
const settings = await ItemsService.readItems('directus_settings', {
...query,
limit: 1,
});
return settings[0];
};
export const updateSettings = async (

View File

@@ -117,6 +117,8 @@ export default async function getAST(collection: string, query: Query): Promise<
function getRelatedCollection(collection: string, field: string) {
const relation = getRelation(collection, field);
if (!relation) return null;
if (relation.collection_many === collection && relation.field_many === field) {
return relation.collection_one;
}