mirror of
https://github.com/strapi/strapi.git
synced 2025-11-02 19:04:38 +00:00
Merge branch 'master' into releases/4.3.0
This commit is contained in:
commit
a4c2f3b46a
@ -53,7 +53,7 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
testEnvironment: 'jsdom',
|
testEnvironment: 'jsdom',
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\.js$': ['@swc-node/jest', { jsx: true, dynamicImport: true }],
|
'^.+\\.js$': ['@swc/jest', { jsc: { parser: { jsx: true, dynamicImport: true } } }],
|
||||||
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
|
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
|
||||||
'<rootDir>/fileTransformer.js',
|
'<rootDir>/fileTransformer.js',
|
||||||
},
|
},
|
||||||
|
|||||||
11
package.json
11
package.json
@ -71,7 +71,8 @@
|
|||||||
"@babel/polyfill": "7.12.1"
|
"@babel/polyfill": "7.12.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@swc-node/jest": "1.5.0",
|
"@swc/core": "1.2.218",
|
||||||
|
"@swc/jest": "0.2.22",
|
||||||
"@testing-library/react": "11.2.7",
|
"@testing-library/react": "11.2.7",
|
||||||
"@testing-library/react-hooks": "3.7.0",
|
"@testing-library/react-hooks": "3.7.0",
|
||||||
"@testing-library/user-event": "13.5.0",
|
"@testing-library/user-event": "13.5.0",
|
||||||
@ -98,11 +99,11 @@
|
|||||||
"glob": "7.2.3",
|
"glob": "7.2.3",
|
||||||
"husky": "3.1.0",
|
"husky": "3.1.0",
|
||||||
"istanbul": "~0.4.2",
|
"istanbul": "~0.4.2",
|
||||||
"jest": "28.1.2",
|
"jest": "28.1.3",
|
||||||
"jest-circus": "28.1.3",
|
"jest-circus": "28.1.3",
|
||||||
"jest-cli": "28.1.2",
|
"jest-cli": "28.1.3",
|
||||||
"jest-environment-jsdom": "28.1.2",
|
"jest-environment-jsdom": "28.1.3",
|
||||||
"jest-watch-typeahead": "0.6.5",
|
"jest-watch-typeahead": "2.0.0",
|
||||||
"lerna": "5.1.6",
|
"lerna": "5.1.6",
|
||||||
"lint-staged": "10.5.4",
|
"lint-staged": "10.5.4",
|
||||||
"lodash": "4.17.21",
|
"lodash": "4.17.21",
|
||||||
|
|||||||
@ -59,8 +59,8 @@ const ModalForm = ({ onMetaChange, onSizeChange }) => {
|
|||||||
const formType = get(attributes, [selectedField, 'type']);
|
const formType = get(attributes, [selectedField, 'type']);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
formType === 'dynamiczone' ||
|
['component', 'dynamiczone'].includes(formType) &&
|
||||||
(formType === 'component' && !['label', 'description'].includes(meta))
|
!['label', 'description'].includes(meta)
|
||||||
) {
|
) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -357,6 +357,7 @@ const ProfilePage = () => {
|
|||||||
})}
|
})}
|
||||||
name="password"
|
name="password"
|
||||||
type={passwordShown ? 'text' : 'password'}
|
type={passwordShown ? 'text' : 'password'}
|
||||||
|
autoComplete="new-password"
|
||||||
endAction={
|
endAction={
|
||||||
<FieldActionWrapper
|
<FieldActionWrapper
|
||||||
onClick={e => {
|
onClick={e => {
|
||||||
@ -398,6 +399,7 @@ const ProfilePage = () => {
|
|||||||
})}
|
})}
|
||||||
name="confirmPassword"
|
name="confirmPassword"
|
||||||
type={passwordConfirmShown ? 'text' : 'password'}
|
type={passwordConfirmShown ? 'text' : 'password'}
|
||||||
|
autoComplete="new-password"
|
||||||
endAction={
|
endAction={
|
||||||
<FieldActionWrapper
|
<FieldActionWrapper
|
||||||
onClick={e => {
|
onClick={e => {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -62,7 +62,7 @@ const layout = [
|
|||||||
id: 'Auth.form.username.placeholder',
|
id: 'Auth.form.username.placeholder',
|
||||||
defaultMessage: 'e.g. Kai_Doe',
|
defaultMessage: 'e.g. Kai_Doe',
|
||||||
},
|
},
|
||||||
type: 'email',
|
type: 'text',
|
||||||
size: {
|
size: {
|
||||||
col: 6,
|
col: 6,
|
||||||
xs: 12,
|
xs: 12,
|
||||||
@ -81,6 +81,7 @@ const layout = [
|
|||||||
col: 6,
|
col: 6,
|
||||||
xs: 12,
|
xs: 12,
|
||||||
},
|
},
|
||||||
|
autoComplete: 'new-password',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
intlLabel: {
|
intlLabel: {
|
||||||
@ -93,6 +94,7 @@ const layout = [
|
|||||||
col: 6,
|
col: 6,
|
||||||
xs: 12,
|
xs: 12,
|
||||||
},
|
},
|
||||||
|
autoComplete: 'new-password',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
|||||||
@ -63,7 +63,7 @@ const TableRows = ({
|
|||||||
return (
|
return (
|
||||||
<Td key={key}>
|
<Td key={key}>
|
||||||
{typeof cellFormatter === 'function' ? (
|
{typeof cellFormatter === 'function' ? (
|
||||||
cellFormatter(data, { key, name, ...rest })
|
cellFormatter(data, { key, name, formatMessage, ...rest })
|
||||||
) : (
|
) : (
|
||||||
<Typography textColor="neutral800">{data[name] || '-'}</Typography>
|
<Typography textColor="neutral800">{data[name] || '-'}</Typography>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -24,9 +24,18 @@ const tableHeaders = [
|
|||||||
name: 'roles',
|
name: 'roles',
|
||||||
metadatas: { label: 'Roles', sortable: false },
|
metadatas: { label: 'Roles', sortable: false },
|
||||||
/* eslint-disable react/prop-types */
|
/* eslint-disable react/prop-types */
|
||||||
cellFormatter: ({ roles }) => {
|
cellFormatter: ({ roles }, { formatMessage }) => {
|
||||||
return (
|
return (
|
||||||
<Typography textColor="neutral800">{roles.map(role => role.name).join(',\n')}</Typography>
|
<Typography textColor="neutral800">
|
||||||
|
{roles
|
||||||
|
.map(role =>
|
||||||
|
formatMessage({
|
||||||
|
id: `global.${role.code}`,
|
||||||
|
defaultMessage: role.name,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.join(',\n')}
|
||||||
|
</Typography>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
/* eslint-enable react/prop-types */
|
/* eslint-enable react/prop-types */
|
||||||
@ -41,11 +50,16 @@ const tableHeaders = [
|
|||||||
name: 'isActive',
|
name: 'isActive',
|
||||||
metadatas: { label: 'User status', sortable: false },
|
metadatas: { label: 'User status', sortable: false },
|
||||||
// eslint-disable-next-line react/prop-types
|
// eslint-disable-next-line react/prop-types
|
||||||
cellFormatter: ({ isActive }) => {
|
cellFormatter: ({ isActive }, { formatMessage }) => {
|
||||||
return (
|
return (
|
||||||
<Flex>
|
<Flex>
|
||||||
<Status isActive={isActive} variant={isActive ? 'success' : 'danger'} />
|
<Status isActive={isActive} variant={isActive ? 'success' : 'danger'} />
|
||||||
<Typography textColor="neutral800">{isActive ? 'Active' : 'Inactive'}</Typography>
|
<Typography textColor="neutral800">
|
||||||
|
{formatMessage({
|
||||||
|
id: isActive ? 'global.active' : 'global.inactive',
|
||||||
|
defaultMessage: isActive ? 'Active' : 'Inactive',
|
||||||
|
})}
|
||||||
|
</Typography>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -73,7 +73,10 @@ const SelectRoles = ({ disabled, error, onChange, value }) => {
|
|||||||
{(data || []).map(role => {
|
{(data || []).map(role => {
|
||||||
return (
|
return (
|
||||||
<Option key={role.id} value={role.id}>
|
<Option key={role.id} value={role.id}>
|
||||||
{role.name}
|
{formatMessage({
|
||||||
|
id: `global.${role.code}`,
|
||||||
|
defaultMessage: role.name,
|
||||||
|
})}
|
||||||
</Option>
|
</Option>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
"Auth.components.Oops.text": "Your account has been suspended.",
|
"Auth.components.Oops.text": "Your account has been suspended.",
|
||||||
"Auth.components.Oops.text.admin": "If this is a mistake, please contact your administrator.",
|
"Auth.components.Oops.text.admin": "If this is a mistake, please contact your administrator.",
|
||||||
"Auth.components.Oops.title": "Oops...",
|
"Auth.components.Oops.title": "Oops...",
|
||||||
|
"Auth.form.active.label": "Active",
|
||||||
"Auth.form.button.forgot-password": "Send Email",
|
"Auth.form.button.forgot-password": "Send Email",
|
||||||
"Auth.form.button.go-home": "GO BACK HOME",
|
"Auth.form.button.go-home": "GO BACK HOME",
|
||||||
"Auth.form.button.login": "Login",
|
"Auth.form.button.login": "Login",
|
||||||
@ -686,6 +687,8 @@
|
|||||||
"form.button.done": "Done",
|
"form.button.done": "Done",
|
||||||
"global.search": "Search",
|
"global.search": "Search",
|
||||||
"global.actions": "Actions",
|
"global.actions": "Actions",
|
||||||
|
"global.active": "Active",
|
||||||
|
"global.inactive": "Inactive",
|
||||||
"global.back": "Back",
|
"global.back": "Back",
|
||||||
"global.cancel": "Cancel",
|
"global.cancel": "Cancel",
|
||||||
"global.change-password": "Change password",
|
"global.change-password": "Change password",
|
||||||
@ -731,6 +734,15 @@
|
|||||||
"global.select": "Select",
|
"global.select": "Select",
|
||||||
"global.select-all-entries": "Select all entries",
|
"global.select-all-entries": "Select all entries",
|
||||||
"global.settings": "Settings",
|
"global.settings": "Settings",
|
||||||
|
"global.strapi-super-admin": "Super Admin",
|
||||||
|
"global.strapi-editor": "Editor",
|
||||||
|
"global.strapi-author": "Author",
|
||||||
|
"global.table.header.email": "Email",
|
||||||
|
"global.table.header.firstname": "Firstname",
|
||||||
|
"global.table.header.isActive": "User status",
|
||||||
|
"global.table.header.lastname": "Lastname",
|
||||||
|
"global.table.header.roles": "Roles",
|
||||||
|
"global.table.header.username": "Username",
|
||||||
"global.type": "Type",
|
"global.type": "Type",
|
||||||
"global.users": "Users",
|
"global.users": "Users",
|
||||||
"notification.contentType.relations.conflict": "Content type has conflicting relations",
|
"notification.contentType.relations.conflict": "Content type has conflicting relations",
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
"Auth.components.Oops.text": "你的帐号已经被停用。",
|
"Auth.components.Oops.text": "你的帐号已经被停用。",
|
||||||
"Auth.components.Oops.text.admin": "如果这是个错误,请联系你的管理员。",
|
"Auth.components.Oops.text.admin": "如果这是个错误,请联系你的管理员。",
|
||||||
"Auth.components.Oops.title": "哎呀...",
|
"Auth.components.Oops.title": "哎呀...",
|
||||||
|
"Auth.form.active.label": "激活",
|
||||||
"Auth.form.button.forgot-password": "发送电子邮件",
|
"Auth.form.button.forgot-password": "发送电子邮件",
|
||||||
"Auth.form.button.go-home": "回到首页",
|
"Auth.form.button.go-home": "回到首页",
|
||||||
"Auth.form.button.login": "登录",
|
"Auth.form.button.login": "登录",
|
||||||
@ -378,11 +379,11 @@
|
|||||||
"components.OverlayBlocker.description.serverError": "服务器已经重新启动,请在终端检查日志。",
|
"components.OverlayBlocker.description.serverError": "服务器已经重新启动,请在终端检查日志。",
|
||||||
"components.OverlayBlocker.title": "等待重新启动...",
|
"components.OverlayBlocker.title": "等待重新启动...",
|
||||||
"components.OverlayBlocker.title.serverError": "重新启动时间超过预期",
|
"components.OverlayBlocker.title.serverError": "重新启动时间超过预期",
|
||||||
"components.PageFooter.select": "每页条目",
|
"components.PageFooter.select": "条每页",
|
||||||
"components.ProductionBlocker.description": "为了安全起见,我们必须在其他环境下禁用这个插件。",
|
"components.ProductionBlocker.description": "为了安全起见,我们必须在其他环境下禁用这个插件。",
|
||||||
"components.ProductionBlocker.header": "这个插件只在开发环境中可用。",
|
"components.ProductionBlocker.header": "这个插件只在开发环境中可用。",
|
||||||
"components.Search.placeholder": "搜索...",
|
"components.Search.placeholder": "搜索...",
|
||||||
"components.TableHeader.sort": "按 {label} 排序",
|
"components.TableHeader.sort": "按{label}排序",
|
||||||
"components.Wysiwyg.ToggleMode.markdown-mode": "Markdown 模式",
|
"components.Wysiwyg.ToggleMode.markdown-mode": "Markdown 模式",
|
||||||
"components.Wysiwyg.ToggleMode.preview-mode": "预览模式",
|
"components.Wysiwyg.ToggleMode.preview-mode": "预览模式",
|
||||||
"components.Wysiwyg.collapse": "收起",
|
"components.Wysiwyg.collapse": "收起",
|
||||||
@ -475,11 +476,11 @@
|
|||||||
"content-manager.containers.Edit.delete-entry": "删除该条目",
|
"content-manager.containers.Edit.delete-entry": "删除该条目",
|
||||||
"content-manager.containers.Edit.editing": "编辑中...",
|
"content-manager.containers.Edit.editing": "编辑中...",
|
||||||
"content-manager.containers.Edit.information": "信息",
|
"content-manager.containers.Edit.information": "信息",
|
||||||
"content-manager.containers.Edit.information.by": "由",
|
"content-manager.containers.Edit.information.by": "操作人",
|
||||||
"content-manager.containers.Edit.information.created": "已创建",
|
"content-manager.containers.Edit.information.created": "创建于",
|
||||||
"content-manager.containers.Edit.information.draftVersion": "草稿版本",
|
"content-manager.containers.Edit.information.draftVersion": "草稿版本",
|
||||||
"content-manager.containers.Edit.information.editing": "编辑中",
|
"content-manager.containers.Edit.information.editing": "编辑中",
|
||||||
"content-manager.containers.Edit.information.lastUpdate": "最后更新",
|
"content-manager.containers.Edit.information.lastUpdate": "更新于",
|
||||||
"content-manager.containers.Edit.information.publishedVersion": "已发布版本",
|
"content-manager.containers.Edit.information.publishedVersion": "已发布版本",
|
||||||
"content-manager.containers.Edit.pluginHeader.title.new": "创建新条目",
|
"content-manager.containers.Edit.pluginHeader.title.new": "创建新条目",
|
||||||
"content-manager.containers.Edit.reset": "重置",
|
"content-manager.containers.Edit.reset": "重置",
|
||||||
@ -613,6 +614,8 @@
|
|||||||
"content-type-builder.plugin.name": "模型构建器",
|
"content-type-builder.plugin.name": "模型构建器",
|
||||||
"form.button.done": "完成",
|
"form.button.done": "完成",
|
||||||
"global.search": "搜索",
|
"global.search": "搜索",
|
||||||
|
"global.active": "已激活",
|
||||||
|
"global.inactive": "未激活",
|
||||||
"global.back": "返回",
|
"global.back": "返回",
|
||||||
"global.cancel": "取消",
|
"global.cancel": "取消",
|
||||||
"global.change-password": "修改密码",
|
"global.change-password": "修改密码",
|
||||||
@ -650,6 +653,15 @@
|
|||||||
"global.roles": "角色列表",
|
"global.roles": "角色列表",
|
||||||
"global.save": "保存",
|
"global.save": "保存",
|
||||||
"global.settings": "设置",
|
"global.settings": "设置",
|
||||||
|
"global.strapi-super-admin": "超级管理员",
|
||||||
|
"global.strapi-editor": "编辑",
|
||||||
|
"global.strapi-author": "作者",
|
||||||
|
"global.table.header.email": "电子邮件",
|
||||||
|
"global.table.header.firstname": "名字",
|
||||||
|
"global.table.header.isActive": "是否激活",
|
||||||
|
"global.table.header.lastname": "姓氏",
|
||||||
|
"global.table.header.roles": "用户角色",
|
||||||
|
"global.table.header.username": "用户名",
|
||||||
"global.users": "用户列表",
|
"global.users": "用户列表",
|
||||||
"global.type": "类型",
|
"global.type": "类型",
|
||||||
"notification.contentType.relations.conflict": "内容类型有关联冲突",
|
"notification.contentType.relations.conflict": "内容类型有关联冲突",
|
||||||
|
|||||||
@ -80,7 +80,7 @@
|
|||||||
"hoist-non-react-statics": "^3.3.0",
|
"hoist-non-react-statics": "^3.3.0",
|
||||||
"html-loader": "3.1.2",
|
"html-loader": "3.1.2",
|
||||||
"html-webpack-plugin": "5.5.0",
|
"html-webpack-plugin": "5.5.0",
|
||||||
"immer": "9.0.6",
|
"immer": "9.0.15",
|
||||||
"invariant": "^2.2.4",
|
"invariant": "^2.2.4",
|
||||||
"js-cookie": "2.2.1",
|
"js-cookie": "2.2.1",
|
||||||
"jsonwebtoken": "8.5.1",
|
"jsonwebtoken": "8.5.1",
|
||||||
@ -113,7 +113,7 @@
|
|||||||
"react-error-boundary": "3.1.1",
|
"react-error-boundary": "3.1.1",
|
||||||
"react-fast-compare": "^3.2.0",
|
"react-fast-compare": "^3.2.0",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-intl": "5.20.2",
|
"react-intl": "6.0.5",
|
||||||
"react-query": "3.24.3",
|
"react-query": "3.24.3",
|
||||||
"react-redux": "7.2.8",
|
"react-redux": "7.2.8",
|
||||||
"react-refresh": "0.11.0",
|
"react-refresh": "0.11.0",
|
||||||
|
|||||||
@ -36,7 +36,7 @@
|
|||||||
"pluralize": "^8.0.0",
|
"pluralize": "^8.0.0",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-intl": "5.20.2",
|
"react-intl": "6.0.5",
|
||||||
"react-redux": "7.2.8",
|
"react-redux": "7.2.8",
|
||||||
"react-router": "^5.2.0",
|
"react-router": "^5.2.0",
|
||||||
"react-router-dom": "5.2.0",
|
"react-router-dom": "5.2.0",
|
||||||
|
|||||||
@ -44,11 +44,16 @@ const TableHead = ({
|
|||||||
{headers.map(({ name, metadatas: { sortable: isSortable, label } }) => {
|
{headers.map(({ name, metadatas: { sortable: isSortable, label } }) => {
|
||||||
const isSorted = sortBy === name;
|
const isSorted = sortBy === name;
|
||||||
const isUp = sortOrder === 'ASC';
|
const isUp = sortOrder === 'ASC';
|
||||||
|
|
||||||
|
const intlLabel = formatMessage({
|
||||||
|
id: `global.table.header.${name}`,
|
||||||
|
defaultMessage: label,
|
||||||
|
});
|
||||||
|
|
||||||
const sortLabel = formatMessage(
|
const sortLabel = formatMessage(
|
||||||
{ id: 'components.TableHeader.sort', defaultMessage: 'Sort on {label}' },
|
{ id: 'components.TableHeader.sort', defaultMessage: 'Sort on {label}' },
|
||||||
{ label }
|
{ label: intlLabel }
|
||||||
);
|
);
|
||||||
const intlLabel = formatMessage({ id: label || name, defaultMessage: label || name });
|
|
||||||
|
|
||||||
const handleClickSort = (shouldAllowClick = true) => {
|
const handleClickSort = (shouldAllowClick = true) => {
|
||||||
if (isSortable && shouldAllowClick) {
|
if (isSortable && shouldAllowClick) {
|
||||||
@ -65,15 +70,13 @@ const TableHead = ({
|
|||||||
<Th
|
<Th
|
||||||
key={name}
|
key={name}
|
||||||
action={
|
action={
|
||||||
isSorted ? (
|
isSorted && (
|
||||||
<IconButton
|
<IconButton
|
||||||
label={sortLabel}
|
label={sortLabel}
|
||||||
onClick={handleClickSort}
|
onClick={handleClickSort}
|
||||||
icon={isSorted ? <SortIcon isUp={isUp} /> : undefined}
|
icon={isSorted && <SortIcon isUp={isUp} />}
|
||||||
noBorder
|
noBorder
|
||||||
/>
|
/>
|
||||||
) : (
|
|
||||||
undefined
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -51,7 +51,7 @@
|
|||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-intl": "5.20.2",
|
"react-intl": "6.0.5",
|
||||||
"react-router": "^5.2.0",
|
"react-router": "^5.2.0",
|
||||||
"react-router-dom": "5.2.0",
|
"react-router-dom": "5.2.0",
|
||||||
"styled-components": "5.3.3",
|
"styled-components": "5.3.3",
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
"byte-size": "7.0.1",
|
"byte-size": "7.0.1",
|
||||||
"cropperjs": "1.5.12",
|
"cropperjs": "1.5.12",
|
||||||
"fs-extra": "10.0.0",
|
"fs-extra": "10.0.0",
|
||||||
"immer": "9.0.6",
|
"immer": "9.0.15",
|
||||||
"koa-range": "0.3.0",
|
"koa-range": "0.3.0",
|
||||||
"koa-static": "5.0.0",
|
"koa-static": "5.0.0",
|
||||||
"lodash": "4.17.21",
|
"lodash": "4.17.21",
|
||||||
@ -37,7 +37,7 @@
|
|||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-copy-to-clipboard": "^5.1.0",
|
"react-copy-to-clipboard": "^5.1.0",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-intl": "5.20.2",
|
"react-intl": "6.0.5",
|
||||||
"react-redux": "7.2.8",
|
"react-redux": "7.2.8",
|
||||||
"react-router": "^5.2.0",
|
"react-router": "^5.2.0",
|
||||||
"react-router-dom": "5.2.0",
|
"react-router-dom": "5.2.0",
|
||||||
|
|||||||
60
packages/core/utils/lib/__tests__/visitors.test.js
Normal file
60
packages/core/utils/lib/__tests__/visitors.test.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const visitors = require('../sanitize/visitors');
|
||||||
|
|
||||||
|
const { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = require('../content-types').constants;
|
||||||
|
|
||||||
|
describe('Sanitize visitors util', () => {
|
||||||
|
describe('removeRestrictedRelations', () => {
|
||||||
|
const auth = {};
|
||||||
|
const data = {};
|
||||||
|
const creatorKeys = [CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE];
|
||||||
|
const rrrFunction = visitors.removeRestrictedRelations(auth);
|
||||||
|
const attribute = {
|
||||||
|
type: 'relation',
|
||||||
|
relation: 'oneToOne',
|
||||||
|
target: 'admin::user',
|
||||||
|
};
|
||||||
|
|
||||||
|
test('keeps creator relations with populateCreatorFields true', async () => {
|
||||||
|
const remove = jest.fn();
|
||||||
|
const set = jest.fn();
|
||||||
|
const promises = creatorKeys.map(async key => {
|
||||||
|
await rrrFunction(
|
||||||
|
{
|
||||||
|
data,
|
||||||
|
key,
|
||||||
|
attribute,
|
||||||
|
schema: { options: { populateCreatorFields: true } },
|
||||||
|
},
|
||||||
|
{ remove, set }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
await Promise.all(promises);
|
||||||
|
|
||||||
|
expect(remove).toHaveBeenCalledTimes(0);
|
||||||
|
expect(set).toBeCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('removes creator relations with populateCreatorFields false', async () => {
|
||||||
|
const remove = jest.fn();
|
||||||
|
const set = jest.fn();
|
||||||
|
const promises = creatorKeys.map(async key => {
|
||||||
|
await rrrFunction(
|
||||||
|
{
|
||||||
|
data,
|
||||||
|
key,
|
||||||
|
attribute,
|
||||||
|
schema: { options: { populateCreatorFields: false } },
|
||||||
|
},
|
||||||
|
{ remove, set }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
await Promise.all(promises);
|
||||||
|
|
||||||
|
expect(remove).toHaveBeenCalledTimes(creatorKeys.length);
|
||||||
|
creatorKeys.forEach(key => expect(remove).toHaveBeenCalledWith(key));
|
||||||
|
expect(set).toBeCalledTimes(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
const ACTIONS_TO_VERIFY = ['find'];
|
const ACTIONS_TO_VERIFY = ['find'];
|
||||||
|
|
||||||
// FIXME: Support populating creator fields
|
const { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = require('../../content-types').constants;
|
||||||
module.exports = auth => async ({ data, key, attribute }, { remove, set }) => {
|
|
||||||
|
module.exports = auth => async ({ data, key, attribute, schema }, { remove, set }) => {
|
||||||
const isRelation = attribute.type === 'relation';
|
const isRelation = attribute.type === 'relation';
|
||||||
|
|
||||||
if (!isRelation) {
|
if (!isRelation) {
|
||||||
@ -42,16 +43,22 @@ module.exports = auth => async ({ data, key, attribute }, { remove, set }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const isMorphRelation = attribute.relation.toLowerCase().startsWith('morph');
|
const isMorphRelation = attribute.relation.toLowerCase().startsWith('morph');
|
||||||
|
const isCreatorRelation = [CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE].includes(key);
|
||||||
|
|
||||||
// Polymorphic relations
|
// Polymorphic relations
|
||||||
if (isMorphRelation) {
|
if (isMorphRelation) {
|
||||||
await handleMorphRelation();
|
await handleMorphRelation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creator relations
|
||||||
|
if (isCreatorRelation && schema.options.populateCreatorFields) {
|
||||||
|
// do nothing
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regular relations
|
// Regular relations
|
||||||
else {
|
await handleRegularRelation();
|
||||||
await handleRegularRelation();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const hasAccessToSomeScopes = async (scopes, auth) => {
|
const hasAccessToSomeScopes = async (scopes, auth) => {
|
||||||
|
|||||||
@ -36,7 +36,7 @@
|
|||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-copy-to-clipboard": "^5.1.0",
|
"react-copy-to-clipboard": "^5.1.0",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-intl": "5.20.2",
|
"react-intl": "5.25.1",
|
||||||
"react-redux": "7.2.8",
|
"react-redux": "7.2.8",
|
||||||
"react-router": "^5.2.0",
|
"react-router": "^5.2.0",
|
||||||
"react-router-dom": "5.2.0",
|
"react-router-dom": "5.2.0",
|
||||||
|
|||||||
@ -32,12 +32,12 @@
|
|||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"grant-koa": "5.4.8",
|
"grant-koa": "5.4.8",
|
||||||
"jsonwebtoken": "^8.1.0",
|
"jsonwebtoken": "^8.1.0",
|
||||||
"koa2-ratelimit": "^0.9.0",
|
"koa2-ratelimit": "^1.1.1",
|
||||||
"lodash": "4.17.21",
|
"lodash": "4.17.21",
|
||||||
"purest": "4.0.2",
|
"purest": "4.0.2",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-intl": "5.20.2",
|
"react-intl": "6.0.5",
|
||||||
"react-redux": "7.2.8",
|
"react-redux": "7.2.8",
|
||||||
"react-router": "^5.2.0",
|
"react-router": "^5.2.0",
|
||||||
"react-router-dom": "5.2.0",
|
"react-router-dom": "5.2.0",
|
||||||
|
|||||||
@ -50,7 +50,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lodash": "4.17.21",
|
"lodash": "4.17.21",
|
||||||
"nodemailer": "6.7.3"
|
"nodemailer": "6.7.7"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14.19.1 <=16.x.x",
|
"node": ">=14.19.1 <=16.x.x",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user