merge master
This commit is contained in:
27
src/client/components/forms/Form/RowModified/index.js
Normal file
27
src/client/components/forms/Form/RowModified/index.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import React, {
|
||||
createContext, useContext,
|
||||
} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const Context = createContext({});
|
||||
|
||||
export const RowModifiedProvider = ({ children, lastModified }) => {
|
||||
return (
|
||||
<Context.Provider value={lastModified}>
|
||||
{children}
|
||||
</Context.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useRowModified = () => useContext(Context);
|
||||
|
||||
RowModifiedProvider.defaultProps = {
|
||||
lastModified: null,
|
||||
};
|
||||
|
||||
RowModifiedProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
lastModified: PropTypes.number,
|
||||
};
|
||||
|
||||
export default Context;
|
||||
@@ -144,6 +144,24 @@ const Form = (props) => {
|
||||
fields,
|
||||
processing,
|
||||
submitted,
|
||||
countRows: (rowName) => {
|
||||
const namePrefixToRemove = rowName.substring(0, rowName.lastIndexOf('.') + 1);
|
||||
|
||||
const rows = Object.keys(fields).reduce((matchedRows, key) => {
|
||||
if (key.indexOf(`${rowName}.`) === 0) {
|
||||
return {
|
||||
...matchedRows,
|
||||
[key.replace(namePrefixToRemove, '')]: fields[key],
|
||||
};
|
||||
}
|
||||
|
||||
return matchedRows;
|
||||
}, {});
|
||||
|
||||
const unflattenedRows = unflatten(rows);
|
||||
const rowCount = unflattenedRows[rowName.replace(namePrefixToRemove, '')]?.length || 0;
|
||||
return rowCount;
|
||||
},
|
||||
}}
|
||||
>
|
||||
<HiddenInput
|
||||
|
||||
@@ -80,10 +80,12 @@ function fieldReducer(state, action) {
|
||||
// Add new object containing subfield names to unflattenedRows array
|
||||
unflattenedRows.splice(rowIndex + 1, 0, subFields);
|
||||
|
||||
return {
|
||||
const newState = {
|
||||
...remainingFlattenedState,
|
||||
...(flatten({ [name]: unflattenedRows }, { filters: flattenFilters })),
|
||||
};
|
||||
|
||||
return newState;
|
||||
}
|
||||
|
||||
case 'MOVE_ROW': {
|
||||
|
||||
@@ -11,13 +11,22 @@ const RenderFields = ({
|
||||
<>
|
||||
{fieldSchema.map((field, i) => {
|
||||
const { defaultValue } = field;
|
||||
const FieldComponent = customComponents?.[field.name]?.field || fieldTypes[field.type];
|
||||
|
||||
let FieldComponent = field.hidden ? fieldTypes.hidden : fieldTypes[field.type];
|
||||
if (customComponents?.[field.name]?.field) {
|
||||
FieldComponent = customComponents[field.name].field;
|
||||
}
|
||||
// let FieldComponent = fieldTypes[field.type];
|
||||
// if (field.hidden) {
|
||||
// FieldComponent = fieldTypes.hidden;
|
||||
// }
|
||||
// if (customComponents?.[field.name]?.field) {
|
||||
// FieldComponent = customComponents[field.name].field;
|
||||
// }
|
||||
if (FieldComponent) {
|
||||
return (
|
||||
<FieldComponent
|
||||
fieldTypes={fieldTypes}
|
||||
key={i}
|
||||
key={field.name}
|
||||
{...field}
|
||||
validate={field.validate ? value => field.validate(value, field) : undefined}
|
||||
defaultValue={initialData[field.name] || defaultValue}
|
||||
@@ -56,7 +65,9 @@ RenderFields.propTypes = {
|
||||
).isRequired,
|
||||
initialData: PropTypes.shape({}),
|
||||
customComponents: PropTypes.shape({}),
|
||||
fieldTypes: PropTypes.shape({}).isRequired,
|
||||
fieldTypes: PropTypes.shape({
|
||||
hidden: PropTypes.node,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default RenderFields;
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import React, {
|
||||
useContext, useEffect, useReducer, useState, Fragment,
|
||||
useContext, useEffect, useReducer, useState,
|
||||
} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
|
||||
import { useModal } from '@trbl/react-modal';
|
||||
|
||||
import { RowModifiedProvider, useRowModified } from '../../Form/RowModified';
|
||||
import withCondition from '../../withCondition';
|
||||
import Button from '../../../controls/Button';
|
||||
import FormContext from '../../Form/Context';
|
||||
import Section from '../../../layout/Section';
|
||||
import AddRowModal from './AddRowModal';
|
||||
import collapsibleReducer from './reducer';
|
||||
import DraggableSection from '../../DraggableSection'; // eslint-disable-line import/no-cycle
|
||||
import DraggableSection from '../../DraggableSection';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
@@ -27,15 +28,16 @@ const Flexible = (props) => {
|
||||
fieldTypes,
|
||||
} = props;
|
||||
|
||||
const parentRowsModified = useRowModified();
|
||||
const { toggle: toggleModal, closeAll: closeAllModals } = useModal();
|
||||
const [rowIndexBeingAdded, setRowIndexBeingAdded] = useState(null);
|
||||
const [hasModifiedRows, setHasModifiedRows] = useState(false);
|
||||
const [lastModified, setLastModified] = useState(null);
|
||||
const [rowCount, setRowCount] = useState(0);
|
||||
const [collapsibleStates, dispatchCollapsibleStates] = useReducer(collapsibleReducer, []);
|
||||
const formContext = useContext(FormContext);
|
||||
const modalSlug = `flexible-${name}`;
|
||||
|
||||
const { fields: fieldState, dispatchFields } = formContext;
|
||||
const { fields: fieldState, dispatchFields, countRows } = formContext;
|
||||
|
||||
const addRow = (rowIndex, blockType) => {
|
||||
const blockToAdd = blocks.find(block => block.slug === blockType);
|
||||
@@ -49,7 +51,7 @@ const Flexible = (props) => {
|
||||
});
|
||||
|
||||
setRowCount(rowCount + 1);
|
||||
setHasModifiedRows(true);
|
||||
setLastModified(Date.now());
|
||||
};
|
||||
|
||||
const removeRow = (rowIndex) => {
|
||||
@@ -63,7 +65,7 @@ const Flexible = (props) => {
|
||||
});
|
||||
|
||||
setRowCount(rowCount - 1);
|
||||
setHasModifiedRows(true);
|
||||
setLastModified(Date.now());
|
||||
};
|
||||
|
||||
const moveRow = (moveFromIndex, moveToIndex) => {
|
||||
@@ -75,7 +77,7 @@ const Flexible = (props) => {
|
||||
type: 'MOVE_COLLAPSIBLE', collapsibleIndex: moveFromIndex, moveToIndex,
|
||||
});
|
||||
|
||||
setHasModifiedRows(true);
|
||||
setLastModified(Date.now());
|
||||
};
|
||||
|
||||
const openAddRowModal = (rowIndex) => {
|
||||
@@ -90,9 +92,16 @@ const Flexible = (props) => {
|
||||
moveRow(sourceIndex, destinationIndex);
|
||||
};
|
||||
|
||||
const updateRowCountOnParentRowModified = () => {
|
||||
const countedRows = countRows(name);
|
||||
setRowCount(countedRows);
|
||||
};
|
||||
|
||||
useEffect(updateRowCountOnParentRowModified, [parentRowsModified]);
|
||||
|
||||
useEffect(() => {
|
||||
setRowCount(defaultValue.length);
|
||||
setHasModifiedRows(false);
|
||||
setLastModified(null);
|
||||
|
||||
dispatchCollapsibleStates({
|
||||
type: 'SET_ALL_COLLAPSIBLES',
|
||||
@@ -101,7 +110,7 @@ const Flexible = (props) => {
|
||||
}, [defaultValue]);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<RowModifiedProvider lastModified={lastModified}>
|
||||
<DragDropContext onDragEnd={onDragEnd}>
|
||||
<div className={baseClass}>
|
||||
<Section
|
||||
@@ -117,7 +126,7 @@ const Flexible = (props) => {
|
||||
{rowCount !== 0 && Array.from(Array(rowCount).keys()).map((_, rowIndex) => {
|
||||
let blockType = fieldState[`${name}.${rowIndex}.blockType`]?.value;
|
||||
|
||||
if (!hasModifiedRows && !blockType) {
|
||||
if (!lastModified && !blockType) {
|
||||
blockType = defaultValue?.[rowIndex]?.blockType;
|
||||
}
|
||||
|
||||
@@ -137,14 +146,16 @@ const Flexible = (props) => {
|
||||
...blockToRender.fields,
|
||||
{
|
||||
name: 'blockType',
|
||||
type: 'hidden',
|
||||
type: 'text',
|
||||
hidden: true,
|
||||
}, {
|
||||
name: 'blockName',
|
||||
type: 'hidden',
|
||||
type: 'text',
|
||||
hidden: true,
|
||||
},
|
||||
]}
|
||||
singularLabel={blockType}
|
||||
defaultValue={hasModifiedRows ? undefined : defaultValue[rowIndex]}
|
||||
defaultValue={lastModified ? undefined : defaultValue[rowIndex]}
|
||||
dispatchCollapsibleStates={dispatchCollapsibleStates}
|
||||
collapsibleStates={collapsibleStates}
|
||||
blockType="flexible"
|
||||
@@ -178,7 +189,7 @@ const Flexible = (props) => {
|
||||
slug={modalSlug}
|
||||
blocks={blocks}
|
||||
/>
|
||||
</Fragment>
|
||||
</RowModifiedProvider>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,11 +4,12 @@ import React, {
|
||||
import PropTypes from 'prop-types';
|
||||
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
|
||||
|
||||
import { RowModifiedProvider, useRowModified } from '../../Form/RowModified';
|
||||
import withCondition from '../../withCondition';
|
||||
import Button from '../../../controls/Button';
|
||||
import FormContext from '../../Form/Context';
|
||||
import Section from '../../../layout/Section';
|
||||
import DraggableSection from '../../DraggableSection'; // eslint-disable-line import/no-cycle
|
||||
import DraggableSection from '../../DraggableSection';
|
||||
import collapsibleReducer from './reducer';
|
||||
|
||||
import './index.scss';
|
||||
@@ -16,11 +17,12 @@ import './index.scss';
|
||||
const baseClass = 'field-type repeater';
|
||||
|
||||
const Repeater = (props) => {
|
||||
const parentRowsModified = useRowModified();
|
||||
const [collapsibleStates, dispatchCollapsibleStates] = useReducer(collapsibleReducer, []);
|
||||
const formContext = useContext(FormContext);
|
||||
const [rowCount, setRowCount] = useState(0);
|
||||
const [hasModifiedRows, setHasModifiedRows] = useState(false);
|
||||
const { fields: fieldState, dispatchFields } = formContext;
|
||||
const [lastModified, setLastModified] = useState(null);
|
||||
const { fields: fieldState, dispatchFields, countRows } = formContext;
|
||||
|
||||
const {
|
||||
label,
|
||||
@@ -41,7 +43,7 @@ const Repeater = (props) => {
|
||||
});
|
||||
|
||||
setRowCount(rowCount + 1);
|
||||
setHasModifiedRows(true);
|
||||
setLastModified(Date.now());
|
||||
};
|
||||
|
||||
const removeRow = (rowIndex) => {
|
||||
@@ -55,7 +57,7 @@ const Repeater = (props) => {
|
||||
});
|
||||
|
||||
setRowCount(rowCount - 1);
|
||||
setHasModifiedRows(true);
|
||||
setLastModified(Date.now());
|
||||
};
|
||||
|
||||
const moveRow = (moveFromIndex, moveToIndex) => {
|
||||
@@ -67,11 +69,12 @@ const Repeater = (props) => {
|
||||
type: 'MOVE_COLLAPSIBLE', collapsibleIndex: moveFromIndex, moveToIndex,
|
||||
});
|
||||
|
||||
setHasModifiedRows(true);
|
||||
setLastModified(Date.now());
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setRowCount(defaultValue.length);
|
||||
setLastModified(null);
|
||||
|
||||
dispatchCollapsibleStates({
|
||||
type: 'SET_ALL_COLLAPSIBLES',
|
||||
@@ -79,6 +82,13 @@ const Repeater = (props) => {
|
||||
});
|
||||
}, [defaultValue]);
|
||||
|
||||
const updateRowCountOnParentRowModified = () => {
|
||||
const countedRows = countRows(name);
|
||||
setRowCount(countedRows);
|
||||
};
|
||||
|
||||
useEffect(updateRowCountOnParentRowModified, [parentRowsModified]);
|
||||
|
||||
const onDragEnd = (result) => {
|
||||
if (!result.destination) return;
|
||||
const sourceIndex = result.source.index;
|
||||
@@ -87,54 +97,56 @@ const Repeater = (props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<DragDropContext onDragEnd={onDragEnd}>
|
||||
<div className={baseClass}>
|
||||
<Section heading={label}>
|
||||
<>
|
||||
<Droppable droppableId="repeater-drop">
|
||||
{provided => (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
{...provided.droppableProps}
|
||||
<RowModifiedProvider lastModified={lastModified}>
|
||||
<DragDropContext onDragEnd={onDragEnd}>
|
||||
<div className={baseClass}>
|
||||
<Section heading={label}>
|
||||
<>
|
||||
<Droppable droppableId="repeater-drop">
|
||||
{provided => (
|
||||
<div
|
||||
ref={provided.innerRef}
|
||||
{...provided.droppableProps}
|
||||
>
|
||||
{rowCount !== 0
|
||||
&& Array.from(Array(rowCount).keys()).map((_, rowIndex) => {
|
||||
return (
|
||||
<DraggableSection
|
||||
fieldTypes={fieldTypes}
|
||||
key={rowIndex}
|
||||
parentName={name}
|
||||
singularLabel={singularLabel}
|
||||
addRow={() => addRow(rowIndex)}
|
||||
removeRow={() => removeRow(rowIndex)}
|
||||
rowIndex={rowIndex}
|
||||
fieldState={fieldState}
|
||||
fieldSchema={fields}
|
||||
defaultValue={lastModified ? undefined : defaultValue[rowIndex]}
|
||||
dispatchCollapsibleStates={dispatchCollapsibleStates}
|
||||
collapsibleStates={collapsibleStates}
|
||||
/>
|
||||
);
|
||||
})
|
||||
}
|
||||
{provided.placeholder}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
|
||||
<div className={`${baseClass}__add-button-wrap`}>
|
||||
<Button
|
||||
onClick={() => addRow(rowCount)}
|
||||
type="secondary"
|
||||
>
|
||||
{rowCount !== 0
|
||||
&& Array.from(Array(rowCount).keys()).map((_, rowIndex) => {
|
||||
return (
|
||||
<DraggableSection
|
||||
fieldTypes={fieldTypes}
|
||||
key={rowIndex}
|
||||
parentName={name}
|
||||
singularLabel={singularLabel}
|
||||
addRow={() => addRow(rowIndex)}
|
||||
removeRow={() => removeRow(rowIndex)}
|
||||
rowIndex={rowIndex}
|
||||
fieldState={fieldState}
|
||||
fieldSchema={fields}
|
||||
defaultValue={hasModifiedRows ? undefined : defaultValue[rowIndex]}
|
||||
dispatchCollapsibleStates={dispatchCollapsibleStates}
|
||||
collapsibleStates={collapsibleStates}
|
||||
/>
|
||||
);
|
||||
})
|
||||
}
|
||||
{provided.placeholder}
|
||||
</div>
|
||||
)}
|
||||
</Droppable>
|
||||
{`Add ${singularLabel}`}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
</Section>
|
||||
|
||||
<div className={`${baseClass}__add-button-wrap`}>
|
||||
<Button
|
||||
onClick={() => addRow(rowCount)}
|
||||
type="secondary"
|
||||
>
|
||||
{`Add ${singularLabel}`}
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
</Section>
|
||||
|
||||
</div>
|
||||
</DragDropContext>
|
||||
</div>
|
||||
</DragDropContext>
|
||||
</RowModifiedProvider>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -2,21 +2,17 @@
|
||||
const { create } = require('../../operations');
|
||||
|
||||
const createResolver = collection => async (_, args, context) => {
|
||||
if (args.locale) {
|
||||
context.locale = args.locale;
|
||||
}
|
||||
|
||||
const options = {
|
||||
config: collection.config,
|
||||
Model: collection.Model,
|
||||
data: args.data,
|
||||
user: context.user,
|
||||
api: 'GraphQL',
|
||||
locale: context.locale,
|
||||
fallbackLocale: context.fallbackLocale,
|
||||
req: context,
|
||||
};
|
||||
|
||||
if (args.locale) {
|
||||
context.locale = args.locale;
|
||||
options.locale = args.locale;
|
||||
}
|
||||
|
||||
const result = await create(options);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -2,26 +2,16 @@
|
||||
const { deleteQuery } = require('../../operations');
|
||||
|
||||
const deleteResolver = collection => async (_, args, context) => {
|
||||
if (args.locale) context.locale = args.locale;
|
||||
if (args.fallbackLocale) context.fallbackLocale = args.fallbackLocale;
|
||||
|
||||
const options = {
|
||||
config: collection.config,
|
||||
Model: collection.Model,
|
||||
id: args.id,
|
||||
user: context.user,
|
||||
api: 'GraphQL',
|
||||
locale: context.locale,
|
||||
fallbackLocale: context.fallbackLocale,
|
||||
req: context,
|
||||
};
|
||||
|
||||
if (args.locale) {
|
||||
context.locale = args.locale;
|
||||
options.locale = args.locale;
|
||||
}
|
||||
|
||||
if (args.fallbackLocale) {
|
||||
context.fallbackLocale = args.fallbackLocale;
|
||||
options.fallbackLocale = args.fallbackLocale;
|
||||
}
|
||||
|
||||
const result = await deleteQuery(options);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
const { find } = require('../../operations');
|
||||
|
||||
const findResolver = collection => async (_, args, context) => {
|
||||
if (args.locale) context.locale = args.locale;
|
||||
if (args.fallbackLocale) context.fallbackLocale = args.fallbackLocale;
|
||||
|
||||
const options = {
|
||||
config: collection.config,
|
||||
Model: collection.Model,
|
||||
@@ -10,22 +13,9 @@ const findResolver = collection => async (_, args, context) => {
|
||||
limit: args.limit,
|
||||
page: args.page,
|
||||
sort: args.sort,
|
||||
user: context.user,
|
||||
api: 'GraphQL',
|
||||
locale: context.locale,
|
||||
fallbackLocale: context.fallbackLocale,
|
||||
req: context,
|
||||
};
|
||||
|
||||
if (args.locale) {
|
||||
context.locale = args.locale;
|
||||
options.locale = args.locale;
|
||||
}
|
||||
|
||||
if (args.fallbackLocale) {
|
||||
context.fallbackLocale = args.fallbackLocale;
|
||||
options.fallbackLocale = args.fallbackLocale;
|
||||
}
|
||||
|
||||
const results = await find(options);
|
||||
|
||||
return results;
|
||||
|
||||
@@ -2,27 +2,17 @@
|
||||
const { findByID } = require('../../operations');
|
||||
|
||||
const findByIDResolver = collection => async (_, args, context) => {
|
||||
if (args.locale) context.locale = args.locale;
|
||||
if (args.fallbackLocale) context.fallbackLocale = args.fallbackLocale;
|
||||
|
||||
const options = {
|
||||
config: collection.config,
|
||||
Model: collection.Model,
|
||||
depth: 0,
|
||||
id: args.id,
|
||||
user: context.user,
|
||||
api: 'GraphQL',
|
||||
locale: context.locale,
|
||||
fallbackLocale: context.fallbackLocale,
|
||||
req: context,
|
||||
};
|
||||
|
||||
if (args.locale) {
|
||||
context.locale = args.locale;
|
||||
options.locale = args.locale;
|
||||
}
|
||||
|
||||
if (args.fallbackLocale) {
|
||||
context.fallbackLocale = args.fallbackLocale;
|
||||
options.fallbackLocale = args.fallbackLocale;
|
||||
}
|
||||
|
||||
const result = await findByID(options);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -2,28 +2,18 @@
|
||||
const { update } = require('../../operations');
|
||||
|
||||
const updateResolver = collection => async (_, args, context) => {
|
||||
if (args.locale) context.locale = args.locale;
|
||||
if (args.fallbackLocale) context.fallbackLocale = args.fallbackLocale;
|
||||
|
||||
const options = {
|
||||
config: collection.config,
|
||||
Model: collection.Model,
|
||||
locale: context.locale,
|
||||
fallbackLocale: context.fallbackLocale,
|
||||
data: args.data,
|
||||
id: args.id,
|
||||
user: context.user,
|
||||
api: 'GraphQL',
|
||||
depth: 0,
|
||||
req: context,
|
||||
};
|
||||
|
||||
if (args.locale) {
|
||||
context.locale = args.locale;
|
||||
options.locale = args.locale;
|
||||
}
|
||||
|
||||
if (args.fallbackLocale) {
|
||||
context.fallbackLocale = args.fallbackLocale;
|
||||
options.fallbackLocale = args.fallbackLocale;
|
||||
}
|
||||
|
||||
const result = await update(options);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -10,15 +10,7 @@ const create = async (args) => {
|
||||
|
||||
await executePolicy(args, args.config.policies.create);
|
||||
|
||||
let options = {
|
||||
Model: args.Model,
|
||||
config: args.config,
|
||||
locale: args.locale,
|
||||
fallbackLocale: args.fallbackLocale,
|
||||
user: args.user,
|
||||
api: args.api,
|
||||
data: args.data,
|
||||
};
|
||||
let options = { ...args };
|
||||
|
||||
// /////////////////////////////////////
|
||||
// 2. Validate incoming data
|
||||
@@ -48,9 +40,11 @@ const create = async (args) => {
|
||||
|
||||
const {
|
||||
Model,
|
||||
locale,
|
||||
fallbackLocale,
|
||||
data,
|
||||
req: {
|
||||
locale,
|
||||
fallbackLocale,
|
||||
},
|
||||
} = options;
|
||||
|
||||
let result = new Model();
|
||||
|
||||
@@ -9,15 +9,7 @@ const deleteQuery = async (args) => {
|
||||
|
||||
await executePolicy(args, args.config.policies.delete);
|
||||
|
||||
let options = {
|
||||
id: args.id,
|
||||
Model: args.Model,
|
||||
config: args.config,
|
||||
locale: args.locale,
|
||||
fallbackLocale: args.fallbackLocale,
|
||||
user: args.user,
|
||||
api: args.api,
|
||||
};
|
||||
let options = { ...args };
|
||||
|
||||
// /////////////////////////////////////
|
||||
// 2. Execute before collection hook
|
||||
@@ -36,8 +28,10 @@ const deleteQuery = async (args) => {
|
||||
const {
|
||||
Model,
|
||||
id,
|
||||
locale,
|
||||
fallbackLocale,
|
||||
req: {
|
||||
locale,
|
||||
fallbackLocale,
|
||||
},
|
||||
} = options;
|
||||
|
||||
let result = await Model.findOneAndDelete({ _id: id });
|
||||
|
||||
@@ -13,17 +13,8 @@ const find = async (args) => {
|
||||
if (args.where) queryToBuild.where = args.where;
|
||||
|
||||
let options = {
|
||||
...args,
|
||||
query: await args.Model.buildQuery(queryToBuild, args.locale),
|
||||
Model: args.Model,
|
||||
locale: args.locale,
|
||||
fallbackLocale: args.fallbackLocale,
|
||||
page: args.page,
|
||||
limit: args.limit,
|
||||
sort: args.sort,
|
||||
depth: args.depth,
|
||||
config: args.config,
|
||||
user: args.user,
|
||||
api: args.api,
|
||||
};
|
||||
|
||||
// /////////////////////////////////////
|
||||
@@ -45,11 +36,13 @@ const find = async (args) => {
|
||||
page,
|
||||
limit,
|
||||
sort,
|
||||
api,
|
||||
depth,
|
||||
Model,
|
||||
locale,
|
||||
fallbackLocale,
|
||||
req: {
|
||||
locale,
|
||||
fallbackLocale,
|
||||
payloadAPI,
|
||||
},
|
||||
} = options;
|
||||
|
||||
const optionsToExecute = {
|
||||
@@ -62,7 +55,7 @@ const find = async (args) => {
|
||||
// Only allow depth override within REST.
|
||||
// If allowed in GraphQL, it would break resolvers
|
||||
// as a full object will be returned instead of an ID string
|
||||
if (api === 'REST') {
|
||||
if (payloadAPI === 'REST') {
|
||||
if (depth && depth !== '0') {
|
||||
optionsToExecute.options.autopopulate = {
|
||||
maxDepth: parseInt(depth, 10),
|
||||
|
||||
@@ -12,14 +12,8 @@ const findByID = async (args) => {
|
||||
await executePolicy(args, policy);
|
||||
|
||||
let options = {
|
||||
...args,
|
||||
query: { _id: args.id },
|
||||
Model: args.Model,
|
||||
locale: args.locale,
|
||||
fallbackLocale: args.fallbackLocale,
|
||||
depth: args.depth,
|
||||
config: args.config,
|
||||
user: args.user,
|
||||
api: args.api,
|
||||
};
|
||||
|
||||
// /////////////////////////////////////
|
||||
@@ -38,11 +32,13 @@ const findByID = async (args) => {
|
||||
|
||||
const {
|
||||
depth,
|
||||
api,
|
||||
Model,
|
||||
query,
|
||||
locale,
|
||||
fallbackLocale,
|
||||
req: {
|
||||
locale,
|
||||
fallbackLocale,
|
||||
payloadAPI,
|
||||
},
|
||||
} = options;
|
||||
|
||||
const queryOptionsToExecute = {
|
||||
@@ -52,7 +48,7 @@ const findByID = async (args) => {
|
||||
// Only allow depth override within REST.
|
||||
// If allowed in GraphQL, it would break resolvers
|
||||
// as a full object will be returned instead of an ID string
|
||||
if (api === 'REST') {
|
||||
if (payloadAPI === 'REST') {
|
||||
if (depth && depth !== '0') {
|
||||
queryOptionsToExecute.options.autopopulate = {
|
||||
maxDepth: parseInt(depth, 10),
|
||||
|
||||
@@ -11,13 +11,7 @@ const update = async (args) => {
|
||||
|
||||
await executePolicy(args, args.config.policies.update);
|
||||
|
||||
let options = {
|
||||
Model: args.Model,
|
||||
locale: args.locale,
|
||||
fallbackLocale: args.fallbackLocale,
|
||||
id: args.id,
|
||||
data: args.data,
|
||||
};
|
||||
let options = { ...args };
|
||||
|
||||
// /////////////////////////////////////
|
||||
// 2. Validate incoming data
|
||||
@@ -48,8 +42,10 @@ const update = async (args) => {
|
||||
const {
|
||||
Model,
|
||||
id,
|
||||
locale,
|
||||
fallbackLocale,
|
||||
req: {
|
||||
locale,
|
||||
fallbackLocale,
|
||||
},
|
||||
data,
|
||||
} = options;
|
||||
|
||||
|
||||
@@ -6,12 +6,10 @@ const { create } = require('../operations');
|
||||
const createHandler = async (req, res) => {
|
||||
try {
|
||||
const doc = await create({
|
||||
req,
|
||||
Model: req.Model,
|
||||
config: req.collection,
|
||||
user: req.user,
|
||||
data: req.body,
|
||||
locale: req.locale,
|
||||
api: 'REST',
|
||||
});
|
||||
|
||||
return res.status(httpStatus.CREATED).json({
|
||||
|
||||
@@ -5,13 +5,10 @@ const { deleteQuery } = require('../operations');
|
||||
const deleteHandler = async (req, res) => {
|
||||
try {
|
||||
const doc = await deleteQuery({
|
||||
req,
|
||||
Model: req.Model,
|
||||
config: req.collection,
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
locale: req.locale,
|
||||
fallbackLocale: req.fallbackLocale,
|
||||
api: 'REST',
|
||||
});
|
||||
|
||||
if (!doc) {
|
||||
|
||||
@@ -4,17 +4,14 @@ const { find } = require('../operations');
|
||||
const findHandler = async (req, res) => {
|
||||
try {
|
||||
const options = {
|
||||
req,
|
||||
Model: req.Model,
|
||||
config: req.collection,
|
||||
where: req.query.where,
|
||||
locale: req.locale,
|
||||
fallbackLocale: req.fallbackLocale,
|
||||
page: req.query.page,
|
||||
limit: req.query.limit,
|
||||
sort: req.query.sort,
|
||||
depth: req.query.depth,
|
||||
user: req.user,
|
||||
api: 'REST',
|
||||
};
|
||||
|
||||
const result = await find(options);
|
||||
|
||||
@@ -4,14 +4,11 @@ const formatErrorResponse = require('../../express/responses/formatError');
|
||||
|
||||
const findByIDHandler = async (req, res) => {
|
||||
const options = {
|
||||
req,
|
||||
Model: req.Model,
|
||||
config: req.collection,
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
locale: req.locale,
|
||||
fallbackLocale: req.fallbackLocale,
|
||||
depth: req.query.depth,
|
||||
api: 'REST',
|
||||
};
|
||||
|
||||
try {
|
||||
|
||||
@@ -6,13 +6,11 @@ const { update } = require('../operations');
|
||||
const updateHandler = async (req, res) => {
|
||||
try {
|
||||
const doc = await update({
|
||||
req,
|
||||
Model: req.Model,
|
||||
config: req.collection,
|
||||
user: req.user,
|
||||
id: req.params.id,
|
||||
data: req.body,
|
||||
locale: req.locale,
|
||||
api: 'REST',
|
||||
});
|
||||
|
||||
return res.status(httpStatus.OK).json({
|
||||
|
||||
8
src/express/middleware/identifyAPI.js
Normal file
8
src/express/middleware/identifyAPI.js
Normal file
@@ -0,0 +1,8 @@
|
||||
const identifyAPI = (api) => {
|
||||
return (req, _, next) => {
|
||||
req.payloadAPI = api;
|
||||
next();
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = identifyAPI;
|
||||
@@ -6,6 +6,7 @@ const methodOverride = require('method-override');
|
||||
const cookieParser = require('cookie-parser');
|
||||
const localizationMiddleware = require('../../localization/middleware');
|
||||
const authenticate = require('./authenticate');
|
||||
const identifyAPI = require('./identifyAPI');
|
||||
|
||||
const middleware = (config) => {
|
||||
return [
|
||||
@@ -19,6 +20,7 @@ const middleware = (config) => {
|
||||
compression(config.compression),
|
||||
localizationMiddleware(config.localization),
|
||||
authenticate,
|
||||
identifyAPI('REST'),
|
||||
(req, res, next) => {
|
||||
if (config.cors) {
|
||||
if (config.cors.indexOf(req.headers.origin) > -1) {
|
||||
|
||||
@@ -2,7 +2,7 @@ const { Schema } = require('mongoose');
|
||||
|
||||
const formatBaseSchema = (field) => {
|
||||
return {
|
||||
hide: field.hide || false,
|
||||
hidden: field.hidden || false,
|
||||
localized: field.localized || false,
|
||||
unique: field.unique || false,
|
||||
required: (field.required && !field.localized) || false,
|
||||
@@ -32,9 +32,6 @@ const fieldToSchemaMap = {
|
||||
checkbox: (field) => {
|
||||
return { ...formatBaseSchema(field), type: Boolean };
|
||||
},
|
||||
// hidden: (field) => {
|
||||
// return { ...formatBaseSchema(field), type: String };
|
||||
// },
|
||||
date: (field) => {
|
||||
return {
|
||||
...formatBaseSchema(field),
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
const { findOne } = require('../../operations');
|
||||
|
||||
const findOneResolver = (Model, config) => async (_, args, context) => {
|
||||
if (args.locale) context.locale = args.locale;
|
||||
if (args.fallbackLocale) context.fallbackLocale = args.fallbackLocale;
|
||||
|
||||
const { slug } = config;
|
||||
|
||||
const options = {
|
||||
@@ -9,20 +12,9 @@ const findOneResolver = (Model, config) => async (_, args, context) => {
|
||||
config,
|
||||
slug,
|
||||
depth: 0,
|
||||
api: 'GraphQL',
|
||||
user: context.user,
|
||||
req: context,
|
||||
};
|
||||
|
||||
if (args.locale) {
|
||||
context.locale = args.locale;
|
||||
options.locale = args.locale;
|
||||
}
|
||||
|
||||
if (args.fallbackLocale) {
|
||||
context.fallbackLocale = args.fallbackLocale;
|
||||
options.fallbackLocale = args.fallbackLocale;
|
||||
}
|
||||
|
||||
const result = await findOne(options);
|
||||
return result;
|
||||
};
|
||||
|
||||
@@ -2,30 +2,20 @@
|
||||
const { upsert } = require('../../operations');
|
||||
|
||||
const upsertResolver = (Model, config) => async (_, args, context) => {
|
||||
if (args.locale) context.locale = args.locale;
|
||||
if (args.fallbackLocale) context.fallbackLocale = args.fallbackLocale;
|
||||
|
||||
const { slug } = config;
|
||||
|
||||
const options = {
|
||||
config,
|
||||
Model,
|
||||
locale: context.locale,
|
||||
fallbackLocale: context.fallbackLocale,
|
||||
data: args.data,
|
||||
slug,
|
||||
depth: 0,
|
||||
api: 'GraphQL',
|
||||
user: context.user,
|
||||
req: context,
|
||||
};
|
||||
|
||||
if (args.locale) {
|
||||
context.locale = args.locale;
|
||||
options.locale = args.locale;
|
||||
}
|
||||
|
||||
if (args.fallbackLocale) {
|
||||
context.fallbackLocale = args.fallbackLocale;
|
||||
options.fallbackLocale = args.fallbackLocale;
|
||||
}
|
||||
|
||||
const result = await upsert(options);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -28,11 +28,13 @@ const findOne = async (args) => {
|
||||
|
||||
const {
|
||||
depth,
|
||||
api,
|
||||
Model,
|
||||
locale,
|
||||
slug,
|
||||
fallbackLocale,
|
||||
req: {
|
||||
payloadAPI,
|
||||
locale,
|
||||
fallbackLocale,
|
||||
},
|
||||
} = options;
|
||||
|
||||
const queryOptionsToExecute = {
|
||||
@@ -42,7 +44,7 @@ const findOne = async (args) => {
|
||||
// Only allow depth override within REST.
|
||||
// If allowed in GraphQL, it would break resolvers
|
||||
// as a full object will be returned instead of an ID string
|
||||
if (api === 'REST') {
|
||||
if (payloadAPI === 'REST') {
|
||||
if (depth && depth !== '0') {
|
||||
queryOptionsToExecute.options.autopopulate = {
|
||||
maxDepth: parseInt(depth, 10),
|
||||
|
||||
@@ -35,10 +35,12 @@ const upsert = async (args) => {
|
||||
|
||||
const {
|
||||
Model,
|
||||
locale,
|
||||
slug,
|
||||
fallbackLocale,
|
||||
data,
|
||||
req: {
|
||||
locale,
|
||||
fallbackLocale,
|
||||
},
|
||||
} = options;
|
||||
|
||||
|
||||
|
||||
@@ -7,14 +7,11 @@ const findOneHandler = (Model, config) => async (req, res) => {
|
||||
const { slug } = config;
|
||||
|
||||
const result = await findOne({
|
||||
req,
|
||||
Model,
|
||||
config,
|
||||
slug,
|
||||
depth: req.query.depth,
|
||||
locale: req.locale,
|
||||
fallbackLocale: req.fallbackLocale,
|
||||
api: 'REST',
|
||||
user: req.user,
|
||||
});
|
||||
|
||||
return res.status(httpStatus.OK).json(result);
|
||||
|
||||
@@ -7,14 +7,11 @@ const upsertHandler = (Model, config) => async (req, res) => {
|
||||
const { slug } = config;
|
||||
|
||||
const result = await upsert({
|
||||
req,
|
||||
Model,
|
||||
config,
|
||||
slug,
|
||||
depth: req.query.depth,
|
||||
locale: req.locale,
|
||||
fallbackLocale: req.fallbackLocale,
|
||||
api: 'REST',
|
||||
user: req.user,
|
||||
});
|
||||
|
||||
return res.status(httpStatus.OK).json({ message: 'Global saved successfully.', result });
|
||||
|
||||
@@ -15,6 +15,7 @@ const registerGlobals = require('./globals/register');
|
||||
const GraphQL = require('./graphql');
|
||||
const sanitizeConfig = require('./utilities/sanitizeConfig');
|
||||
const buildEmail = require('./email/build');
|
||||
const identifyAPI = require('./express/middleware/identifyAPI');
|
||||
|
||||
class Payload {
|
||||
constructor(options) {
|
||||
@@ -56,6 +57,7 @@ class Payload {
|
||||
// Init GraphQL
|
||||
this.router.use(
|
||||
this.config.routes.graphQL,
|
||||
identifyAPI('GraphQL'),
|
||||
createAuthHeaderFromCookie,
|
||||
authenticate,
|
||||
new GraphQL(this.config, this.collections, this.User, this.Upload, this.globals).init(),
|
||||
|
||||
@@ -2,12 +2,12 @@ module.exports = [
|
||||
{
|
||||
name: 'resetPasswordToken',
|
||||
type: 'text',
|
||||
// hide: true,
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
name: 'resetPasswordExpiration',
|
||||
type: 'date',
|
||||
// hide: true,
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
name: 'enableAPIKey',
|
||||
|
||||
@@ -11,7 +11,7 @@ const executePolicy = async (operation, policy) => {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (operation.user) {
|
||||
if (operation.req.user) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -163,6 +163,14 @@ function registerUser() {
|
||||
resolve: register(this.User),
|
||||
};
|
||||
|
||||
this.Mutation.fields.forgotPassword = {
|
||||
type: new GraphQLNonNull(GraphQLBoolean),
|
||||
args: {
|
||||
[useAsUsername]: { type: new GraphQLNonNull(GraphQLString) },
|
||||
},
|
||||
resolve: forgotPassword(this.User, this.email),
|
||||
};
|
||||
|
||||
this.Mutation.fields.resetPassword = {
|
||||
type: this.User.graphQL.type,
|
||||
args: {
|
||||
@@ -172,14 +180,6 @@ function registerUser() {
|
||||
resolve: resetPassword(this.User),
|
||||
};
|
||||
|
||||
this.Mutation.fields.forgotPassword = {
|
||||
type: new GraphQLNonNull(GraphQLBoolean),
|
||||
args: {
|
||||
[useAsUsername]: { type: GraphQLString },
|
||||
},
|
||||
resolve: forgotPassword(this.User, this.email),
|
||||
};
|
||||
|
||||
this.Mutation.fields.refreshToken = {
|
||||
type: GraphQLString,
|
||||
resolve: refresh(this.User),
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
const { forgotPassword } = require('../../operations');
|
||||
|
||||
const forgotPasswordResolver = ({ Model, config }, email) => async (_, args, context) => {
|
||||
const forgotPasswordResolver = (config, email) => async (_, args, context) => {
|
||||
const options = {
|
||||
Model,
|
||||
config,
|
||||
data: args,
|
||||
api: 'GraphQL',
|
||||
user: context.user,
|
||||
email,
|
||||
req: context,
|
||||
};
|
||||
|
||||
const result = await forgotPassword(options);
|
||||
|
||||
@@ -4,8 +4,7 @@ const { init } = require('../../operations');
|
||||
const initResolver = ({ Model }) => async (_, __, context) => {
|
||||
const options = {
|
||||
Model,
|
||||
api: 'GraphQL',
|
||||
user: context.user,
|
||||
req: context,
|
||||
};
|
||||
|
||||
const result = await init(options);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable no-param-reassign */
|
||||
const { login } = require('../../operations');
|
||||
|
||||
const loginResolver = ({ Model, config }) => async (_, args) => {
|
||||
const loginResolver = ({ Model, config }) => async (_, args, context) => {
|
||||
const usernameField = config.auth.useAsUsername;
|
||||
const options = {
|
||||
Model,
|
||||
@@ -10,7 +10,7 @@ const loginResolver = ({ Model, config }) => async (_, args) => {
|
||||
[usernameField]: args[usernameField],
|
||||
password: args.password,
|
||||
},
|
||||
api: 'GraphQL',
|
||||
req: context,
|
||||
};
|
||||
|
||||
const token = await login(options);
|
||||
|
||||
@@ -6,7 +6,7 @@ const refreshResolver = ({ Model, config }) => async (_, __, context) => {
|
||||
config,
|
||||
Model,
|
||||
authorization: context.headers.authorization,
|
||||
api: 'GraphQL',
|
||||
req: context,
|
||||
};
|
||||
|
||||
const refreshedToken = await refresh(options);
|
||||
|
||||
@@ -6,10 +6,8 @@ const registerResolver = ({ Model, config }) => async (_, args, context) => {
|
||||
config,
|
||||
Model,
|
||||
data: args.data,
|
||||
api: 'GraphQL',
|
||||
locale: context.locale,
|
||||
fallbackLocale: context.fallbackLocale,
|
||||
depth: 0,
|
||||
req: context,
|
||||
};
|
||||
|
||||
if (args.locale) {
|
||||
|
||||
@@ -2,10 +2,14 @@
|
||||
const { resetPassword } = require('../../operations');
|
||||
|
||||
const resetPasswordResolver = ({ Model, config }) => async (_, args, context) => {
|
||||
if (args.locale) context.locale = args.locale;
|
||||
if (args.fallbackLocale) context.fallbackLocale = args.fallbackLocale;
|
||||
|
||||
const options = {
|
||||
Model,
|
||||
config,
|
||||
data: args,
|
||||
req: context,
|
||||
api: 'GraphQL',
|
||||
user: context.user,
|
||||
};
|
||||
|
||||
@@ -2,28 +2,18 @@
|
||||
const { update } = require('../../operations');
|
||||
|
||||
const updateResolver = ({ Model, config }) => async (_, args, context) => {
|
||||
if (args.locale) context.locale = args.locale;
|
||||
if (args.fallbackLocale) context.fallbackLocale = args.fallbackLocale;
|
||||
|
||||
const options = {
|
||||
config,
|
||||
Model,
|
||||
data: args.data,
|
||||
id: args.id,
|
||||
api: 'GraphQL',
|
||||
user: context.user,
|
||||
locale: context.locale,
|
||||
fallbackLocale: context.fallbackLocale,
|
||||
depth: 0,
|
||||
req: context,
|
||||
};
|
||||
|
||||
if (args.locale) {
|
||||
context.locale = args.locale;
|
||||
options.locale = args.locale;
|
||||
}
|
||||
|
||||
if (args.fallbackLocale) {
|
||||
context.fallbackLocale = args.fallbackLocale;
|
||||
options.fallbackLocale = args.fallbackLocale;
|
||||
}
|
||||
|
||||
const user = await update(options);
|
||||
|
||||
return user;
|
||||
|
||||
@@ -9,13 +9,7 @@ const forgotPassword = async (args) => {
|
||||
throw new APIError('Missing username.');
|
||||
}
|
||||
|
||||
let options = {
|
||||
Model: args.Model,
|
||||
config: args.config,
|
||||
api: args.api,
|
||||
data: args.data,
|
||||
email: args.email,
|
||||
};
|
||||
let options = { ...args };
|
||||
|
||||
// /////////////////////////////////////
|
||||
// 1. Execute before login hook
|
||||
|
||||
@@ -5,12 +5,7 @@ const login = async (args) => {
|
||||
try {
|
||||
// Await validation here
|
||||
|
||||
let options = {
|
||||
Model: args.Model,
|
||||
config: args.config,
|
||||
api: args.api,
|
||||
data: args.data,
|
||||
};
|
||||
let options = { ...args };
|
||||
|
||||
// /////////////////////////////////////
|
||||
// 1. Execute before login hook
|
||||
|
||||
@@ -4,11 +4,7 @@ const refresh = async (args) => {
|
||||
try {
|
||||
// Await validation here
|
||||
|
||||
let options = {
|
||||
config: args.config,
|
||||
api: args.api,
|
||||
authorization: args.authorization,
|
||||
};
|
||||
let options = { ...args };
|
||||
|
||||
// /////////////////////////////////////
|
||||
// 1. Execute before refresh hook
|
||||
|
||||
@@ -13,14 +13,7 @@ const register = async (args) => {
|
||||
await executePolicy(args, args.config.policies.register);
|
||||
}
|
||||
|
||||
let options = {
|
||||
Model: args.Model,
|
||||
config: args.config,
|
||||
api: args.api,
|
||||
data: args.data,
|
||||
locale: args.locale,
|
||||
fallbackLocale: args.fallbackLocale,
|
||||
};
|
||||
let options = { ...args };
|
||||
|
||||
// /////////////////////////////////////
|
||||
// 2. Validate incoming data
|
||||
@@ -51,8 +44,10 @@ const register = async (args) => {
|
||||
const {
|
||||
Model,
|
||||
data,
|
||||
locale,
|
||||
fallbackLocale,
|
||||
req: {
|
||||
locale,
|
||||
fallbackLocale,
|
||||
},
|
||||
} = options;
|
||||
|
||||
const modelData = { ...data };
|
||||
|
||||
@@ -10,12 +10,7 @@ const registerFirstUser = async (args) => {
|
||||
|
||||
// Await validation here
|
||||
|
||||
let options = {
|
||||
Model: args.Model,
|
||||
config: args.config,
|
||||
api: args.api,
|
||||
data: args.data,
|
||||
};
|
||||
let options = { ...args };
|
||||
|
||||
// /////////////////////////////////////
|
||||
// 1. Execute before register first user hook
|
||||
|
||||
@@ -8,13 +8,7 @@ const resetPassword = async (args) => {
|
||||
throw new APIError('Missing required data.');
|
||||
}
|
||||
|
||||
let options = {
|
||||
Model: args.Model,
|
||||
config: args.config,
|
||||
api: args.api,
|
||||
data: args.data,
|
||||
user: args.user,
|
||||
};
|
||||
let options = { ...args };
|
||||
|
||||
// /////////////////////////////////////
|
||||
// 1. Execute before reset password hook
|
||||
|
||||
@@ -12,15 +12,7 @@ const update = async (args) => {
|
||||
|
||||
// Await validation here
|
||||
|
||||
let options = {
|
||||
Model: args.Model,
|
||||
config: args.config,
|
||||
api: args.api,
|
||||
data: args.data,
|
||||
id: args.id,
|
||||
locale: args.locale,
|
||||
fallbackLocale: args.fallbackLocale,
|
||||
};
|
||||
let options = { ...args };
|
||||
|
||||
// /////////////////////////////////////
|
||||
// 1. Execute before update hook
|
||||
@@ -40,8 +32,10 @@ const update = async (args) => {
|
||||
Model,
|
||||
data,
|
||||
id,
|
||||
locale,
|
||||
fallbackLocale,
|
||||
req: {
|
||||
locale,
|
||||
fallbackLocale,
|
||||
},
|
||||
} = options;
|
||||
|
||||
const dataToUpdate = { ...data };
|
||||
|
||||
@@ -5,9 +5,9 @@ const { forgotPassword } = require('../operations');
|
||||
const forgotPasswordHandler = (config, email) => async (req, res) => {
|
||||
try {
|
||||
await forgotPassword({
|
||||
req,
|
||||
Model: req.Model,
|
||||
config,
|
||||
api: 'REST',
|
||||
data: req.body,
|
||||
email,
|
||||
});
|
||||
|
||||
@@ -5,10 +5,10 @@ const { login } = require('../operations');
|
||||
const loginHandler = async (req, res) => {
|
||||
try {
|
||||
const token = await login({
|
||||
req,
|
||||
Model: req.Model,
|
||||
config: req.collection,
|
||||
data: req.body,
|
||||
api: 'REST',
|
||||
});
|
||||
|
||||
return res.status(httpStatus.OK)
|
||||
|
||||
@@ -5,10 +5,9 @@ const { refresh } = require('../operations');
|
||||
const refreshHandler = async (req, res) => {
|
||||
try {
|
||||
const refreshedToken = await refresh({
|
||||
req,
|
||||
config: req.collection,
|
||||
api: 'REST',
|
||||
authorization: req.headers.authorization,
|
||||
user: req.user,
|
||||
});
|
||||
|
||||
return res.status(200).json({
|
||||
|
||||
@@ -5,13 +5,10 @@ const { register } = require('../operations');
|
||||
const registerHandler = async (req, res) => {
|
||||
try {
|
||||
const user = await register({
|
||||
req,
|
||||
data: req.body,
|
||||
Model: req.Model,
|
||||
config: req.collection,
|
||||
api: 'REST',
|
||||
locale: req.locale,
|
||||
fallbackLocale: req.fallbackLocale,
|
||||
user: req.user,
|
||||
});
|
||||
|
||||
return res.status(201).json(user);
|
||||
|
||||
@@ -5,9 +5,9 @@ const { registerFirstUser } = require('../operations');
|
||||
const registerFirstUserHandler = async (req, res) => {
|
||||
try {
|
||||
const firstUser = await registerFirstUser({
|
||||
req,
|
||||
Model: req.Model,
|
||||
config: req.collection,
|
||||
api: 'REST',
|
||||
data: req.body,
|
||||
});
|
||||
|
||||
|
||||
@@ -5,10 +5,9 @@ const { resetPassword } = require('../operations');
|
||||
const resetPasswordHandler = async (req, res) => {
|
||||
try {
|
||||
const token = await resetPassword({
|
||||
req,
|
||||
Model: req.Model,
|
||||
config: req.collection,
|
||||
data: req.body,
|
||||
api: 'REST',
|
||||
});
|
||||
|
||||
return res.status(httpStatus.OK)
|
||||
|
||||
@@ -6,14 +6,11 @@ const { update } = require('../operations');
|
||||
const updateHandler = async (req, res) => {
|
||||
try {
|
||||
const user = await update({
|
||||
req,
|
||||
data: req.body,
|
||||
Model: req.Model,
|
||||
config: req.collection,
|
||||
id: req.params.id,
|
||||
api: 'REST',
|
||||
locale: req.locale,
|
||||
fallbackLocale: req.fallbackLocale,
|
||||
user: req.user,
|
||||
});
|
||||
|
||||
return res.status(httpStatus.OK).json({
|
||||
|
||||
@@ -7,6 +7,7 @@ const { email, password } = require('../tests/credentials');
|
||||
*/
|
||||
|
||||
const config = require('../../demo/payload.config');
|
||||
const { payload } = require('../../demo/server');
|
||||
|
||||
const url = config.serverURL;
|
||||
const usernameField = config.user.auth.useAsUsername;
|
||||
@@ -79,6 +80,25 @@ describe('Users REST API', () => {
|
||||
token = data.refreshedToken;
|
||||
});
|
||||
|
||||
it('should allow forgot-password by email', async () => {
|
||||
// TODO: figure out how to spy on payload instance functions
|
||||
// const mailSpy = jest.spyOn(payload, 'sendEmail');
|
||||
const response = await fetch(`${url}/api/forgot-password`, {
|
||||
method: 'post',
|
||||
body: JSON.stringify({
|
||||
[usernameField]: email,
|
||||
}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
// is not working
|
||||
// expect(mailSpy).toHaveBeenCalled();
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
|
||||
it('should allow a user to be created', async () => {
|
||||
const response = await fetch(`${url}/api/users/register`, {
|
||||
body: JSON.stringify({
|
||||
|
||||
Reference in New Issue
Block a user