@nocobase/plugin-public-forms 1.4.0-alpha
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.txt +159 -0
- package/client.d.ts +2 -0
- package/client.js +1 -0
- package/dist/client/collections/index.d.ts +9 -0
- package/dist/client/collections/publicForms.d.ts +72 -0
- package/dist/client/components/AdminPublicFormList.d.ts +10 -0
- package/dist/client/components/AdminPublicFormPage.d.ts +10 -0
- package/dist/client/components/ConfigureLink.d.ts +10 -0
- package/dist/client/components/PublicFormPage.d.ts +12 -0
- package/dist/client/components/UnEnabledFormPlaceholder.d.ts +11 -0
- package/dist/client/hooks/index.d.ts +12 -0
- package/dist/client/hooks/useDeleteActionProps.d.ts +10 -0
- package/dist/client/hooks/useEditFormProps.d.ts +11 -0
- package/dist/client/hooks/usePublicSubmitActionProps.d.ts +4 -0
- package/dist/client/hooks/useSubmitActionProps.d.ts +12 -0
- package/dist/client/index.d.ts +20 -0
- package/dist/client/index.js +17 -0
- package/dist/client/locale.d.ts +12 -0
- package/dist/client/schemas/createActionSchema.d.ts +70 -0
- package/dist/client/schemas/editActionSchema.d.ts +81 -0
- package/dist/client/schemas/formSchemaCallback.d.ts +46 -0
- package/dist/client/schemas/index.d.ts +9 -0
- package/dist/client/schemas/publicForms.d.ts +10 -0
- package/dist/client/settings/index.d.ts +11 -0
- package/dist/externalVersion.js +26 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +48 -0
- package/dist/locale/zh-CN.json +18 -0
- package/dist/server/collections/publicForms.d.ts +10 -0
- package/dist/server/collections/publicForms.js +69 -0
- package/dist/server/hook.d.ts +21 -0
- package/dist/server/hook.js +121 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +42 -0
- package/dist/server/plugin.d.ts +47 -0
- package/dist/server/plugin.js +224 -0
- package/package.json +20 -0
- package/server.d.ts +2 -0
- package/server.js +1 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var plugin_exports = {};
|
|
28
|
+
__export(plugin_exports, {
|
|
29
|
+
PluginPublicFormsServer: () => PluginPublicFormsServer,
|
|
30
|
+
default: () => plugin_default
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(plugin_exports);
|
|
33
|
+
var import_server = require("@nocobase/server");
|
|
34
|
+
var import_hook = require("./hook");
|
|
35
|
+
class PasswordError extends Error {
|
|
36
|
+
}
|
|
37
|
+
class PluginPublicFormsServer extends import_server.Plugin {
|
|
38
|
+
async parseCollectionData(formCollection, appends) {
|
|
39
|
+
const collection = this.db.getCollection(formCollection);
|
|
40
|
+
const collections = [
|
|
41
|
+
{
|
|
42
|
+
name: collection.name,
|
|
43
|
+
fields: collection.getFields().map((v) => {
|
|
44
|
+
return {
|
|
45
|
+
...v.options
|
|
46
|
+
};
|
|
47
|
+
}),
|
|
48
|
+
template: collection.options.template
|
|
49
|
+
}
|
|
50
|
+
];
|
|
51
|
+
return collections.concat(
|
|
52
|
+
appends.map((v) => {
|
|
53
|
+
const targetCollection = this.db.getCollection(v);
|
|
54
|
+
return {
|
|
55
|
+
name: targetCollection.name,
|
|
56
|
+
fields: targetCollection.getFields().map((v2) => {
|
|
57
|
+
return {
|
|
58
|
+
...v2.options
|
|
59
|
+
};
|
|
60
|
+
}),
|
|
61
|
+
template: targetCollection.options.template
|
|
62
|
+
};
|
|
63
|
+
})
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
async getMetaByTk(filterByTk, options) {
|
|
67
|
+
const { token, password } = options;
|
|
68
|
+
const publicForms = this.db.getRepository("publicForms");
|
|
69
|
+
const uiSchema = this.db.getRepository("uiSchemas");
|
|
70
|
+
const instance = await publicForms.findOne({
|
|
71
|
+
filter: {
|
|
72
|
+
key: filterByTk
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
if (!instance) {
|
|
76
|
+
throw new Error("The form is not found");
|
|
77
|
+
}
|
|
78
|
+
if (!instance.get("enabled")) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
if (!token) {
|
|
82
|
+
if (instance.get("password")) {
|
|
83
|
+
if (password === void 0) {
|
|
84
|
+
return {
|
|
85
|
+
passwordRequired: true
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
if (instance.get("password") !== password) {
|
|
89
|
+
throw new PasswordError("Please enter your password");
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const keys = instance.collection.split(":");
|
|
94
|
+
const collectionName = keys.pop();
|
|
95
|
+
const dataSourceKey = keys.pop() || "main";
|
|
96
|
+
const schema = await uiSchema.getJsonSchema(filterByTk);
|
|
97
|
+
const { getAssociationAppends } = (0, import_hook.parseAssociationNames)(dataSourceKey, collectionName, this.app, schema);
|
|
98
|
+
const { appends } = getAssociationAppends();
|
|
99
|
+
const collections = await this.parseCollectionData(collectionName, appends);
|
|
100
|
+
return {
|
|
101
|
+
dataSource: {
|
|
102
|
+
key: dataSourceKey,
|
|
103
|
+
displayName: dataSourceKey,
|
|
104
|
+
collections
|
|
105
|
+
},
|
|
106
|
+
token: this.app.authManager.jwt.sign(
|
|
107
|
+
{
|
|
108
|
+
collectionName,
|
|
109
|
+
formKey: filterByTk,
|
|
110
|
+
targetCollections: appends
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
expiresIn: "1h"
|
|
114
|
+
}
|
|
115
|
+
),
|
|
116
|
+
schema
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// TODO
|
|
120
|
+
getPublicFormsMeta = async (ctx, next) => {
|
|
121
|
+
const token = ctx.get("X-Form-Token");
|
|
122
|
+
const { filterByTk, password } = ctx.action.params;
|
|
123
|
+
try {
|
|
124
|
+
ctx.body = await this.getMetaByTk(filterByTk, { password, token });
|
|
125
|
+
} catch (error) {
|
|
126
|
+
if (error instanceof PasswordError) {
|
|
127
|
+
ctx.throw(401, error.message);
|
|
128
|
+
} else {
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
await next();
|
|
133
|
+
};
|
|
134
|
+
parseToken = async (ctx, next) => {
|
|
135
|
+
if (!ctx.action) {
|
|
136
|
+
return next();
|
|
137
|
+
}
|
|
138
|
+
const { actionName, resourceName, params } = ctx.action;
|
|
139
|
+
if (resourceName === "publicForms" && actionName === "getMeta" && params.password) {
|
|
140
|
+
return next();
|
|
141
|
+
}
|
|
142
|
+
const jwt = this.app.authManager.jwt;
|
|
143
|
+
const token = ctx.get("X-Form-Token");
|
|
144
|
+
if (token) {
|
|
145
|
+
try {
|
|
146
|
+
const tokenData = await jwt.decode(token);
|
|
147
|
+
ctx.PublicForm = {
|
|
148
|
+
collectionName: tokenData.collectionName,
|
|
149
|
+
formKey: tokenData.formKey,
|
|
150
|
+
targetCollections: tokenData.targetCollections
|
|
151
|
+
};
|
|
152
|
+
const publicForms = this.db.getRepository("publicForms");
|
|
153
|
+
const instance = await publicForms.findOne({
|
|
154
|
+
filter: {
|
|
155
|
+
key: tokenData.formKey
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
if (!instance) {
|
|
159
|
+
throw new Error("The form is not found");
|
|
160
|
+
}
|
|
161
|
+
if (!instance.get("enabled")) {
|
|
162
|
+
throw new Error("The form is not enabled");
|
|
163
|
+
}
|
|
164
|
+
const actionName2 = ctx.action.actionName;
|
|
165
|
+
if (actionName2 === "publicSubmit") {
|
|
166
|
+
ctx.action.actionName = "create";
|
|
167
|
+
}
|
|
168
|
+
} catch (error) {
|
|
169
|
+
ctx.throw(401, error.message);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
await next();
|
|
173
|
+
};
|
|
174
|
+
parseACL = async (ctx, next) => {
|
|
175
|
+
if (!ctx.PublicForm) {
|
|
176
|
+
return next();
|
|
177
|
+
}
|
|
178
|
+
const { resourceName, actionName } = ctx.action;
|
|
179
|
+
if (actionName === "create" && ctx.PublicForm["collectionName"] === resourceName) {
|
|
180
|
+
ctx.permission = {
|
|
181
|
+
skip: true
|
|
182
|
+
};
|
|
183
|
+
} else if (actionName === "list" && ctx.PublicForm["targetCollections"].includes(resourceName)) {
|
|
184
|
+
ctx.permission = {
|
|
185
|
+
skip: true
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
await next();
|
|
189
|
+
};
|
|
190
|
+
async load() {
|
|
191
|
+
this.app.acl.registerSnippet({
|
|
192
|
+
name: `pm.${this.name}`,
|
|
193
|
+
actions: ["publicForms:*"]
|
|
194
|
+
});
|
|
195
|
+
this.app.acl.allow("publicForms", "getMeta", "public");
|
|
196
|
+
this.app.resourceManager.registerActionHandlers({
|
|
197
|
+
"publicForms:getMeta": this.getPublicFormsMeta
|
|
198
|
+
});
|
|
199
|
+
this.app.dataSourceManager.afterAddDataSource((dataSource) => {
|
|
200
|
+
dataSource.resourceManager.use(this.parseToken, {
|
|
201
|
+
before: "acl"
|
|
202
|
+
});
|
|
203
|
+
dataSource.acl.use(this.parseACL, {
|
|
204
|
+
before: "core"
|
|
205
|
+
});
|
|
206
|
+
dataSource.resourceManager.registerActionHandlers({
|
|
207
|
+
publicSubmit: dataSource.resourceManager.getRegisteredHandler("create")
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
async install() {
|
|
212
|
+
}
|
|
213
|
+
async afterEnable() {
|
|
214
|
+
}
|
|
215
|
+
async afterDisable() {
|
|
216
|
+
}
|
|
217
|
+
async remove() {
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
var plugin_default = PluginPublicFormsServer;
|
|
221
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
222
|
+
0 && (module.exports = {
|
|
223
|
+
PluginPublicFormsServer
|
|
224
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nocobase/plugin-public-forms",
|
|
3
|
+
"version": "1.4.0-alpha",
|
|
4
|
+
"main": "dist/server/index.js",
|
|
5
|
+
"displayName": "Public forms",
|
|
6
|
+
"displayName.zh-CN": "公开表单",
|
|
7
|
+
"description": "Share public forms externally to collect information from anonymous users",
|
|
8
|
+
"description.zh-CN": "对外分享公开表单,向匿名用户收集信息。",
|
|
9
|
+
"license": "AGPL-3.0",
|
|
10
|
+
"homepage": "https://docs.nocobase.com/handbook/public-form",
|
|
11
|
+
"homepage.zh-CN": "https://docs-cn.nocobase.com/public-form",
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"@nocobase/client": "1.x",
|
|
14
|
+
"@nocobase/plugin-client": "1.x",
|
|
15
|
+
"@nocobase/plugin-ui-schema-storage": "1.x",
|
|
16
|
+
"@nocobase/server": "1.x",
|
|
17
|
+
"@nocobase/test": "1.x"
|
|
18
|
+
},
|
|
19
|
+
"gitHead": "f097a2bddec152522b5645bd5d451f4c866d2060"
|
|
20
|
+
}
|
package/server.d.ts
ADDED
package/server.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./dist/server/index.js');
|