@akemona-org/strapi-plugin-users-permissions 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +19 -0
- package/admin/src/assets/images/logo.svg +1 -0
- package/admin/src/components/BaselineAlignement/index.js +33 -0
- package/admin/src/components/Bloc/index.js +10 -0
- package/admin/src/components/BoundRoute/Components.js +78 -0
- package/admin/src/components/BoundRoute/index.js +56 -0
- package/admin/src/components/ContainerFluid/index.js +13 -0
- package/admin/src/components/FormBloc/index.js +61 -0
- package/admin/src/components/IntlInput/index.js +38 -0
- package/admin/src/components/ListBaselineAlignment/index.js +8 -0
- package/admin/src/components/ListRow/Components.js +74 -0
- package/admin/src/components/ListRow/index.js +35 -0
- package/admin/src/components/ModalForm/Wrapper.js +12 -0
- package/admin/src/components/ModalForm/index.js +59 -0
- package/admin/src/components/Permissions/ListWrapper.js +9 -0
- package/admin/src/components/Permissions/PermissionRow/BaselineAlignment.js +7 -0
- package/admin/src/components/Permissions/PermissionRow/CheckboxWrapper.js +37 -0
- package/admin/src/components/Permissions/PermissionRow/RowStyle.js +28 -0
- package/admin/src/components/Permissions/PermissionRow/SubCategory/ConditionsButtonWrapper.js +13 -0
- package/admin/src/components/Permissions/PermissionRow/SubCategory/PolicyWrapper.js +8 -0
- package/admin/src/components/Permissions/PermissionRow/SubCategory/SubCategoryWrapper.js +26 -0
- package/admin/src/components/Permissions/PermissionRow/SubCategory/index.js +116 -0
- package/admin/src/components/Permissions/PermissionRow/index.js +92 -0
- package/admin/src/components/Permissions/index.js +44 -0
- package/admin/src/components/Permissions/init.js +14 -0
- package/admin/src/components/Permissions/reducer.js +27 -0
- package/admin/src/components/Policies/Components.js +26 -0
- package/admin/src/components/Policies/index.js +61 -0
- package/admin/src/components/PrefixedIcon/index.js +27 -0
- package/admin/src/components/Roles/EmptyRole/BaselineAlignment.js +7 -0
- package/admin/src/components/Roles/EmptyRole/index.js +27 -0
- package/admin/src/components/Roles/RoleListWrapper/index.js +17 -0
- package/admin/src/components/Roles/RoleRow/RoleDescription.js +9 -0
- package/admin/src/components/Roles/RoleRow/index.js +45 -0
- package/admin/src/components/Roles/index.js +3 -0
- package/admin/src/components/SizedInput/index.js +24 -0
- package/admin/src/components/UsersPermissions/index.js +91 -0
- package/admin/src/components/UsersPermissions/init.js +11 -0
- package/admin/src/components/UsersPermissions/reducer.js +60 -0
- package/admin/src/containers/AdvancedSettings/index.js +218 -0
- package/admin/src/containers/AdvancedSettings/reducer.js +65 -0
- package/admin/src/containers/AdvancedSettings/utils/form.js +52 -0
- package/admin/src/containers/EmailTemplates/CustomTextInput.js +105 -0
- package/admin/src/containers/EmailTemplates/Wrapper.js +36 -0
- package/admin/src/containers/EmailTemplates/index.js +222 -0
- package/admin/src/containers/EmailTemplates/reducer.js +58 -0
- package/admin/src/containers/EmailTemplates/utils/forms.js +81 -0
- package/admin/src/containers/EmailTemplates/utils/schema.js +25 -0
- package/admin/src/containers/Providers/index.js +283 -0
- package/admin/src/containers/Providers/reducer.js +54 -0
- package/admin/src/containers/Providers/utils/createProvidersArray.js +21 -0
- package/admin/src/containers/Providers/utils/forms.js +205 -0
- package/admin/src/containers/Roles/CreatePage/index.js +167 -0
- package/admin/src/containers/Roles/CreatePage/utils/schema.js +9 -0
- package/admin/src/containers/Roles/EditPage/index.js +161 -0
- package/admin/src/containers/Roles/EditPage/utils/schema.js +9 -0
- package/admin/src/containers/Roles/ListPage/BaselineAlignment.js +8 -0
- package/admin/src/containers/Roles/ListPage/index.js +188 -0
- package/admin/src/containers/Roles/ProtectedCreatePage/index.js +12 -0
- package/admin/src/containers/Roles/ProtectedEditPage/index.js +12 -0
- package/admin/src/containers/Roles/ProtectedListPage/index.js +15 -0
- package/admin/src/containers/Roles/index.js +35 -0
- package/admin/src/contexts/EditPage/index.js +26 -0
- package/admin/src/contexts/HomePage/index.js +27 -0
- package/admin/src/contexts/UsersPermissionsContext/index.js +17 -0
- package/admin/src/hooks/index.js +5 -0
- package/admin/src/hooks/useFetchRole/index.js +55 -0
- package/admin/src/hooks/useFetchRole/reducer.js +31 -0
- package/admin/src/hooks/useForm/index.js +96 -0
- package/admin/src/hooks/useForm/reducer.js +59 -0
- package/admin/src/hooks/usePlugins/index.js +73 -0
- package/admin/src/hooks/usePlugins/init.js +5 -0
- package/admin/src/hooks/usePlugins/reducer.js +37 -0
- package/admin/src/hooks/useRolesList/index.js +62 -0
- package/admin/src/hooks/useRolesList/init.js +5 -0
- package/admin/src/hooks/useRolesList/reducer.js +31 -0
- package/admin/src/index.js +109 -0
- package/admin/src/permissions.js +33 -0
- package/admin/src/pluginId.js +5 -0
- package/admin/src/translations/ar.json +49 -0
- package/admin/src/translations/cs.json +55 -0
- package/admin/src/translations/de.json +68 -0
- package/admin/src/translations/dk.json +116 -0
- package/admin/src/translations/en.json +104 -0
- package/admin/src/translations/es.json +70 -0
- package/admin/src/translations/fr.json +55 -0
- package/admin/src/translations/id.json +69 -0
- package/admin/src/translations/index.js +55 -0
- package/admin/src/translations/it.json +68 -0
- package/admin/src/translations/ja.json +53 -0
- package/admin/src/translations/ko.json +55 -0
- package/admin/src/translations/ms.json +54 -0
- package/admin/src/translations/nl.json +53 -0
- package/admin/src/translations/pl.json +55 -0
- package/admin/src/translations/pt-BR.json +49 -0
- package/admin/src/translations/pt.json +53 -0
- package/admin/src/translations/ru.json +68 -0
- package/admin/src/translations/sk.json +57 -0
- package/admin/src/translations/sv.json +68 -0
- package/admin/src/translations/th.json +66 -0
- package/admin/src/translations/tr.json +53 -0
- package/admin/src/translations/uk.json +54 -0
- package/admin/src/translations/vi.json +55 -0
- package/admin/src/translations/zh-Hans.json +104 -0
- package/admin/src/translations/zh.json +53 -0
- package/admin/src/utils/cleanPermissions.js +25 -0
- package/admin/src/utils/formatPolicies.js +8 -0
- package/admin/src/utils/getRequestURL.js +5 -0
- package/admin/src/utils/getTrad.js +5 -0
- package/admin/src/utils/index.js +4 -0
- package/config/functions/bootstrap.js +234 -0
- package/config/layout.js +10 -0
- package/config/policies/isAuthenticated.js +9 -0
- package/config/policies/permissions.js +93 -0
- package/config/policies/rateLimit.js +33 -0
- package/config/request.json +6 -0
- package/config/routes.json +397 -0
- package/config/schema.graphql.js +280 -0
- package/config/security.json +5 -0
- package/config/users-permissions-actions.js +80 -0
- package/controllers/Auth.js +612 -0
- package/controllers/User.js +125 -0
- package/controllers/UsersPermissions.js +291 -0
- package/controllers/user/admin.js +224 -0
- package/controllers/user/api.js +173 -0
- package/controllers/validation/email-template.js +40 -0
- package/documentation/1.0.0/overrides/users-permissions-Role.json +281 -0
- package/documentation/1.0.0/overrides/users-permissions-User.json +325 -0
- package/middlewares/users-permissions/defaults.json +5 -0
- package/middlewares/users-permissions/index.js +40 -0
- package/models/Permission.js +7 -0
- package/models/Permission.settings.json +43 -0
- package/models/Role.js +7 -0
- package/models/Role.settings.json +42 -0
- package/models/User.config.js +15 -0
- package/models/User.js +7 -0
- package/models/User.settings.json +62 -0
- package/package.json +70 -0
- package/services/Jwt.js +65 -0
- package/services/Providers.js +596 -0
- package/services/User.js +167 -0
- package/services/UsersPermissions.js +416 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"BoundRoute.title": "Đến tới",
|
|
3
|
+
"EditForm.inputSelect.description.role": "Đính kèm người dùng mới đã được xác thực vào quyền được chọn.",
|
|
4
|
+
"EditForm.inputSelect.label.role": "Quyền mặc định cho các người dùng đã được chứng thực",
|
|
5
|
+
"EditForm.inputToggle.description.email": "Không cho phép người dùng tạo nhiều tài khoản có cùng địa chỉ email với nhiều nhà cung cấp chứng thực.",
|
|
6
|
+
"EditForm.inputToggle.description.email-confirmation": "Khi được kích hoạt (ON), người dùng đăng ký mới nhận được một email xác nhận.",
|
|
7
|
+
"EditForm.inputToggle.description.email-confirmation-redirection": "Sau khi xác nhận email của bạn, chọn nơi bạn sẽ được đưa về.",
|
|
8
|
+
"EditForm.inputToggle.description.email-reset-password": "URL của trang lấy lại mật khẩu của ứng dụng của bạn",
|
|
9
|
+
"EditForm.inputToggle.description.sign-up": "Khi không kích hoạt (OFF), quá trình đăng ký bị cấm. Không ai có thể đăng ký thêm dù dùng bất kỳ nhà cung cấp nào.",
|
|
10
|
+
"EditForm.inputToggle.label.email": "Một tài khoản trên một địa chỉ email",
|
|
11
|
+
"EditForm.inputToggle.label.email-confirmation": "Kích hoạt email xác nhận",
|
|
12
|
+
"EditForm.inputToggle.label.email-confirmation-redirection": "URL đưa về",
|
|
13
|
+
"EditForm.inputToggle.label.email-reset-password": "Trang lấy lại mật khẩu",
|
|
14
|
+
"EditForm.inputToggle.label.sign-up": "Kích hoạt đăng ký",
|
|
15
|
+
"HeaderNav.link.advancedSettings": "Cài đặt nâng cao",
|
|
16
|
+
"HeaderNav.link.emailTemplates": "Mẫu email",
|
|
17
|
+
"HeaderNav.link.providers": "Các nhà cung cấp",
|
|
18
|
+
"HeaderNav.link.roles": "Các Vai trò & Quyền",
|
|
19
|
+
"List.title.emailTemplates.plural": "{number} mẫu email có sẵn",
|
|
20
|
+
"List.title.emailTemplates.singular": "{number} mẫu email có sẵn",
|
|
21
|
+
"List.title.providers.disabled.plural": "{number} đã không được kích hoạt",
|
|
22
|
+
"List.title.providers.disabled.singular": "{number} đã không được kích hoạt",
|
|
23
|
+
"List.title.providers.enabled.plural": "{number} nhà cung cấp đã được kích hoạt và",
|
|
24
|
+
"List.title.providers.enabled.singular": "{number} nhà cung cấp đã được kích hoạt và",
|
|
25
|
+
"Plugin.permissions.plugins.description": "Định nghĩa tất cả hành động được phép cho {name} plugin.",
|
|
26
|
+
"Plugins.header.description": "Chỉ các hành động đến bởi một đường dẫn được liệt kê bên dưới.",
|
|
27
|
+
"Plugins.header.title": "Các Quyền",
|
|
28
|
+
"Policies.InputSelect.empty": "Rỗng",
|
|
29
|
+
"Policies.InputSelect.label": "Được phép thực hiện hành động này cho:",
|
|
30
|
+
"Policies.header.hint": "Chọn các hành động của ứng dựng hoặc hành động của plugin và nhấn vào biểu tượng bánh răng để hiển thị đường đến",
|
|
31
|
+
"Policies.header.title": "Các cài đặt nâng cao",
|
|
32
|
+
"PopUpForm.Email.email_templates.inputDescription": "Nếu bạn không chắc sử dụng các biến như thế nào, {link}",
|
|
33
|
+
"PopUpForm.Email.options.from.email.label": "Email người gửi",
|
|
34
|
+
"PopUpForm.Email.options.from.email.placeholder": "kai@doe.com",
|
|
35
|
+
"PopUpForm.Email.options.from.name.label": "Tên người gửi",
|
|
36
|
+
"PopUpForm.Email.options.from.name.placeholder": "Kai Doe",
|
|
37
|
+
"PopUpForm.Email.options.message.label": "Thông điệp",
|
|
38
|
+
"PopUpForm.Email.options.object.label": "Chủ đề",
|
|
39
|
+
"PopUpForm.Email.options.response_email.label": "Email phản hồi",
|
|
40
|
+
"PopUpForm.Email.options.response_email.placeholder": "kai@doe.com",
|
|
41
|
+
"PopUpForm.Providers.enabled.description": "Nếu không kích hoạt, người dùng sẽ không thể dùng nhà cung cấp này.",
|
|
42
|
+
"PopUpForm.Providers.enabled.label": "Kích hoạt",
|
|
43
|
+
"PopUpForm.Providers.key.label": "Client ID",
|
|
44
|
+
"PopUpForm.Providers.key.placeholder": "VĂN BẢN",
|
|
45
|
+
"PopUpForm.Providers.redirectURL.front-end.label": "URL chuyển tiếp đến ứng dụng bên ngoài của bạn",
|
|
46
|
+
"PopUpForm.Providers.secret.label": "Client Secret",
|
|
47
|
+
"PopUpForm.Providers.secret.placeholder": "VĂN BẢN",
|
|
48
|
+
"PopUpForm.header.edit.email-templates": "Sửa Các Mẫu Email",
|
|
49
|
+
"PopUpForm.Providers.subdomain.label": "Host URI (Subdomain)",
|
|
50
|
+
"PopUpForm.Providers.subdomain.placeholder": "my.subdomain.com",
|
|
51
|
+
"notification.success.submit": "Các cấu hình đã được cập nhật",
|
|
52
|
+
"plugin.description.long": "Bảo vệ API của bạn với quá trình chứng thực đầy đủ dựa trên JWT. Plugin này cũng kèm với chiến lược ACL cho phép bạn quản lý quyền giữa các nhóm người dùng.",
|
|
53
|
+
"plugin.description.short": "Bảo vệ API của bạn với quá trình chứng thực đầy đủ dựa trên JWT",
|
|
54
|
+
"plugin.name": "Vai trò và Quyền"
|
|
55
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
{
|
|
2
|
+
"page.title": "角色设置",
|
|
3
|
+
"app.components.Button.save": "保存",
|
|
4
|
+
"app.components.Button.reset": "重置",
|
|
5
|
+
"BoundRoute.title": "绑定路由到",
|
|
6
|
+
"EditForm.inputSelect.description.role": "新验证身份的用户将被赋予所选角色。",
|
|
7
|
+
"EditForm.inputSelect.label.role": "认证用户的默认角色",
|
|
8
|
+
"EditForm.inputToggle.description.email": "不允许用户使用相同的电子邮件地址来创建多个帐户。",
|
|
9
|
+
"EditForm.inputToggle.description.email-confirmation": "启用后,新注册的用户需要进行邮件确认。",
|
|
10
|
+
"EditForm.inputToggle.description.email-confirmation-redirection": "确认您的电子邮件后,选择将您重定向到的位置。",
|
|
11
|
+
"EditForm.inputToggle.description.email-reset-password": "应用程序的重置密码页面的 URL",
|
|
12
|
+
"EditForm.inputToggle.description.sign-up": "禁用后将无法注册,也无法通过SSO登录。",
|
|
13
|
+
"EditForm.inputToggle.label.email": "每个邮箱对应一个账号",
|
|
14
|
+
"EditForm.inputToggle.label.email-confirmation": "启用电子邮件确认",
|
|
15
|
+
"EditForm.inputToggle.label.email-confirmation-redirection": "重定向 URL",
|
|
16
|
+
"EditForm.inputToggle.label.email-reset-password": "重置密码页面 URL",
|
|
17
|
+
"EditForm.inputToggle.label.sign-up": "开启注册",
|
|
18
|
+
"Email.template.email_confirmation": "邮件地址确认",
|
|
19
|
+
"EditForm.inputToggle.placeholder.email-reset-password": "例如: https://yourfrontend.com/reset-password",
|
|
20
|
+
"EditForm.inputToggle.placeholder.email-confirmation-redirection": "例如: https://yourfrontend.com/reset-password",
|
|
21
|
+
"Email.template.reset_password": "重置密码",
|
|
22
|
+
"HeaderNav.link.advancedSettings": "高级设置",
|
|
23
|
+
"HeaderNav.link.advanced-settings": "高级设置",
|
|
24
|
+
"HeaderNav.link.emailTemplates": "电子邮件模板",
|
|
25
|
+
"HeaderNav.link.providers": "第三方连接SSO",
|
|
26
|
+
"HeaderNav.link.roles": "角色与权限",
|
|
27
|
+
"HeaderNav.link.email-templates": "邮件模板",
|
|
28
|
+
"List.title.emailTemplates.plural": "{number} 电子邮件模板是可用的",
|
|
29
|
+
"List.title.emailTemplates.singular": "{number} 电子邮件模板是可用的",
|
|
30
|
+
"List.title.providers.disabled.plural": "{number} 被禁用",
|
|
31
|
+
"List.title.providers.disabled.singular": "{number} 被禁用",
|
|
32
|
+
"List.title.providers.enabled.plural": "{number} 个供应商被启用, ",
|
|
33
|
+
"List.title.providers.enabled.singular": "{number} 个供应商被启用, ",
|
|
34
|
+
"List.button.roles": "创建新角色",
|
|
35
|
+
"List.row.provider.enabled": "已启用",
|
|
36
|
+
"List.row.provider.disabled": "已禁用",
|
|
37
|
+
"notification.error": "出错了!",
|
|
38
|
+
"Plugin.permissions.plugins.description": "定义 {name} 插件所有允许的操作。",
|
|
39
|
+
"Plugins.header.description": "下面只列出路由绑定的操作。",
|
|
40
|
+
"Plugins.header.title": "权限",
|
|
41
|
+
"Policies.InputSelect.empty": "无",
|
|
42
|
+
"Policies.InputSelect.label": "允许执行以下操作:",
|
|
43
|
+
"Policies.header.hint": "选择应用程序或插件的操作,然后点击 COG 图标显示绑定的路由",
|
|
44
|
+
"Policies.header.title": "高级设置",
|
|
45
|
+
"PopUpForm.Email.email_templates.inputDescription": "如果你不确定如何使用变量, {link}",
|
|
46
|
+
"PopUpForm.Email.link.documentation": "查看文档",
|
|
47
|
+
"PopUpForm.Email.options.from.email.label": "发件人地址",
|
|
48
|
+
"PopUpForm.Email.options.from.email.placeholder": "kai@doe.com",
|
|
49
|
+
"PopUpForm.Email.options.from.name.label": "发件人名称",
|
|
50
|
+
"PopUpForm.Email.options.from.name.placeholder": "Kai Doe",
|
|
51
|
+
"PopUpForm.Email.options.message.label": "消息",
|
|
52
|
+
"PopUpForm.Email.options.object.label": "主题",
|
|
53
|
+
"PopUpForm.Email.options.object.placeholder": "请确认您在 “%APP_NAME%” 的邮件地址。",
|
|
54
|
+
"PopUpForm.Email.options.response_email.label": "回复邮箱地址",
|
|
55
|
+
"PopUpForm.Email.options.response_email.placeholder": "kai@doe.com",
|
|
56
|
+
"PopUpForm.Providers.enabled.description": "如果禁用,用户将无法以该方式发送邮件",
|
|
57
|
+
"PopUpForm.Providers.enabled.label": "启用",
|
|
58
|
+
"PopUpForm.Providers.key.label": "客户端 ID",
|
|
59
|
+
"PopUpForm.Providers.key.placeholder": "文本",
|
|
60
|
+
"PopUpForm.Providers.redirectURL.front-end.label": "重定向到前端应用的 URL",
|
|
61
|
+
"PopUpForm.Providers.redirectURL.label": "要添加到 {provider} 应用配置中的重定向 URL",
|
|
62
|
+
"PopUpForm.Providers.secret.label": "Client Secret",
|
|
63
|
+
"PopUpForm.Providers.secret.placeholder": "文本",
|
|
64
|
+
"PopUpForm.header.edit.email-templates": "编辑电子邮件模版",
|
|
65
|
+
"PopUpForm.header.edit.providers": "编辑提供方",
|
|
66
|
+
"PopUpForm.Providers.subdomain.label": "域名 URI (Subdomain)",
|
|
67
|
+
"PopUpForm.Providers.subdomain.placeholder": "my.subdomain.com",
|
|
68
|
+
"popUpWarning.button.cancel": "取消",
|
|
69
|
+
"popUpWarning.button.confirm": "确认",
|
|
70
|
+
"popUpWarning.title": "请确认",
|
|
71
|
+
"popUpWarning.warning.cancel": "确定要取消变更吗?",
|
|
72
|
+
"Settings.roles.deleted": "角色已删除",
|
|
73
|
+
"Settings.roles.edited": "角色已编辑",
|
|
74
|
+
"Settings.section-label": "角色与权限插件",
|
|
75
|
+
"notification.success.submit": "设置已被更新",
|
|
76
|
+
"plugin.description.long": "使用基于 JWT 的完整身份验证过程来保护 API。这个插件还有一个 ACL 策略,允许你管理用户组之间的权限。",
|
|
77
|
+
"plugin.description.short": "使用基于 JWT 的完整身份验证过程保护 API",
|
|
78
|
+
"plugin.name": "角色与权限",
|
|
79
|
+
"Settings.advancedSettings.title": "设置",
|
|
80
|
+
"Settings.roles.create.description": "编辑角色的权限",
|
|
81
|
+
"Settings.roles.create.title": "创建角色",
|
|
82
|
+
"Settings.roles.created": "角色创建成功",
|
|
83
|
+
"EditPage.form.roles": "角色详情",
|
|
84
|
+
"Settings.roles.edit.title": "编辑角色",
|
|
85
|
+
"Settings.roles.form.button.users-with-role": "该角色下的用户",
|
|
86
|
+
"Settings.roles.form.created": "已创建",
|
|
87
|
+
"Settings.roles.form.description": "角色的名称和描述",
|
|
88
|
+
"Settings.roles.form.input.description": "描述",
|
|
89
|
+
"Settings.roles.form.input.name": "名称",
|
|
90
|
+
"Settings.roles.form.permission.property-label": "{label} 权限",
|
|
91
|
+
"Settings.roles.form.permissions.attributesPermissions": "字段权限",
|
|
92
|
+
"Settings.roles.form.permissions.create": "创建",
|
|
93
|
+
"Settings.roles.form.permissions.delete": "删除",
|
|
94
|
+
"Settings.roles.form.permissions.publish": "发布",
|
|
95
|
+
"Settings.roles.form.permissions.read": "查看",
|
|
96
|
+
"Settings.roles.form.permissions.update": "修改",
|
|
97
|
+
"Settings.roles.form.title": "详细",
|
|
98
|
+
"Settings.roles.list.button.add": "添加新角色",
|
|
99
|
+
"Settings.roles.list.description": "前端角色列表与权限设置",
|
|
100
|
+
"Settings.roles.list.title.plural": "已有 {number} 个角色",
|
|
101
|
+
"Settings.roles.list.title.singular": "已有 {number} 个角色",
|
|
102
|
+
"Settings.roles.title": "角色与权限",
|
|
103
|
+
"Settings.roles.title.singular": "角色"
|
|
104
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"BoundRoute.title": "綁定路徑到",
|
|
3
|
+
"EditForm.inputSelect.description.role": "將新的驗證使用者加入此身份。",
|
|
4
|
+
"EditForm.inputSelect.label.role": "驗證使用者預設身份",
|
|
5
|
+
"EditForm.inputToggle.description.email": "禁止使用者使用同一個電子郵件地址 + 不同的驗證方式註冊多個帳號",
|
|
6
|
+
"EditForm.inputToggle.description.email-confirmation": "當啟用後,新註冊的使用者將會收到一封認證郵件。",
|
|
7
|
+
"EditForm.inputToggle.description.email-confirmation-redirection": "認證完後後,使用者被重新導向的網址。",
|
|
8
|
+
"EditForm.inputToggle.description.sign-up": "當停用後,不論使用任何驗證方式使用者將無法註冊。",
|
|
9
|
+
"EditForm.inputToggle.label.email": "電子郵件地址單一帳號限制",
|
|
10
|
+
"EditForm.inputToggle.label.email-confirmation": "啟用電子郵件地址驗證",
|
|
11
|
+
"EditForm.inputToggle.label.email-confirmation-redirection": "重新導向網址",
|
|
12
|
+
"EditForm.inputToggle.label.sign-up": "啟用註冊",
|
|
13
|
+
"HeaderNav.link.advancedSettings": "進階設定",
|
|
14
|
+
"HeaderNav.link.emailTemplates": "郵件範本",
|
|
15
|
+
"HeaderNav.link.providers": "驗證方式",
|
|
16
|
+
"HeaderNav.link.roles": "身份",
|
|
17
|
+
"List.title.emailTemplates.plural": "{number} 個郵件範本可用",
|
|
18
|
+
"List.title.emailTemplates.singular": "{number} 個郵件範本可用",
|
|
19
|
+
"List.title.providers.disabled.plural": "{number} 已停用",
|
|
20
|
+
"List.title.providers.disabled.singular": "{number} 已停用",
|
|
21
|
+
"List.title.providers.enabled.plural": "{number} 個驗證方式已啟動",
|
|
22
|
+
"List.title.providers.enabled.singular": "{number} 個驗證方式已啟動",
|
|
23
|
+
"Plugin.permissions.plugins.description": "為 {name} 擴充功能定義所有可用的操作",
|
|
24
|
+
"Plugins.header.description": "只有綁定路徑的操作會顯示在下方",
|
|
25
|
+
"Plugins.header.title": "權限",
|
|
26
|
+
"Policies.InputSelect.empty": "無",
|
|
27
|
+
"Policies.InputSelect.label": "限制此操作:",
|
|
28
|
+
"Policies.header.hint": "選取應用程式或擴充功能的操作然後點擊齒輪圖示以顯示綁定路徑",
|
|
29
|
+
"Policies.header.title": "進階設定",
|
|
30
|
+
"PopUpForm.Email.email_templates.inputDescription": "如果您不確定要怎麼使用變數,請 {link}",
|
|
31
|
+
"PopUpForm.Email.options.from.email.label": "寄件人地址",
|
|
32
|
+
"PopUpForm.Email.options.from.email.placeholder": "kai@doe.com",
|
|
33
|
+
"PopUpForm.Email.options.from.name.label": "寄件人名稱",
|
|
34
|
+
"PopUpForm.Email.options.from.name.placeholder": "Kai Doe",
|
|
35
|
+
"PopUpForm.Email.options.message.label": "訊息",
|
|
36
|
+
"PopUpForm.Email.options.object.label": "主旨",
|
|
37
|
+
"PopUpForm.Email.options.response_email.label": "回覆地址",
|
|
38
|
+
"PopUpForm.Email.options.response_email.placeholder": "kai@doe.com",
|
|
39
|
+
"PopUpForm.Providers.enabled.description": "如果停用,使用者將無法使用這個驗證方式",
|
|
40
|
+
"PopUpForm.Providers.enabled.label": "啟用",
|
|
41
|
+
"PopUpForm.Providers.key.label": "客戶端 ID",
|
|
42
|
+
"PopUpForm.Providers.key.placeholder": "TEXT",
|
|
43
|
+
"PopUpForm.Providers.redirectURL.front-end.label": "您應用程式的前端頁面網址",
|
|
44
|
+
"PopUpForm.Providers.secret.label": "客戶端密鑰",
|
|
45
|
+
"PopUpForm.Providers.secret.placeholder": "TEXT",
|
|
46
|
+
"PopUpForm.header.edit.email-templates": "編輯郵件範本",
|
|
47
|
+
"PopUpForm.Providers.subdomain.label": "Host URI (Subdomain)",
|
|
48
|
+
"PopUpForm.Providers.subdomain.placeholder": "my.subdomain.com",
|
|
49
|
+
"notification.success.submit": "設定已更新",
|
|
50
|
+
"plugin.description.long": "使用 JWT 認證保護您的 API。這個擴充功能也使用 ACL 來讓你管理不同群組使用者的權限。",
|
|
51
|
+
"plugin.description.short": "使用 JWT 認證保護您的 API",
|
|
52
|
+
"plugin.name": "身份與權限"
|
|
53
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { isEmpty } from 'lodash';
|
|
2
|
+
|
|
3
|
+
const cleanPermissions = permissions =>
|
|
4
|
+
Object.keys(permissions).reduce((acc, current) => {
|
|
5
|
+
const currentPermission = permissions[current].controllers;
|
|
6
|
+
const cleanedControllers = Object.keys(currentPermission).reduce((acc2, curr) => {
|
|
7
|
+
if (isEmpty(currentPermission[curr])) {
|
|
8
|
+
return acc2;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
acc2[curr] = currentPermission[curr];
|
|
12
|
+
|
|
13
|
+
return acc2;
|
|
14
|
+
}, {});
|
|
15
|
+
|
|
16
|
+
if (isEmpty(cleanedControllers)) {
|
|
17
|
+
return acc;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
acc[current] = { controllers: cleanedControllers };
|
|
21
|
+
|
|
22
|
+
return acc;
|
|
23
|
+
}, {});
|
|
24
|
+
|
|
25
|
+
export default cleanPermissions;
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* An asynchronous bootstrap function that runs before
|
|
5
|
+
* your application gets started.
|
|
6
|
+
*
|
|
7
|
+
* This gives you an opportunity to set up your data model,
|
|
8
|
+
* run jobs, or perform some special logic.
|
|
9
|
+
*/
|
|
10
|
+
const _ = require('lodash');
|
|
11
|
+
const uuid = require('uuid/v4');
|
|
12
|
+
|
|
13
|
+
const usersPermissionsActions = require('../users-permissions-actions');
|
|
14
|
+
|
|
15
|
+
module.exports = async () => {
|
|
16
|
+
const pluginStore = strapi.store({
|
|
17
|
+
environment: '',
|
|
18
|
+
type: 'plugin',
|
|
19
|
+
name: 'users-permissions',
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const grantConfig = {
|
|
23
|
+
email: {
|
|
24
|
+
enabled: true,
|
|
25
|
+
icon: 'envelope',
|
|
26
|
+
},
|
|
27
|
+
discord: {
|
|
28
|
+
enabled: false,
|
|
29
|
+
icon: 'discord',
|
|
30
|
+
key: '',
|
|
31
|
+
secret: '',
|
|
32
|
+
callback: `${strapi.config.server.url}/auth/discord/callback`,
|
|
33
|
+
scope: ['identify', 'email'],
|
|
34
|
+
},
|
|
35
|
+
facebook: {
|
|
36
|
+
enabled: false,
|
|
37
|
+
icon: 'facebook-square',
|
|
38
|
+
key: '',
|
|
39
|
+
secret: '',
|
|
40
|
+
callback: `${strapi.config.server.url}/auth/facebook/callback`,
|
|
41
|
+
scope: ['email'],
|
|
42
|
+
},
|
|
43
|
+
google: {
|
|
44
|
+
enabled: false,
|
|
45
|
+
icon: 'google',
|
|
46
|
+
key: '',
|
|
47
|
+
secret: '',
|
|
48
|
+
callback: `${strapi.config.server.url}/auth/google/callback`,
|
|
49
|
+
scope: ['email'],
|
|
50
|
+
},
|
|
51
|
+
github: {
|
|
52
|
+
enabled: false,
|
|
53
|
+
icon: 'github',
|
|
54
|
+
key: '',
|
|
55
|
+
secret: '',
|
|
56
|
+
callback: `${strapi.config.server.url}/auth/github/callback`,
|
|
57
|
+
scope: ['user', 'user:email'],
|
|
58
|
+
},
|
|
59
|
+
microsoft: {
|
|
60
|
+
enabled: false,
|
|
61
|
+
icon: 'windows',
|
|
62
|
+
key: '',
|
|
63
|
+
secret: '',
|
|
64
|
+
callback: `${strapi.config.server.url}/auth/microsoft/callback`,
|
|
65
|
+
scope: ['user.read'],
|
|
66
|
+
},
|
|
67
|
+
twitter: {
|
|
68
|
+
enabled: false,
|
|
69
|
+
icon: 'twitter',
|
|
70
|
+
key: '',
|
|
71
|
+
secret: '',
|
|
72
|
+
callback: `${strapi.config.server.url}/auth/twitter/callback`,
|
|
73
|
+
},
|
|
74
|
+
instagram: {
|
|
75
|
+
enabled: false,
|
|
76
|
+
icon: 'instagram',
|
|
77
|
+
key: '',
|
|
78
|
+
secret: '',
|
|
79
|
+
callback: `${strapi.config.server.url}/auth/instagram/callback`,
|
|
80
|
+
scope: ['user_profile'],
|
|
81
|
+
},
|
|
82
|
+
vk: {
|
|
83
|
+
enabled: false,
|
|
84
|
+
icon: 'vk',
|
|
85
|
+
key: '',
|
|
86
|
+
secret: '',
|
|
87
|
+
callback: `${strapi.config.server.url}/auth/vk/callback`,
|
|
88
|
+
scope: ['email'],
|
|
89
|
+
},
|
|
90
|
+
twitch: {
|
|
91
|
+
enabled: false,
|
|
92
|
+
icon: 'twitch',
|
|
93
|
+
key: '',
|
|
94
|
+
secret: '',
|
|
95
|
+
callback: `${strapi.config.server.url}/auth/twitch/callback`,
|
|
96
|
+
scope: ['user:read:email'],
|
|
97
|
+
},
|
|
98
|
+
linkedin: {
|
|
99
|
+
enabled: false,
|
|
100
|
+
icon: 'linkedin',
|
|
101
|
+
key: '',
|
|
102
|
+
secret: '',
|
|
103
|
+
callback: `${strapi.config.server.url}/auth/linkedin/callback`,
|
|
104
|
+
scope: ['r_liteprofile', 'r_emailaddress'],
|
|
105
|
+
},
|
|
106
|
+
cognito: {
|
|
107
|
+
enabled: false,
|
|
108
|
+
icon: 'aws',
|
|
109
|
+
key: '',
|
|
110
|
+
secret: '',
|
|
111
|
+
subdomain: 'my.subdomain.com',
|
|
112
|
+
callback: `${strapi.config.server.url}/auth/cognito/callback`,
|
|
113
|
+
scope: ['email', 'openid', 'profile'],
|
|
114
|
+
},
|
|
115
|
+
reddit: {
|
|
116
|
+
enabled: false,
|
|
117
|
+
icon: 'reddit',
|
|
118
|
+
key: '',
|
|
119
|
+
secret: '',
|
|
120
|
+
state: true,
|
|
121
|
+
callback: `${strapi.config.server.url}/auth/reddit/callback`,
|
|
122
|
+
scope: ['identity'],
|
|
123
|
+
},
|
|
124
|
+
auth0: {
|
|
125
|
+
enabled: false,
|
|
126
|
+
icon: '',
|
|
127
|
+
key: '',
|
|
128
|
+
secret: '',
|
|
129
|
+
subdomain: 'my-tenant.eu',
|
|
130
|
+
callback: `${strapi.config.server.url}/auth/auth0/callback`,
|
|
131
|
+
scope: ['openid', 'email', 'profile'],
|
|
132
|
+
},
|
|
133
|
+
cas: {
|
|
134
|
+
enabled: false,
|
|
135
|
+
icon: 'book',
|
|
136
|
+
key: '',
|
|
137
|
+
secret: '',
|
|
138
|
+
callback: `${strapi.config.server.url}/auth/cas/callback`,
|
|
139
|
+
scope: ['openid email'], // scopes should be space delimited
|
|
140
|
+
subdomain: 'my.subdomain.com/cas',
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
const prevGrantConfig = (await pluginStore.get({ key: 'grant' })) || {};
|
|
144
|
+
// store grant auth config to db
|
|
145
|
+
// when plugin_users-permissions_grant is not existed in db
|
|
146
|
+
// or we have added/deleted provider here.
|
|
147
|
+
if (!prevGrantConfig || !_.isEqual(_.keys(prevGrantConfig), _.keys(grantConfig))) {
|
|
148
|
+
// merge with the previous provider config.
|
|
149
|
+
_.keys(grantConfig).forEach(key => {
|
|
150
|
+
if (key in prevGrantConfig) {
|
|
151
|
+
grantConfig[key] = _.merge(grantConfig[key], prevGrantConfig[key]);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
await pluginStore.set({ key: 'grant', value: grantConfig });
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (!(await pluginStore.get({ key: 'email' }))) {
|
|
158
|
+
const value = {
|
|
159
|
+
reset_password: {
|
|
160
|
+
display: 'Email.template.reset_password',
|
|
161
|
+
icon: 'sync',
|
|
162
|
+
options: {
|
|
163
|
+
from: {
|
|
164
|
+
name: 'Administration Panel',
|
|
165
|
+
email: 'no-reply@strapi.io',
|
|
166
|
+
},
|
|
167
|
+
response_email: '',
|
|
168
|
+
object: 'Reset password',
|
|
169
|
+
message: `<p>We heard that you lost your password. Sorry about that!</p>
|
|
170
|
+
|
|
171
|
+
<p>But don’t worry! You can use the following link to reset your password:</p>
|
|
172
|
+
<p><%= URL %>?code=<%= TOKEN %></p>
|
|
173
|
+
|
|
174
|
+
<p>Thanks.</p>`,
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
email_confirmation: {
|
|
178
|
+
display: 'Email.template.email_confirmation',
|
|
179
|
+
icon: 'check-square',
|
|
180
|
+
options: {
|
|
181
|
+
from: {
|
|
182
|
+
name: 'Administration Panel',
|
|
183
|
+
email: 'no-reply@strapi.io',
|
|
184
|
+
},
|
|
185
|
+
response_email: '',
|
|
186
|
+
object: 'Account confirmation',
|
|
187
|
+
message: `<p>Thank you for registering!</p>
|
|
188
|
+
|
|
189
|
+
<p>You have to confirm your email address. Please click on the link below.</p>
|
|
190
|
+
|
|
191
|
+
<p><%= URL %>?confirmation=<%= CODE %></p>
|
|
192
|
+
|
|
193
|
+
<p>Thanks.</p>`,
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
await pluginStore.set({ key: 'email', value });
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (!(await pluginStore.get({ key: 'advanced' }))) {
|
|
202
|
+
const value = {
|
|
203
|
+
unique_email: true,
|
|
204
|
+
allow_register: true,
|
|
205
|
+
email_confirmation: false,
|
|
206
|
+
email_reset_password: null,
|
|
207
|
+
email_confirmation_redirection: null,
|
|
208
|
+
default_role: 'authenticated',
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
await pluginStore.set({ key: 'advanced', value });
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
await strapi.plugins['users-permissions'].services.userspermissions.initialize();
|
|
215
|
+
|
|
216
|
+
if (!_.get(strapi.plugins['users-permissions'], 'config.jwtSecret')) {
|
|
217
|
+
const jwtSecret = uuid();
|
|
218
|
+
_.set(strapi.plugins['users-permissions'], 'config.jwtSecret', jwtSecret);
|
|
219
|
+
|
|
220
|
+
strapi.reload.isWatching = false;
|
|
221
|
+
|
|
222
|
+
await strapi.fs.writePluginFile(
|
|
223
|
+
'users-permissions',
|
|
224
|
+
'config/jwt.js',
|
|
225
|
+
`module.exports = {\n jwtSecret: process.env.JWT_SECRET || '${jwtSecret}'\n};`
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
strapi.reload.isWatching = true;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
await strapi.admin.services.permission.actionProvider.registerMany(
|
|
232
|
+
usersPermissionsActions.actions
|
|
233
|
+
);
|
|
234
|
+
};
|
package/config/layout.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
|
|
5
|
+
module.exports = async (ctx, next) => {
|
|
6
|
+
let role;
|
|
7
|
+
|
|
8
|
+
if (ctx.state.user) {
|
|
9
|
+
// request is already authenticated in a different way
|
|
10
|
+
return next();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (ctx.request && ctx.request.header && ctx.request.header.authorization) {
|
|
14
|
+
try {
|
|
15
|
+
const { id } = await strapi.plugins['users-permissions'].services.jwt.getToken(ctx);
|
|
16
|
+
|
|
17
|
+
if (id === undefined) {
|
|
18
|
+
throw new Error('Invalid token: Token did not contain required fields');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// fetch authenticated user
|
|
22
|
+
ctx.state.user = await strapi.plugins[
|
|
23
|
+
'users-permissions'
|
|
24
|
+
].services.user.fetchAuthenticatedUser(id);
|
|
25
|
+
} catch (err) {
|
|
26
|
+
return handleErrors(ctx, err, 'unauthorized');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (!ctx.state.user) {
|
|
30
|
+
return handleErrors(ctx, 'User Not Found', 'unauthorized');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
role = ctx.state.user.role;
|
|
34
|
+
|
|
35
|
+
if (role.type === 'root') {
|
|
36
|
+
return await next();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const store = await strapi.store({
|
|
40
|
+
environment: '',
|
|
41
|
+
type: 'plugin',
|
|
42
|
+
name: 'users-permissions',
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
if (
|
|
46
|
+
_.get(await store.get({ key: 'advanced' }), 'email_confirmation') &&
|
|
47
|
+
!ctx.state.user.confirmed
|
|
48
|
+
) {
|
|
49
|
+
return handleErrors(ctx, 'Your account email is not confirmed.', 'unauthorized');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (ctx.state.user.blocked) {
|
|
53
|
+
return handleErrors(
|
|
54
|
+
ctx,
|
|
55
|
+
'Your account has been blocked by the administrator.',
|
|
56
|
+
'unauthorized'
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Retrieve `public` role.
|
|
62
|
+
if (!role) {
|
|
63
|
+
role = await strapi.query('role', 'users-permissions').findOne({ type: 'public' }, []);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const route = ctx.request.route;
|
|
67
|
+
const permission = await strapi.query('permission', 'users-permissions').findOne(
|
|
68
|
+
{
|
|
69
|
+
role: role.id,
|
|
70
|
+
type: route.plugin || 'application',
|
|
71
|
+
controller: route.controller,
|
|
72
|
+
action: route.action,
|
|
73
|
+
enabled: true,
|
|
74
|
+
},
|
|
75
|
+
[]
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
if (!permission) {
|
|
79
|
+
return handleErrors(ctx, undefined, 'forbidden');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Execute the policies.
|
|
83
|
+
if (permission.policy) {
|
|
84
|
+
return await strapi.plugins['users-permissions'].config.policies[permission.policy](ctx, next);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Execute the action.
|
|
88
|
+
await next();
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const handleErrors = (ctx, err = undefined, type) => {
|
|
92
|
+
throw strapi.errors[type](err);
|
|
93
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const lazyRateLimit = {
|
|
4
|
+
get RateLimit() {
|
|
5
|
+
return require('koa2-ratelimit').RateLimit;
|
|
6
|
+
},
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
module.exports = async (ctx, next) => {
|
|
10
|
+
const message = [
|
|
11
|
+
{
|
|
12
|
+
messages: [
|
|
13
|
+
{
|
|
14
|
+
id: 'Auth.form.error.ratelimit',
|
|
15
|
+
message: 'Too many attempts, please try again in a minute.',
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
return lazyRateLimit.RateLimit.middleware(
|
|
22
|
+
Object.assign(
|
|
23
|
+
{},
|
|
24
|
+
{
|
|
25
|
+
interval: 1 * 60 * 1000,
|
|
26
|
+
max: 5,
|
|
27
|
+
prefixKey: `${ctx.request.path}:${ctx.request.ip}`,
|
|
28
|
+
message,
|
|
29
|
+
},
|
|
30
|
+
strapi.plugins['users-permissions'].config.ratelimit
|
|
31
|
+
)
|
|
32
|
+
)(ctx, next);
|
|
33
|
+
};
|