@smartive/graphql-magic 14.0.2 → 15.0.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/.env +1 -1
- package/CHANGELOG.md +1 -6
- package/dist/bin/gqm.cjs +132 -121
- package/dist/cjs/index.cjs +134 -119
- package/dist/esm/client/queries.d.ts +1 -1
- package/dist/esm/client/queries.js +1 -1
- package/dist/esm/client/queries.js.map +1 -1
- package/dist/esm/context.d.ts +1 -1
- package/dist/esm/models/utils.d.ts +4 -4
- package/dist/esm/permissions/check.d.ts +1 -0
- package/dist/esm/permissions/check.js +19 -11
- package/dist/esm/permissions/check.js.map +1 -1
- package/dist/esm/resolvers/filters.js +1 -1
- package/dist/esm/resolvers/filters.js.map +1 -1
- package/dist/esm/resolvers/mutations.js +4 -4
- package/dist/esm/resolvers/mutations.js.map +1 -1
- package/dist/esm/resolvers/resolver.js +3 -0
- package/dist/esm/resolvers/resolver.js.map +1 -1
- package/dist/esm/resolvers/resolvers.d.ts +1 -1
- package/dist/esm/resolvers/resolvers.js +29 -23
- package/dist/esm/resolvers/resolvers.js.map +1 -1
- package/dist/esm/resolvers/selects.js +4 -3
- package/dist/esm/resolvers/selects.js.map +1 -1
- package/dist/esm/schema/generate.js +76 -72
- package/dist/esm/schema/generate.js.map +1 -1
- package/docker-compose.yml +0 -4
- package/package.json +6 -6
- package/src/bin/gqm/codegen.ts +3 -1
- package/src/bin/gqm/gqm.ts +3 -69
- package/src/bin/gqm/parse-knexfile.ts +5 -6
- package/src/bin/gqm/settings.ts +29 -3
- package/src/bin/gqm/templates.ts +70 -8
- package/src/client/queries.ts +2 -2
- package/src/context.ts +1 -1
- package/src/permissions/check.ts +24 -16
- package/src/resolvers/filters.ts +1 -1
- package/src/resolvers/mutations.ts +4 -4
- package/src/resolvers/resolver.ts +4 -0
- package/src/resolvers/resolvers.ts +33 -27
- package/src/resolvers/selects.ts +4 -3
- package/src/schema/generate.ts +78 -72
package/dist/cjs/index.cjs
CHANGED
|
@@ -96,6 +96,7 @@ __export(src_exports, {
|
|
|
96
96
|
getPermissionStack: () => getPermissionStack,
|
|
97
97
|
getResolverNode: () => getResolverNode,
|
|
98
98
|
getResolvers: () => getResolvers,
|
|
99
|
+
getRole: () => getRole,
|
|
99
100
|
getRootFieldNode: () => getRootFieldNode,
|
|
100
101
|
getSelectEntityRelationsQuery: () => getSelectEntityRelationsQuery,
|
|
101
102
|
getSimpleFields: () => getSimpleFields,
|
|
@@ -768,7 +769,7 @@ var getUpdateEntityQuery = (model, role, fields2, additionalFields = "") => `que
|
|
|
768
769
|
data: ${typeToField(model.name)}(where: { id: $id }) {
|
|
769
770
|
id
|
|
770
771
|
${model.fields.filter(({ name: name2 }) => !fields2 || fields2.includes(name2)).filter(not(isRelation)).filter(isUpdatableBy(role)).map(({ name: name2 }) => name2).join(" ")}
|
|
771
|
-
${getActionableRelations(model, "update").filter((name2) => !fields2 || fields2.includes(name2)).map((name2) => `${name2} { id }`)}
|
|
772
|
+
${getActionableRelations(model, "update").filter((name2) => !fields2 || fields2.includes(name2)).map((name2) => `${name2} { id, display: ${model.getRelation(name2).targetModel.displayField || "id"} }`)}
|
|
772
773
|
${additionalFields}
|
|
773
774
|
}
|
|
774
775
|
}`;
|
|
@@ -1689,8 +1690,9 @@ var getColumn = (node, key) => {
|
|
|
1689
1690
|
};
|
|
1690
1691
|
|
|
1691
1692
|
// src/permissions/check.ts
|
|
1693
|
+
var getRole = (ctx) => ctx.user?.role ?? "UNAUTHENTICATED";
|
|
1692
1694
|
var getPermissionStack = (ctx, type, action) => {
|
|
1693
|
-
const rolePermissions = ctx.permissions[ctx
|
|
1695
|
+
const rolePermissions = ctx.permissions[getRole(ctx)];
|
|
1694
1696
|
if (typeof rolePermissions === "boolean" || rolePermissions === void 0) {
|
|
1695
1697
|
return !!rolePermissions;
|
|
1696
1698
|
}
|
|
@@ -1710,7 +1712,7 @@ var applyPermissions = (ctx, type, tableAlias, query, action, verifiedPermission
|
|
|
1710
1712
|
return permissionStack;
|
|
1711
1713
|
}
|
|
1712
1714
|
if (permissionStack === false) {
|
|
1713
|
-
console.error(`No applicable permissions exist for ${ctx
|
|
1715
|
+
console.error(`No applicable permissions exist for ${getRole(ctx)} ${type} ${action}.`);
|
|
1714
1716
|
query.where(false);
|
|
1715
1717
|
return permissionStack;
|
|
1716
1718
|
}
|
|
@@ -1745,7 +1747,7 @@ var getEntityToMutate = async (ctx, model, where, action) => {
|
|
|
1745
1747
|
console.error(
|
|
1746
1748
|
`Permission error: ${Object.entries(where).map(([key, value2]) => `${key}: ${value2}`).join(", ")}`
|
|
1747
1749
|
);
|
|
1748
|
-
throw new PermissionError(ctx
|
|
1750
|
+
throw new PermissionError(getRole(ctx), action, `this ${model.name}`, "no available permissions applied");
|
|
1749
1751
|
}
|
|
1750
1752
|
if (model.parent) {
|
|
1751
1753
|
const subEntity = await ctx.knex(model.name).where({ id: entity.id }).first();
|
|
@@ -1759,7 +1761,7 @@ var checkCanWrite = async (ctx, model, data, action) => {
|
|
|
1759
1761
|
return;
|
|
1760
1762
|
}
|
|
1761
1763
|
if (permissionStack === false) {
|
|
1762
|
-
throw new PermissionError(ctx
|
|
1764
|
+
throw new PermissionError(getRole(ctx), action, model.plural, "no applicable permissions");
|
|
1763
1765
|
}
|
|
1764
1766
|
const query = ctx.knex.select(1).first();
|
|
1765
1767
|
let linked = false;
|
|
@@ -1770,13 +1772,9 @@ var checkCanWrite = async (ctx, model, data, action) => {
|
|
|
1770
1772
|
continue;
|
|
1771
1773
|
}
|
|
1772
1774
|
const fieldPermissions = field[action === "CREATE" ? "creatable" : "updatable"];
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
action,
|
|
1777
|
-
`this ${model.name}'s ${field.name}`,
|
|
1778
|
-
"field permission not available"
|
|
1779
|
-
);
|
|
1775
|
+
const role2 = getRole(ctx);
|
|
1776
|
+
if (fieldPermissions && typeof fieldPermissions === "object" && !fieldPermissions.roles?.includes(role2)) {
|
|
1777
|
+
throw new PermissionError(role2, action, `this ${model.name}'s ${field.name}`, "field permission not available");
|
|
1780
1778
|
}
|
|
1781
1779
|
linked = true;
|
|
1782
1780
|
const fieldPermissionStack = getPermissionStack(ctx, field.type, "LINK");
|
|
@@ -1786,7 +1784,7 @@ var checkCanWrite = async (ctx, model, data, action) => {
|
|
|
1786
1784
|
}
|
|
1787
1785
|
if (fieldPermissionStack === false || !fieldPermissionStack.length) {
|
|
1788
1786
|
throw new PermissionError(
|
|
1789
|
-
|
|
1787
|
+
role2,
|
|
1790
1788
|
action,
|
|
1791
1789
|
`this ${model.name}'s ${field.name}`,
|
|
1792
1790
|
"no applicable permissions on data to link"
|
|
@@ -1799,23 +1797,28 @@ var checkCanWrite = async (ctx, model, data, action) => {
|
|
|
1799
1797
|
)
|
|
1800
1798
|
);
|
|
1801
1799
|
}
|
|
1800
|
+
const role = getRole(ctx);
|
|
1802
1801
|
if (linked) {
|
|
1803
1802
|
const canMutate = await query;
|
|
1804
1803
|
if (!canMutate) {
|
|
1805
|
-
throw new PermissionError(
|
|
1804
|
+
throw new PermissionError(role, action, `this ${model.name}`, "no linkable entities");
|
|
1806
1805
|
}
|
|
1807
1806
|
} else if (action === "CREATE") {
|
|
1808
|
-
throw new PermissionError(
|
|
1807
|
+
throw new PermissionError(role, action, `this ${model.name}`, "no linkable entities");
|
|
1809
1808
|
}
|
|
1810
1809
|
};
|
|
1811
1810
|
var permissionLinkQuery = (ctx, subQuery, links, id) => {
|
|
1812
1811
|
const aliases = new AliasGenerator();
|
|
1813
1812
|
let alias = aliases.getShort();
|
|
1814
1813
|
const { type, me, where } = links[0];
|
|
1815
|
-
subQuery.from(`${type} as ${alias}`);
|
|
1816
1814
|
if (me) {
|
|
1815
|
+
if (!ctx.user) {
|
|
1816
|
+
subQuery.where(false);
|
|
1817
|
+
return;
|
|
1818
|
+
}
|
|
1817
1819
|
subQuery.where({ [`${alias}.id`]: ctx.user.id });
|
|
1818
1820
|
}
|
|
1821
|
+
subQuery.from(`${type} as ${alias}`);
|
|
1819
1822
|
if (where) {
|
|
1820
1823
|
applyWhere(ctx.models.getModel(type, "entity"), subQuery, alias, where, aliases);
|
|
1821
1824
|
}
|
|
@@ -2052,7 +2055,7 @@ var applyFilters = (node, query, joins) => {
|
|
|
2052
2055
|
normalizedArguments.where = {};
|
|
2053
2056
|
}
|
|
2054
2057
|
if (normalizedArguments.where.deleted && (!Array.isArray(normalizedArguments.where.deleted) || normalizedArguments.where.deleted.some((v) => v))) {
|
|
2055
|
-
if (node.ctx.user
|
|
2058
|
+
if (node.ctx.user?.role !== "ADMIN") {
|
|
2056
2059
|
throw new ForbiddenError("You cannot access deleted entries.");
|
|
2057
2060
|
}
|
|
2058
2061
|
} else {
|
|
@@ -2325,9 +2328,10 @@ var applySelects = (node, query, joins) => {
|
|
|
2325
2328
|
if (!field || field.kind === "relation" || field.kind === "custom") {
|
|
2326
2329
|
return false;
|
|
2327
2330
|
}
|
|
2328
|
-
|
|
2331
|
+
const role = getRole(node.ctx);
|
|
2332
|
+
if (typeof field.queriable === "object" && !field.queriable.roles?.includes(role)) {
|
|
2329
2333
|
throw new PermissionError(
|
|
2330
|
-
|
|
2334
|
+
role,
|
|
2331
2335
|
"READ",
|
|
2332
2336
|
`${node.model.name}'s field "${field.name}"`,
|
|
2333
2337
|
"field permission not available"
|
|
@@ -2382,6 +2386,9 @@ var resolve = async (ctx, id) => {
|
|
|
2382
2386
|
});
|
|
2383
2387
|
const { query, verifiedPermissionStacks } = await buildQuery(node);
|
|
2384
2388
|
if (ctx.info.fieldName === "me") {
|
|
2389
|
+
if (!node.ctx.user.id) {
|
|
2390
|
+
return void 0;
|
|
2391
|
+
}
|
|
2385
2392
|
void query.where({ [getColumn(node, "id")]: node.ctx.user.id });
|
|
2386
2393
|
}
|
|
2387
2394
|
if (id) {
|
|
@@ -2510,7 +2517,7 @@ var create = async (model, { data: input2 }, ctx) => {
|
|
|
2510
2517
|
const normalizedInput = { ...input2 };
|
|
2511
2518
|
normalizedInput.id = (0, import_uuid.v4)();
|
|
2512
2519
|
normalizedInput.createdAt = ctx.now;
|
|
2513
|
-
normalizedInput.createdById = ctx.user
|
|
2520
|
+
normalizedInput.createdById = ctx.user?.id;
|
|
2514
2521
|
if (model.parent) {
|
|
2515
2522
|
normalizedInput.type = model.name;
|
|
2516
2523
|
}
|
|
@@ -2612,7 +2619,7 @@ var del = async (model, { where, dryRun }, ctx) => {
|
|
|
2612
2619
|
}
|
|
2613
2620
|
toDelete[currentModel.name][entity2.id] = entity2[currentModel.displayField || "id"] || entity2.id;
|
|
2614
2621
|
if (!dryRun) {
|
|
2615
|
-
const normalizedInput = { deleted: true, deletedAt: ctx.now, deletedById: ctx.user
|
|
2622
|
+
const normalizedInput = { deleted: true, deletedAt: ctx.now, deletedById: ctx.user?.id };
|
|
2616
2623
|
const data = { prev: entity2, input: {}, normalizedInput, next: { ...entity2, ...normalizedInput } };
|
|
2617
2624
|
if (ctx.mutationHook) {
|
|
2618
2625
|
beforeHooks.push(async () => {
|
|
@@ -2744,7 +2751,7 @@ var createRevision = async (model, data, ctx) => {
|
|
|
2744
2751
|
id: revisionId,
|
|
2745
2752
|
[`${typeToField(model.parent || model.name)}Id`]: data.id,
|
|
2746
2753
|
createdAt: ctx.now,
|
|
2747
|
-
createdById: ctx.user
|
|
2754
|
+
createdById: ctx.user?.id
|
|
2748
2755
|
};
|
|
2749
2756
|
if (model.deletable) {
|
|
2750
2757
|
rootRevisionData.deleted = data.deleted || false;
|
|
@@ -2775,7 +2782,7 @@ var createRevision = async (model, data, ctx) => {
|
|
|
2775
2782
|
var sanitize = (ctx, model, data) => {
|
|
2776
2783
|
if (model.updatable) {
|
|
2777
2784
|
data.updatedAt = ctx.now;
|
|
2778
|
-
data.updatedById = ctx.user
|
|
2785
|
+
data.updatedById = ctx.user?.id;
|
|
2779
2786
|
}
|
|
2780
2787
|
for (const key of Object.keys(data)) {
|
|
2781
2788
|
const field = model.fields.find(({ name: name2 }) => name2 === key);
|
|
@@ -2795,19 +2802,21 @@ var sanitize = (ctx, model, data) => {
|
|
|
2795
2802
|
var isEndOfDay = (field) => isPrimitive(field) && field.type === "DateTime" && field?.endOfDay === true && field?.dateTimeType === "date";
|
|
2796
2803
|
|
|
2797
2804
|
// src/resolvers/resolvers.ts
|
|
2798
|
-
var getResolvers = (models) =>
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2805
|
+
var getResolvers = (models) => {
|
|
2806
|
+
const resolvers = {
|
|
2807
|
+
Query: merge2([
|
|
2808
|
+
{
|
|
2809
|
+
me: queryResolver
|
|
2810
|
+
},
|
|
2811
|
+
...models.entities.filter(({ queriable }) => queriable).map((model) => ({
|
|
2812
|
+
[typeToField(model.name)]: queryResolver
|
|
2813
|
+
})),
|
|
2814
|
+
...models.entities.filter(({ listQueriable }) => listQueriable).map((model) => ({
|
|
2815
|
+
[model.pluralField]: queryResolver
|
|
2816
|
+
}))
|
|
2817
|
+
])
|
|
2818
|
+
};
|
|
2819
|
+
const mutations = [
|
|
2811
2820
|
...models.entities.filter(not(isRootModel)).filter(({ creatable }) => creatable).map((model) => ({
|
|
2812
2821
|
[`create${model.name}`]: mutationResolver
|
|
2813
2822
|
})),
|
|
@@ -2818,16 +2827,17 @@ var getResolvers = (models) => ({
|
|
|
2818
2827
|
[`delete${model.name}`]: mutationResolver,
|
|
2819
2828
|
[`restore${model.name}`]: mutationResolver
|
|
2820
2829
|
}))
|
|
2821
|
-
]
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
}
|
|
2828
|
-
}
|
|
2829
|
-
|
|
2830
|
-
|
|
2830
|
+
];
|
|
2831
|
+
if (mutations.length) {
|
|
2832
|
+
resolvers.Mutation = merge2(mutations);
|
|
2833
|
+
}
|
|
2834
|
+
for (const model of models.entities.filter(isRootModel)) {
|
|
2835
|
+
resolvers[model.name] = {
|
|
2836
|
+
__resolveType: ({ TYPE }) => TYPE
|
|
2837
|
+
};
|
|
2838
|
+
}
|
|
2839
|
+
return resolvers;
|
|
2840
|
+
};
|
|
2831
2841
|
|
|
2832
2842
|
// src/schema/generate.ts
|
|
2833
2843
|
var import_graphql5 = require("graphql");
|
|
@@ -2991,7 +3001,7 @@ var generateDefinitions = ({
|
|
|
2991
3001
|
entities,
|
|
2992
3002
|
objects
|
|
2993
3003
|
}) => {
|
|
2994
|
-
|
|
3004
|
+
const definitions = [
|
|
2995
3005
|
// Predefined types
|
|
2996
3006
|
...rawEnums.map((model) => enm(model.name, model.values)),
|
|
2997
3007
|
...enums.map((model) => enm(model.name, model.values)),
|
|
@@ -3135,80 +3145,84 @@ var generateDefinitions = ({
|
|
|
3135
3145
|
]
|
|
3136
3146
|
})),
|
|
3137
3147
|
...objects.filter((model) => model.name === "Query").flatMap((model) => model.fields)
|
|
3138
|
-
]),
|
|
3139
|
-
object("Mutation", [
|
|
3140
|
-
...entities.flatMap((model) => {
|
|
3141
|
-
const mutations = [];
|
|
3142
|
-
if (!isRootModel(model)) {
|
|
3143
|
-
if (model.creatable) {
|
|
3144
|
-
mutations.push({
|
|
3145
|
-
name: `create${model.name}`,
|
|
3146
|
-
type: model.name,
|
|
3147
|
-
nonNull: true,
|
|
3148
|
-
args: [
|
|
3149
|
-
{
|
|
3150
|
-
name: "data",
|
|
3151
|
-
type: `Create${model.name}`,
|
|
3152
|
-
nonNull: true
|
|
3153
|
-
}
|
|
3154
|
-
]
|
|
3155
|
-
});
|
|
3156
|
-
}
|
|
3157
|
-
if (model.updatable) {
|
|
3158
|
-
mutations.push({
|
|
3159
|
-
name: `update${model.name}`,
|
|
3160
|
-
type: model.name,
|
|
3161
|
-
nonNull: true,
|
|
3162
|
-
args: [
|
|
3163
|
-
{
|
|
3164
|
-
name: "where",
|
|
3165
|
-
type: `${model.name}WhereUnique`,
|
|
3166
|
-
nonNull: true
|
|
3167
|
-
},
|
|
3168
|
-
{
|
|
3169
|
-
name: "data",
|
|
3170
|
-
type: `Update${model.name}`,
|
|
3171
|
-
nonNull: true
|
|
3172
|
-
}
|
|
3173
|
-
]
|
|
3174
|
-
});
|
|
3175
|
-
}
|
|
3176
|
-
if (model.deletable) {
|
|
3177
|
-
mutations.push({
|
|
3178
|
-
name: `delete${model.name}`,
|
|
3179
|
-
type: "ID",
|
|
3180
|
-
nonNull: true,
|
|
3181
|
-
args: [
|
|
3182
|
-
{
|
|
3183
|
-
name: "where",
|
|
3184
|
-
type: `${model.name}WhereUnique`,
|
|
3185
|
-
nonNull: true
|
|
3186
|
-
},
|
|
3187
|
-
{
|
|
3188
|
-
name: "dryRun",
|
|
3189
|
-
type: "Boolean"
|
|
3190
|
-
}
|
|
3191
|
-
]
|
|
3192
|
-
});
|
|
3193
|
-
mutations.push({
|
|
3194
|
-
name: `restore${model.name}`,
|
|
3195
|
-
type: "ID",
|
|
3196
|
-
nonNull: true,
|
|
3197
|
-
args: [
|
|
3198
|
-
{
|
|
3199
|
-
name: "where",
|
|
3200
|
-
type: `${model.name}WhereUnique`,
|
|
3201
|
-
nonNull: true
|
|
3202
|
-
}
|
|
3203
|
-
]
|
|
3204
|
-
});
|
|
3205
|
-
}
|
|
3206
|
-
}
|
|
3207
|
-
return mutations;
|
|
3208
|
-
}),
|
|
3209
|
-
...objects.filter((model) => model.name === "Mutation").flatMap((model) => model.fields)
|
|
3210
3148
|
])
|
|
3211
3149
|
];
|
|
3150
|
+
const mutations = [
|
|
3151
|
+
...entities.flatMap((model) => {
|
|
3152
|
+
const mutations2 = [];
|
|
3153
|
+
if (!isRootModel(model)) {
|
|
3154
|
+
if (model.creatable) {
|
|
3155
|
+
mutations2.push({
|
|
3156
|
+
name: `create${model.name}`,
|
|
3157
|
+
type: model.name,
|
|
3158
|
+
nonNull: true,
|
|
3159
|
+
args: [
|
|
3160
|
+
{
|
|
3161
|
+
name: "data",
|
|
3162
|
+
type: `Create${model.name}`,
|
|
3163
|
+
nonNull: true
|
|
3164
|
+
}
|
|
3165
|
+
]
|
|
3166
|
+
});
|
|
3167
|
+
}
|
|
3168
|
+
if (model.updatable) {
|
|
3169
|
+
mutations2.push({
|
|
3170
|
+
name: `update${model.name}`,
|
|
3171
|
+
type: model.name,
|
|
3172
|
+
nonNull: true,
|
|
3173
|
+
args: [
|
|
3174
|
+
{
|
|
3175
|
+
name: "where",
|
|
3176
|
+
type: `${model.name}WhereUnique`,
|
|
3177
|
+
nonNull: true
|
|
3178
|
+
},
|
|
3179
|
+
{
|
|
3180
|
+
name: "data",
|
|
3181
|
+
type: `Update${model.name}`,
|
|
3182
|
+
nonNull: true
|
|
3183
|
+
}
|
|
3184
|
+
]
|
|
3185
|
+
});
|
|
3186
|
+
}
|
|
3187
|
+
if (model.deletable) {
|
|
3188
|
+
mutations2.push({
|
|
3189
|
+
name: `delete${model.name}`,
|
|
3190
|
+
type: "ID",
|
|
3191
|
+
nonNull: true,
|
|
3192
|
+
args: [
|
|
3193
|
+
{
|
|
3194
|
+
name: "where",
|
|
3195
|
+
type: `${model.name}WhereUnique`,
|
|
3196
|
+
nonNull: true
|
|
3197
|
+
},
|
|
3198
|
+
{
|
|
3199
|
+
name: "dryRun",
|
|
3200
|
+
type: "Boolean"
|
|
3201
|
+
}
|
|
3202
|
+
]
|
|
3203
|
+
});
|
|
3204
|
+
mutations2.push({
|
|
3205
|
+
name: `restore${model.name}`,
|
|
3206
|
+
type: "ID",
|
|
3207
|
+
nonNull: true,
|
|
3208
|
+
args: [
|
|
3209
|
+
{
|
|
3210
|
+
name: "where",
|
|
3211
|
+
type: `${model.name}WhereUnique`,
|
|
3212
|
+
nonNull: true
|
|
3213
|
+
}
|
|
3214
|
+
]
|
|
3215
|
+
});
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3218
|
+
return mutations2;
|
|
3219
|
+
}),
|
|
3220
|
+
...objects.filter((model) => model.name === "Mutation").flatMap((model) => model.fields)
|
|
3221
|
+
];
|
|
3222
|
+
if (mutations.length) {
|
|
3223
|
+
definitions.push(object("Mutation", mutations));
|
|
3224
|
+
}
|
|
3225
|
+
return definitions;
|
|
3212
3226
|
};
|
|
3213
3227
|
var generate = (models) => document(generateDefinitions(models));
|
|
3214
3228
|
var printSchema = (schema) => [
|
|
@@ -3287,6 +3301,7 @@ var printSchemaFromModels = (models) => printSchema((0, import_graphql5.buildAST
|
|
|
3287
3301
|
getPermissionStack,
|
|
3288
3302
|
getResolverNode,
|
|
3289
3303
|
getResolvers,
|
|
3304
|
+
getRole,
|
|
3290
3305
|
getRootFieldNode,
|
|
3291
3306
|
getSelectEntityRelationsQuery,
|
|
3292
3307
|
getSimpleFields,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ManyToManyRelation, ReverseRelation } from '..';
|
|
2
2
|
import { EntityModel, Model, Models, Relation } from '../models/models';
|
|
3
|
-
export declare const getUpdateEntityQuery: (model: EntityModel, role:
|
|
3
|
+
export declare const getUpdateEntityQuery: (model: EntityModel, role: string, fields?: string[] | undefined, additionalFields?: string) => string;
|
|
4
4
|
export type RelationConstraints = Record<string, (source: any) => any>;
|
|
5
5
|
export declare const fieldIsSearchable: (model: EntityModel, fieldName: string) => boolean;
|
|
6
6
|
export declare const getSelectEntityRelationsQuery: (model: EntityModel, relationNames: string[]) => string;
|
|
@@ -10,7 +10,7 @@ export const getUpdateEntityQuery = (model, role, fields, additionalFields = '')
|
|
|
10
10
|
.join(' ')}
|
|
11
11
|
${getActionableRelations(model, 'update')
|
|
12
12
|
.filter((name) => !fields || fields.includes(name))
|
|
13
|
-
.map((name) => `${name} { id }`)}
|
|
13
|
+
.map((name) => `${name} { id, display: ${model.getRelation(name).targetModel.displayField || 'id'} }`)}
|
|
14
14
|
${additionalFields}
|
|
15
15
|
}
|
|
16
16
|
}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../../src/client/queries.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,GAAG,EACH,sBAAsB,EACtB,aAAa,EACb,UAAU,EACV,aAAa,EACb,eAAe,EACf,aAAa,EACb,GAAG,EACH,WAAW,GACZ,MAAM,iBAAiB,CAAC;AAEzB,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,KAAkB,EAClB,
|
|
1
|
+
{"version":3,"file":"queries.js","sourceRoot":"","sources":["../../../src/client/queries.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/context.d.ts
CHANGED
|
@@ -119,11 +119,11 @@ export declare const getActionableRelations: (model: EntityModel, action: 'creat
|
|
|
119
119
|
export declare const summonByName: <T extends {
|
|
120
120
|
name: string;
|
|
121
121
|
}>(array: T[], value: string) => T;
|
|
122
|
-
export declare const summonByKey: <T>(array: readonly T[], key: string, value: unknown) => T;
|
|
123
|
-
export declare const summon: <T>(array: readonly T[], cb:
|
|
122
|
+
export declare const summonByKey: <T>(array: readonly T[] | undefined, key: string, value: unknown) => T;
|
|
123
|
+
export declare const summon: <T>(array: readonly T[] | undefined, cb: Parameters<T[]['find']>[1], errorMessage?: string) => T;
|
|
124
124
|
type ForSure<T> = T extends undefined | null ? never : T;
|
|
125
|
-
export declare const it: <T>(object: T) => ForSure<T>;
|
|
126
|
-
export declare const get: <T, U extends keyof ForSure<T>>(object: T, key: U) => ForSure<ForSure<T>[U]>;
|
|
125
|
+
export declare const it: <T>(object: T | null | undefined) => ForSure<T>;
|
|
126
|
+
export declare const get: <T, U extends keyof ForSure<T>>(object: T | null | undefined, key: U) => ForSure<ForSure<T>[U]>;
|
|
127
127
|
export declare const getString: (v: unknown) => string;
|
|
128
128
|
export declare const retry: <T>(cb: () => Promise<T>, condition: (e: any) => boolean) => Promise<T>;
|
|
129
129
|
export {};
|
|
@@ -3,6 +3,7 @@ import { FullContext } from '../context';
|
|
|
3
3
|
import { EntityModel } from '../models/models';
|
|
4
4
|
import { BasicValue } from '../values';
|
|
5
5
|
import { PermissionAction, PermissionStack } from './generate';
|
|
6
|
+
export declare const getRole: (ctx: Pick<FullContext, 'user'>) => string;
|
|
6
7
|
export declare const getPermissionStack: (ctx: Pick<FullContext, 'permissions' | 'user'>, type: string, action: PermissionAction) => boolean | PermissionStack;
|
|
7
8
|
export declare const applyPermissions: (ctx: Pick<FullContext, 'models' | 'permissions' | 'user' | 'knex'>, type: string, tableAlias: string, query: Knex.QueryBuilder, action: PermissionAction, verifiedPermissionStack?: PermissionStack) => boolean | PermissionStack;
|
|
8
9
|
/**
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { NotFoundError, PermissionError } from '../errors';
|
|
2
2
|
import { get, isRelation } from '../models/utils';
|
|
3
3
|
import { AliasGenerator, hash, ors } from '../resolvers/utils';
|
|
4
|
+
export const getRole = (ctx) => ctx.user?.role ?? 'UNAUTHENTICATED';
|
|
4
5
|
export const getPermissionStack = (ctx, type, action) => {
|
|
5
|
-
const rolePermissions = ctx.permissions[ctx
|
|
6
|
+
const rolePermissions = ctx.permissions[getRole(ctx)];
|
|
6
7
|
if (typeof rolePermissions === 'boolean' || rolePermissions === undefined) {
|
|
7
8
|
return !!rolePermissions;
|
|
8
9
|
}
|
|
@@ -22,7 +23,7 @@ export const applyPermissions = (ctx, type, tableAlias, query, action, verifiedP
|
|
|
22
23
|
return permissionStack;
|
|
23
24
|
}
|
|
24
25
|
if (permissionStack === false) {
|
|
25
|
-
console.error(`No applicable permissions exist for ${ctx
|
|
26
|
+
console.error(`No applicable permissions exist for ${getRole(ctx)} ${type} ${action}.`);
|
|
26
27
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises -- we do not need to await knex here
|
|
27
28
|
query.where(false);
|
|
28
29
|
return permissionStack;
|
|
@@ -62,7 +63,7 @@ export const getEntityToMutate = async (ctx, model, where, action) => {
|
|
|
62
63
|
console.error(`Permission error: ${Object.entries(where)
|
|
63
64
|
.map(([key, value]) => `${key}: ${value}`)
|
|
64
65
|
.join(', ')}`);
|
|
65
|
-
throw new PermissionError(ctx
|
|
66
|
+
throw new PermissionError(getRole(ctx), action, `this ${model.name}`, 'no available permissions applied');
|
|
66
67
|
}
|
|
67
68
|
if (model.parent) {
|
|
68
69
|
const subEntity = await ctx.knex(model.name).where({ id: entity.id }).first();
|
|
@@ -79,7 +80,7 @@ export const checkCanWrite = async (ctx, model, data, action) => {
|
|
|
79
80
|
return;
|
|
80
81
|
}
|
|
81
82
|
if (permissionStack === false) {
|
|
82
|
-
throw new PermissionError(ctx
|
|
83
|
+
throw new PermissionError(getRole(ctx), action, model.plural, 'no applicable permissions');
|
|
83
84
|
}
|
|
84
85
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- using `select(1 as any)` to instantiate an "empty" query builder
|
|
85
86
|
const query = ctx.knex.select(1).first();
|
|
@@ -93,8 +94,9 @@ export const checkCanWrite = async (ctx, model, data, action) => {
|
|
|
93
94
|
continue;
|
|
94
95
|
}
|
|
95
96
|
const fieldPermissions = field[action === 'CREATE' ? 'creatable' : 'updatable'];
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
const role = getRole(ctx);
|
|
98
|
+
if (fieldPermissions && typeof fieldPermissions === 'object' && !fieldPermissions.roles?.includes(role)) {
|
|
99
|
+
throw new PermissionError(role, action, `this ${model.name}'s ${field.name}`, 'field permission not available');
|
|
98
100
|
}
|
|
99
101
|
linked = true;
|
|
100
102
|
const fieldPermissionStack = getPermissionStack(ctx, field.type, 'LINK');
|
|
@@ -105,31 +107,37 @@ export const checkCanWrite = async (ctx, model, data, action) => {
|
|
|
105
107
|
continue;
|
|
106
108
|
}
|
|
107
109
|
if (fieldPermissionStack === false || !fieldPermissionStack.length) {
|
|
108
|
-
throw new PermissionError(
|
|
110
|
+
throw new PermissionError(role, action, `this ${model.name}'s ${field.name}`, 'no applicable permissions on data to link');
|
|
109
111
|
}
|
|
110
112
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises -- we do not need to await knex here
|
|
111
113
|
ors(query, fieldPermissionStack.map((links) => (query) => query.whereExists((subQuery) => permissionLinkQuery(ctx, subQuery, links, foreignId))));
|
|
112
114
|
}
|
|
115
|
+
const role = getRole(ctx);
|
|
113
116
|
if (linked) {
|
|
114
117
|
const canMutate = await query;
|
|
115
118
|
if (!canMutate) {
|
|
116
|
-
throw new PermissionError(
|
|
119
|
+
throw new PermissionError(role, action, `this ${model.name}`, 'no linkable entities');
|
|
117
120
|
}
|
|
118
121
|
}
|
|
119
122
|
else if (action === 'CREATE') {
|
|
120
|
-
throw new PermissionError(
|
|
123
|
+
throw new PermissionError(role, action, `this ${model.name}`, 'no linkable entities');
|
|
121
124
|
}
|
|
122
125
|
};
|
|
123
126
|
const permissionLinkQuery = (ctx, subQuery, links, id) => {
|
|
124
127
|
const aliases = new AliasGenerator();
|
|
125
128
|
let alias = aliases.getShort();
|
|
126
129
|
const { type, me, where } = links[0];
|
|
127
|
-
// eslint-disable-next-line @typescript-eslint/no-floating-promises -- we do not need to await knex here
|
|
128
|
-
subQuery.from(`${type} as ${alias}`);
|
|
129
130
|
if (me) {
|
|
131
|
+
if (!ctx.user) {
|
|
132
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises -- we do not need to await knex here
|
|
133
|
+
subQuery.where(false);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
130
136
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises -- we do not need to await knex here
|
|
131
137
|
subQuery.where({ [`${alias}.id`]: ctx.user.id });
|
|
132
138
|
}
|
|
139
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises -- we do not need to await knex here
|
|
140
|
+
subQuery.from(`${type} as ${alias}`);
|
|
133
141
|
if (where) {
|
|
134
142
|
applyWhere(ctx.models.getModel(type, 'entity'), subQuery, alias, where, aliases);
|
|
135
143
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/permissions/check.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE3D,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAI/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,GAA8C,EAC9C,IAAY,EACZ,MAAwB,EACG,EAAE;IAC7B,MAAM,eAAe,GAAG,GAAG,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/permissions/check.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,7 +23,7 @@ export const applyFilters = (node, query, joins) => {
|
|
|
23
23
|
}
|
|
24
24
|
if (normalizedArguments.where.deleted &&
|
|
25
25
|
(!Array.isArray(normalizedArguments.where.deleted) || normalizedArguments.where.deleted.some((v) => v))) {
|
|
26
|
-
if (node.ctx.user
|
|
26
|
+
if (node.ctx.user?.role !== 'ADMIN') {
|
|
27
27
|
throw new ForbiddenError('You cannot access deleted entries.');
|
|
28
28
|
}
|
|
29
29
|
}
|