@tinacms/graphql 1.6.1 → 1.6.3
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/dist/ast-builder/index.d.ts +2 -2
- package/dist/build.d.ts +2 -4
- package/dist/index.d.ts +1 -4
- package/dist/index.js +173 -146
- package/dist/index.mjs +170 -141
- package/dist/resolver/auth-fields.d.ts +31 -0
- package/dist/resolver/error.d.ts +1 -2
- package/package.json +7 -12
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
|
|
3
3
|
*/
|
|
4
|
-
import { type FieldDefinitionNode, type ScalarTypeDefinitionNode, type InputValueDefinitionNode, type ObjectTypeDefinitionNode, type InterfaceTypeDefinitionNode, type NamedTypeNode, type UnionTypeDefinitionNode, type TypeDefinitionNode, type DirectiveNode, type EnumTypeDefinitionNode, type InputObjectTypeDefinitionNode, type DocumentNode, type FragmentDefinitionNode, type SelectionNode, type FieldNode, type InlineFragmentNode, type OperationDefinitionNode } from 'graphql';
|
|
4
|
+
import { type FieldDefinitionNode, type ScalarTypeDefinitionNode, type InputValueDefinitionNode, type ObjectTypeDefinitionNode, type InterfaceTypeDefinitionNode, type NamedTypeNode, type UnionTypeDefinitionNode, type TypeDefinitionNode, type DirectiveNode, type EnumTypeDefinitionNode, type InputObjectTypeDefinitionNode, type DocumentNode, type FragmentDefinitionNode, type SelectionNode, type FieldNode, type InlineFragmentNode, type OperationDefinitionNode, type DefinitionNode } from 'graphql';
|
|
5
5
|
export declare const SysFieldDefinition: {
|
|
6
6
|
kind: "Field";
|
|
7
7
|
name: {
|
|
@@ -153,7 +153,7 @@ export declare const astBuilder: {
|
|
|
153
153
|
}) => DocumentNode;
|
|
154
154
|
};
|
|
155
155
|
type scalarNames = 'string' | 'boolean' | 'datetime' | 'image' | 'text' | 'number';
|
|
156
|
-
export declare const extractInlineTypes: (item:
|
|
156
|
+
export declare const extractInlineTypes: (item: DefinitionNode | DefinitionNode[]) => DefinitionNode[];
|
|
157
157
|
export declare function walk(maybeNode: TypeDefinitionNode, visited?: WeakSet<WeakKey>): IterableIterator<TypeDefinitionNode>;
|
|
158
158
|
export declare const NAMER: {
|
|
159
159
|
dataFilterTypeNameOn: (namespace: string[]) => string;
|
package/dist/build.d.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
|
|
3
3
|
*/
|
|
4
|
+
import { type DocumentNode } from 'graphql';
|
|
4
5
|
import type { TinaSchema, Config } from '@tinacms/schema-tools';
|
|
5
6
|
export declare const buildDotTinaFiles: ({ config, flags, buildSDK, }: {
|
|
6
7
|
config: Config;
|
|
7
8
|
flags?: string[];
|
|
8
9
|
buildSDK?: boolean;
|
|
9
10
|
}) => Promise<{
|
|
10
|
-
graphQLSchema:
|
|
11
|
-
kind: "Document";
|
|
12
|
-
definitions: any;
|
|
13
|
-
};
|
|
11
|
+
graphQLSchema: DocumentNode;
|
|
14
12
|
tinaSchema: TinaSchema;
|
|
15
13
|
lookup: Record<string, import("./database").LookupMapType>;
|
|
16
14
|
fragDoc: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -16,10 +16,7 @@ export { createSchema } from './schema/createSchema';
|
|
|
16
16
|
export { buildDotTinaFiles };
|
|
17
17
|
export type DummyType = unknown;
|
|
18
18
|
export declare const buildSchema: (config: Config, flags?: string[]) => Promise<{
|
|
19
|
-
graphQLSchema:
|
|
20
|
-
kind: "Document";
|
|
21
|
-
definitions: any;
|
|
22
|
-
};
|
|
19
|
+
graphQLSchema: import("graphql").DocumentNode;
|
|
23
20
|
tinaSchema: import("@tinacms/schema-tools").TinaSchema;
|
|
24
21
|
lookup: Record<string, import("./database").LookupMapType>;
|
|
25
22
|
fragDoc: string;
|
package/dist/index.js
CHANGED
|
@@ -66,7 +66,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
66
66
|
|
|
67
67
|
// src/build.ts
|
|
68
68
|
var import_graphql2 = require("graphql");
|
|
69
|
-
var
|
|
69
|
+
var import_es_toolkit3 = require("es-toolkit");
|
|
70
70
|
|
|
71
71
|
// src/util.ts
|
|
72
72
|
var yup = __toESM(require("yup"));
|
|
@@ -122,7 +122,7 @@ var flattenDeep = (arr) => arr.flatMap(
|
|
|
122
122
|
);
|
|
123
123
|
|
|
124
124
|
// src/ast-builder/index.ts
|
|
125
|
-
var
|
|
125
|
+
var import_es_toolkit = require("es-toolkit");
|
|
126
126
|
var SysFieldDefinition = {
|
|
127
127
|
kind: "Field",
|
|
128
128
|
name: {
|
|
@@ -1037,12 +1037,13 @@ var astBuilder = {
|
|
|
1037
1037
|
};
|
|
1038
1038
|
},
|
|
1039
1039
|
toGraphQLAst: (ast) => {
|
|
1040
|
-
const definitions = (0,
|
|
1040
|
+
const definitions = (0, import_es_toolkit.uniqBy)(
|
|
1041
1041
|
[
|
|
1042
1042
|
...extractInlineTypes(ast.query),
|
|
1043
1043
|
...extractInlineTypes(ast.globalTemplates),
|
|
1044
1044
|
...ast.definitions
|
|
1045
1045
|
],
|
|
1046
|
+
// @ts-ignore - all nodes have a name property in practice
|
|
1046
1047
|
(field) => field.name.value
|
|
1047
1048
|
);
|
|
1048
1049
|
return {
|
|
@@ -1065,7 +1066,7 @@ var extractInlineTypes = (item) => {
|
|
|
1065
1066
|
const accumulator = [item];
|
|
1066
1067
|
for (const node of walk(item)) {
|
|
1067
1068
|
if (node.kind === "UnionTypeDefinition") {
|
|
1068
|
-
node.types = (0,
|
|
1069
|
+
node.types = (0, import_es_toolkit.uniqBy)(node.types, (type) => type.name.value);
|
|
1069
1070
|
}
|
|
1070
1071
|
if (node.kind === "NamedType") {
|
|
1071
1072
|
if (typeof node.name.value !== "string") {
|
|
@@ -2777,7 +2778,7 @@ var Builder = class {
|
|
|
2777
2778
|
this._buildDataField = async (field) => {
|
|
2778
2779
|
const listWarningMsg = `
|
|
2779
2780
|
WARNING: The user interface for ${field.type} does not support \`list: true\`
|
|
2780
|
-
Visit https://tina.io/docs/
|
|
2781
|
+
Visit https://tina.io/docs/r/content-fields/#list-fields/ for more information
|
|
2781
2782
|
|
|
2782
2783
|
`;
|
|
2783
2784
|
switch (field.type) {
|
|
@@ -2930,8 +2931,8 @@ var import_schema_tools3 = require("@tinacms/schema-tools");
|
|
|
2930
2931
|
|
|
2931
2932
|
// src/schema/validate.ts
|
|
2932
2933
|
var import_schema_tools = require("@tinacms/schema-tools");
|
|
2933
|
-
var import_lodash2 = __toESM(require("lodash.clonedeep"));
|
|
2934
2934
|
var yup2 = __toESM(require("yup"));
|
|
2935
|
+
var import_es_toolkit2 = require("es-toolkit");
|
|
2935
2936
|
var import_schema_tools2 = require("@tinacms/schema-tools");
|
|
2936
2937
|
var FIELD_TYPES = [
|
|
2937
2938
|
"string",
|
|
@@ -2946,7 +2947,7 @@ var FIELD_TYPES = [
|
|
|
2946
2947
|
];
|
|
2947
2948
|
var validateSchema = async (schema) => {
|
|
2948
2949
|
const schema2 = (0, import_schema_tools.addNamespaceToSchema)(
|
|
2949
|
-
(0,
|
|
2950
|
+
(0, import_es_toolkit2.cloneDeep)(schema)
|
|
2950
2951
|
);
|
|
2951
2952
|
const collections = await sequential(
|
|
2952
2953
|
schema2.collections,
|
|
@@ -3083,7 +3084,7 @@ var validateField = async (field) => {
|
|
|
3083
3084
|
// package.json
|
|
3084
3085
|
var package_default = {
|
|
3085
3086
|
name: "@tinacms/graphql",
|
|
3086
|
-
version: "1.6.
|
|
3087
|
+
version: "1.6.3",
|
|
3087
3088
|
main: "dist/index.js",
|
|
3088
3089
|
module: "dist/index.mjs",
|
|
3089
3090
|
typings: "dist/index.d.ts",
|
|
@@ -3118,6 +3119,7 @@ var package_default = {
|
|
|
3118
3119
|
"@tinacms/schema-tools": "workspace:*",
|
|
3119
3120
|
"abstract-level": "catalog:",
|
|
3120
3121
|
"date-fns": "^2.30.0",
|
|
3122
|
+
"es-toolkit": "^1.42.0",
|
|
3121
3123
|
"fast-glob": "catalog:",
|
|
3122
3124
|
"fs-extra": "catalog:",
|
|
3123
3125
|
"glob-parent": "catalog:",
|
|
@@ -3127,15 +3129,12 @@ var package_default = {
|
|
|
3127
3129
|
"js-sha1": "catalog:",
|
|
3128
3130
|
"js-yaml": "^3.14.1",
|
|
3129
3131
|
"jsonpath-plus": "catalog:",
|
|
3130
|
-
"lodash.clonedeep": "catalog:",
|
|
3131
|
-
"lodash.set": "catalog:",
|
|
3132
|
-
"lodash.uniqby": "catalog:",
|
|
3133
3132
|
"many-level": "catalog:",
|
|
3134
3133
|
micromatch: "catalog:",
|
|
3135
3134
|
"normalize-path": "catalog:",
|
|
3136
3135
|
"readable-stream": "catalog:",
|
|
3137
3136
|
scmp: "catalog:",
|
|
3138
|
-
yup: "^
|
|
3137
|
+
yup: "^1.6.1"
|
|
3139
3138
|
},
|
|
3140
3139
|
publishConfig: {
|
|
3141
3140
|
registry: "https://registry.npmjs.org"
|
|
@@ -3152,21 +3151,18 @@ var package_default = {
|
|
|
3152
3151
|
"@types/express": "catalog:",
|
|
3153
3152
|
"@types/fs-extra": "^9.0.13",
|
|
3154
3153
|
"@types/js-yaml": "^3.12.10",
|
|
3155
|
-
"@types/lodash.camelcase": "catalog:",
|
|
3156
|
-
"@types/lodash.upperfirst": "catalog:",
|
|
3157
3154
|
"@types/lru-cache": "catalog:",
|
|
3158
3155
|
"@types/mdast": "catalog:",
|
|
3159
3156
|
"@types/micromatch": "catalog:",
|
|
3160
3157
|
"@types/node": "^22.13.1",
|
|
3161
3158
|
"@types/normalize-path": "catalog:",
|
|
3162
3159
|
"@types/ws": "catalog:",
|
|
3163
|
-
"@types/yup": "^0.29.14",
|
|
3164
3160
|
"jest-file-snapshot": "^0.5.0",
|
|
3165
3161
|
"memory-level": "catalog:",
|
|
3166
3162
|
typescript: "^5.7.3",
|
|
3167
3163
|
vite: "^4.5.9",
|
|
3168
3164
|
vitest: "^0.32.4",
|
|
3169
|
-
zod: "
|
|
3165
|
+
zod: "catalog:"
|
|
3170
3166
|
}
|
|
3171
3167
|
};
|
|
3172
3168
|
|
|
@@ -3236,9 +3232,9 @@ var _buildFragments = async (builder, tinaSchema) => {
|
|
|
3236
3232
|
});
|
|
3237
3233
|
const fragDoc = {
|
|
3238
3234
|
kind: "Document",
|
|
3239
|
-
definitions: (0,
|
|
3240
|
-
// @ts-ignore
|
|
3235
|
+
definitions: (0, import_es_toolkit3.uniqBy)(
|
|
3241
3236
|
extractInlineTypes(fragmentDefinitionsFields),
|
|
3237
|
+
// @ts-ignore - all nodes returned by extractInlineTypes have a name property
|
|
3242
3238
|
(node) => node.name.value
|
|
3243
3239
|
)
|
|
3244
3240
|
};
|
|
@@ -3269,9 +3265,9 @@ var _buildQueries = async (builder, tinaSchema) => {
|
|
|
3269
3265
|
});
|
|
3270
3266
|
const queryDoc = {
|
|
3271
3267
|
kind: "Document",
|
|
3272
|
-
definitions: (0,
|
|
3273
|
-
// @ts-ignore
|
|
3268
|
+
definitions: (0, import_es_toolkit3.uniqBy)(
|
|
3274
3269
|
extractInlineTypes(operationsDefinitions),
|
|
3270
|
+
// @ts-ignore - all nodes returned by extractInlineTypes have a name property
|
|
3275
3271
|
(node) => node.name.value
|
|
3276
3272
|
)
|
|
3277
3273
|
};
|
|
@@ -3358,14 +3354,15 @@ var _buildSchema = async (builder, tinaSchema) => {
|
|
|
3358
3354
|
fields: mutationTypeDefinitionFields
|
|
3359
3355
|
})
|
|
3360
3356
|
);
|
|
3361
|
-
|
|
3357
|
+
const schema = {
|
|
3362
3358
|
kind: "Document",
|
|
3363
|
-
definitions: (0,
|
|
3364
|
-
// @ts-ignore
|
|
3359
|
+
definitions: (0, import_es_toolkit3.uniqBy)(
|
|
3365
3360
|
extractInlineTypes(definitions),
|
|
3361
|
+
// @ts-ignore - all nodes returned by extractInlineTypes have a name property
|
|
3366
3362
|
(node) => node.name.value
|
|
3367
3363
|
)
|
|
3368
3364
|
};
|
|
3365
|
+
return schema;
|
|
3369
3366
|
};
|
|
3370
3367
|
|
|
3371
3368
|
// src/resolve.ts
|
|
@@ -4447,7 +4444,6 @@ var TinaFetchError = class extends Error {
|
|
|
4447
4444
|
super(message);
|
|
4448
4445
|
this.name = "TinaFetchError";
|
|
4449
4446
|
this.collection = args.collection;
|
|
4450
|
-
this.stack = args.stack;
|
|
4451
4447
|
this.file = args.file;
|
|
4452
4448
|
this.originalError = args.originalError;
|
|
4453
4449
|
}
|
|
@@ -4829,8 +4825,7 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
|
|
|
4829
4825
|
originalError: e,
|
|
4830
4826
|
collection: collection.name,
|
|
4831
4827
|
includeAuditMessage: !isAudit,
|
|
4832
|
-
file: relativePath
|
|
4833
|
-
stack: e.stack
|
|
4828
|
+
file: relativePath
|
|
4834
4829
|
});
|
|
4835
4830
|
}
|
|
4836
4831
|
const titleField = template.fields.find((x) => {
|
|
@@ -5741,8 +5736,129 @@ var resolveDateInput = (value) => {
|
|
|
5741
5736
|
return date;
|
|
5742
5737
|
};
|
|
5743
5738
|
|
|
5744
|
-
// src/
|
|
5745
|
-
var
|
|
5739
|
+
// src/resolver/auth-fields.ts
|
|
5740
|
+
var import_compat = require("es-toolkit/compat");
|
|
5741
|
+
async function getUserDocumentContext(tinaSchema, resolver) {
|
|
5742
|
+
const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
|
|
5743
|
+
if (!collection) {
|
|
5744
|
+
throw new Error("Auth collection not found");
|
|
5745
|
+
}
|
|
5746
|
+
const userFields = mapUserFields(collection, ["_rawData"]);
|
|
5747
|
+
if (!userFields.length) {
|
|
5748
|
+
throw new Error(`No user field found in collection ${collection.name}`);
|
|
5749
|
+
}
|
|
5750
|
+
if (userFields.length > 1) {
|
|
5751
|
+
throw new Error(
|
|
5752
|
+
`Multiple user fields found in collection ${collection.name}`
|
|
5753
|
+
);
|
|
5754
|
+
}
|
|
5755
|
+
const userField = userFields[0];
|
|
5756
|
+
const realPath = `${collection.path}/index.json`;
|
|
5757
|
+
const userDoc = await resolver.getDocument(realPath);
|
|
5758
|
+
const users = get(userDoc, userField.path);
|
|
5759
|
+
if (!users) {
|
|
5760
|
+
throw new Error("No users found");
|
|
5761
|
+
}
|
|
5762
|
+
return { collection, userField, users, userDoc, realPath };
|
|
5763
|
+
}
|
|
5764
|
+
function findUserInCollection(users, userField, userSub) {
|
|
5765
|
+
const { idFieldName } = userField;
|
|
5766
|
+
if (!idFieldName) {
|
|
5767
|
+
throw new Error("No uid field found on user field");
|
|
5768
|
+
}
|
|
5769
|
+
return users.find((u) => u[idFieldName] === userSub) || null;
|
|
5770
|
+
}
|
|
5771
|
+
async function handleAuthenticate({
|
|
5772
|
+
tinaSchema,
|
|
5773
|
+
resolver,
|
|
5774
|
+
sub,
|
|
5775
|
+
password,
|
|
5776
|
+
ctxUser
|
|
5777
|
+
}) {
|
|
5778
|
+
const userSub = sub || ctxUser?.sub;
|
|
5779
|
+
const { userField, users } = await getUserDocumentContext(
|
|
5780
|
+
tinaSchema,
|
|
5781
|
+
resolver
|
|
5782
|
+
);
|
|
5783
|
+
const user = findUserInCollection(users, userField, userSub);
|
|
5784
|
+
if (!user) {
|
|
5785
|
+
return null;
|
|
5786
|
+
}
|
|
5787
|
+
const { passwordFieldName } = userField;
|
|
5788
|
+
const saltedHash = get(user, [passwordFieldName || "", "value"]);
|
|
5789
|
+
if (!saltedHash) {
|
|
5790
|
+
throw new Error("No password field found on user field");
|
|
5791
|
+
}
|
|
5792
|
+
const matches = await checkPasswordHash({
|
|
5793
|
+
saltedHash,
|
|
5794
|
+
password
|
|
5795
|
+
});
|
|
5796
|
+
return matches ? user : null;
|
|
5797
|
+
}
|
|
5798
|
+
async function handleAuthorize({
|
|
5799
|
+
tinaSchema,
|
|
5800
|
+
resolver,
|
|
5801
|
+
sub,
|
|
5802
|
+
ctxUser
|
|
5803
|
+
}) {
|
|
5804
|
+
const userSub = sub || ctxUser?.sub;
|
|
5805
|
+
const { userField, users } = await getUserDocumentContext(
|
|
5806
|
+
tinaSchema,
|
|
5807
|
+
resolver
|
|
5808
|
+
);
|
|
5809
|
+
const user = findUserInCollection(users, userField, userSub);
|
|
5810
|
+
return user ? user : null;
|
|
5811
|
+
}
|
|
5812
|
+
async function handleUpdatePassword({
|
|
5813
|
+
tinaSchema,
|
|
5814
|
+
resolver,
|
|
5815
|
+
password,
|
|
5816
|
+
ctxUser
|
|
5817
|
+
}) {
|
|
5818
|
+
if (!ctxUser?.sub) {
|
|
5819
|
+
throw new Error("Not authorized");
|
|
5820
|
+
}
|
|
5821
|
+
if (!password) {
|
|
5822
|
+
throw new Error("No password provided");
|
|
5823
|
+
}
|
|
5824
|
+
const { collection, userField, users, realPath } = await getUserDocumentContext(tinaSchema, resolver);
|
|
5825
|
+
const { idFieldName, passwordFieldName } = userField;
|
|
5826
|
+
const user = users.find((u) => u[idFieldName] === ctxUser.sub);
|
|
5827
|
+
if (!user) {
|
|
5828
|
+
throw new Error("Not authorized");
|
|
5829
|
+
}
|
|
5830
|
+
user[passwordFieldName] = {
|
|
5831
|
+
value: password,
|
|
5832
|
+
passwordChangeRequired: false
|
|
5833
|
+
};
|
|
5834
|
+
const params = {};
|
|
5835
|
+
(0, import_compat.set)(
|
|
5836
|
+
params,
|
|
5837
|
+
userField.path.slice(1),
|
|
5838
|
+
// remove _rawData from users path
|
|
5839
|
+
users.map((u) => {
|
|
5840
|
+
if (user[idFieldName] === u[idFieldName]) {
|
|
5841
|
+
return user;
|
|
5842
|
+
}
|
|
5843
|
+
return {
|
|
5844
|
+
// don't overwrite other users' passwords
|
|
5845
|
+
...u,
|
|
5846
|
+
[passwordFieldName]: {
|
|
5847
|
+
...u[passwordFieldName],
|
|
5848
|
+
value: ""
|
|
5849
|
+
}
|
|
5850
|
+
};
|
|
5851
|
+
})
|
|
5852
|
+
);
|
|
5853
|
+
await resolver.updateResolveDocument({
|
|
5854
|
+
collection,
|
|
5855
|
+
args: { params },
|
|
5856
|
+
realPath,
|
|
5857
|
+
isCollectionSpecific: true,
|
|
5858
|
+
isAddPendingDocument: false
|
|
5859
|
+
});
|
|
5860
|
+
return true;
|
|
5861
|
+
}
|
|
5746
5862
|
|
|
5747
5863
|
// src/error.ts
|
|
5748
5864
|
var import_graphql4 = require("graphql");
|
|
@@ -5852,119 +5968,33 @@ var resolve = async ({
|
|
|
5852
5968
|
);
|
|
5853
5969
|
}
|
|
5854
5970
|
}
|
|
5855
|
-
if (info.fieldName === "authenticate"
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
const realPath = `${collection.path}/index.json`;
|
|
5874
|
-
const userDoc = await resolver.getDocument(realPath);
|
|
5875
|
-
const users = get(userDoc, userField.path);
|
|
5876
|
-
if (!users) {
|
|
5877
|
-
throw new Error("No users found");
|
|
5878
|
-
}
|
|
5879
|
-
const { idFieldName, passwordFieldName } = userField;
|
|
5880
|
-
if (!idFieldName) {
|
|
5881
|
-
throw new Error("No uid field found on user field");
|
|
5882
|
-
}
|
|
5883
|
-
const user = users.find((u) => u[idFieldName] === sub);
|
|
5884
|
-
if (!user) {
|
|
5885
|
-
return null;
|
|
5886
|
-
}
|
|
5887
|
-
if (info.fieldName === "authenticate") {
|
|
5888
|
-
const saltedHash = get(user, [passwordFieldName || "", "value"]);
|
|
5889
|
-
if (!saltedHash) {
|
|
5890
|
-
throw new Error("No password field found on user field");
|
|
5891
|
-
}
|
|
5892
|
-
const matches = await checkPasswordHash({
|
|
5893
|
-
saltedHash,
|
|
5894
|
-
password: args.password
|
|
5895
|
-
});
|
|
5896
|
-
if (matches) {
|
|
5897
|
-
return user;
|
|
5898
|
-
}
|
|
5899
|
-
return null;
|
|
5900
|
-
}
|
|
5901
|
-
return user;
|
|
5971
|
+
if (info.fieldName === "authenticate") {
|
|
5972
|
+
return handleAuthenticate({
|
|
5973
|
+
tinaSchema,
|
|
5974
|
+
resolver,
|
|
5975
|
+
sub: args.sub,
|
|
5976
|
+
password: args.password,
|
|
5977
|
+
info,
|
|
5978
|
+
ctxUser
|
|
5979
|
+
});
|
|
5980
|
+
}
|
|
5981
|
+
if (info.fieldName === "authorize") {
|
|
5982
|
+
return handleAuthorize({
|
|
5983
|
+
tinaSchema,
|
|
5984
|
+
resolver,
|
|
5985
|
+
sub: args.sub,
|
|
5986
|
+
info,
|
|
5987
|
+
ctxUser
|
|
5988
|
+
});
|
|
5902
5989
|
}
|
|
5903
5990
|
if (info.fieldName === "updatePassword") {
|
|
5904
|
-
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
|
|
5911
|
-
if (!collection) {
|
|
5912
|
-
throw new Error("Auth collection not found");
|
|
5913
|
-
}
|
|
5914
|
-
const userFields = mapUserFields(collection, ["_rawData"]);
|
|
5915
|
-
if (!userFields.length) {
|
|
5916
|
-
throw new Error(
|
|
5917
|
-
`No user field found in collection ${collection.name}`
|
|
5918
|
-
);
|
|
5919
|
-
}
|
|
5920
|
-
if (userFields.length > 1) {
|
|
5921
|
-
throw new Error(
|
|
5922
|
-
`Multiple user fields found in collection ${collection.name}`
|
|
5923
|
-
);
|
|
5924
|
-
}
|
|
5925
|
-
const userField = userFields[0];
|
|
5926
|
-
const realPath = `${collection.path}/index.json`;
|
|
5927
|
-
const userDoc = await resolver.getDocument(realPath);
|
|
5928
|
-
const users = get(userDoc, userField.path);
|
|
5929
|
-
if (!users) {
|
|
5930
|
-
throw new Error("No users found");
|
|
5931
|
-
}
|
|
5932
|
-
const { idFieldName, passwordFieldName } = userField;
|
|
5933
|
-
const user = users.find((u) => u[idFieldName] === ctxUser.sub);
|
|
5934
|
-
if (!user) {
|
|
5935
|
-
throw new Error("Not authorized");
|
|
5936
|
-
}
|
|
5937
|
-
user[passwordFieldName] = {
|
|
5938
|
-
value: args.password,
|
|
5939
|
-
passwordChangeRequired: false
|
|
5940
|
-
};
|
|
5941
|
-
const params = {};
|
|
5942
|
-
(0, import_lodash4.default)(
|
|
5943
|
-
params,
|
|
5944
|
-
userField.path.slice(1),
|
|
5945
|
-
// remove _rawData from users path
|
|
5946
|
-
users.map((u) => {
|
|
5947
|
-
if (user[idFieldName] === u[idFieldName]) {
|
|
5948
|
-
return user;
|
|
5949
|
-
}
|
|
5950
|
-
return {
|
|
5951
|
-
// don't overwrite other users' passwords
|
|
5952
|
-
...u,
|
|
5953
|
-
[passwordFieldName]: {
|
|
5954
|
-
...u[passwordFieldName],
|
|
5955
|
-
value: ""
|
|
5956
|
-
}
|
|
5957
|
-
};
|
|
5958
|
-
})
|
|
5959
|
-
);
|
|
5960
|
-
await resolver.updateResolveDocument({
|
|
5961
|
-
collection,
|
|
5962
|
-
args: { params },
|
|
5963
|
-
realPath,
|
|
5964
|
-
isCollectionSpecific: true,
|
|
5965
|
-
isAddPendingDocument: false
|
|
5991
|
+
return handleUpdatePassword({
|
|
5992
|
+
tinaSchema,
|
|
5993
|
+
resolver,
|
|
5994
|
+
password: args.password,
|
|
5995
|
+
info,
|
|
5996
|
+
ctxUser
|
|
5966
5997
|
});
|
|
5967
|
-
return true;
|
|
5968
5998
|
}
|
|
5969
5999
|
if (!lookup) {
|
|
5970
6000
|
return value;
|
|
@@ -6177,7 +6207,7 @@ var import_node_path = __toESM(require("node:path"));
|
|
|
6177
6207
|
var import_graphql6 = require("graphql");
|
|
6178
6208
|
var import_micromatch2 = __toESM(require("micromatch"));
|
|
6179
6209
|
var import_js_sha12 = __toESM(require("js-sha1"));
|
|
6180
|
-
var
|
|
6210
|
+
var import_compat2 = require("es-toolkit/compat");
|
|
6181
6211
|
var createLocalDatabase = (config) => {
|
|
6182
6212
|
const level = new TinaLevelClient(config?.port);
|
|
6183
6213
|
level.openConnection();
|
|
@@ -6552,8 +6582,7 @@ var Database = class {
|
|
|
6552
6582
|
throw new TinaFetchError(`Error in PUT for ${filepath}`, {
|
|
6553
6583
|
originalError: error,
|
|
6554
6584
|
file: filepath,
|
|
6555
|
-
collection: collectionName
|
|
6556
|
-
stack: error.stack
|
|
6585
|
+
collection: collectionName
|
|
6557
6586
|
});
|
|
6558
6587
|
}
|
|
6559
6588
|
};
|
|
@@ -6913,8 +6942,7 @@ var Database = class {
|
|
|
6913
6942
|
throw new TinaQueryError({
|
|
6914
6943
|
originalError: error,
|
|
6915
6944
|
file: path7,
|
|
6916
|
-
collection: collection.name
|
|
6917
|
-
stack: error.stack
|
|
6945
|
+
collection: collection.name
|
|
6918
6946
|
});
|
|
6919
6947
|
}
|
|
6920
6948
|
throw error;
|
|
@@ -7290,7 +7318,7 @@ var hashPasswordVisitor = async (node, path7) => {
|
|
|
7290
7318
|
const passwordValuePath = [...path7, "value"];
|
|
7291
7319
|
const plaintextPassword = get(node, passwordValuePath);
|
|
7292
7320
|
if (plaintextPassword) {
|
|
7293
|
-
(0,
|
|
7321
|
+
(0, import_compat2.set)(
|
|
7294
7322
|
node,
|
|
7295
7323
|
passwordValuePath,
|
|
7296
7324
|
await generatePasswordHash({ password: plaintextPassword })
|
|
@@ -7444,8 +7472,7 @@ var _indexContent = async ({
|
|
|
7444
7472
|
throw new TinaFetchError(`Unable to seed ${filepath}`, {
|
|
7445
7473
|
originalError: error,
|
|
7446
7474
|
file: filepath,
|
|
7447
|
-
collection: collection?.name
|
|
7448
|
-
stack: error.stack
|
|
7475
|
+
collection: collection?.name
|
|
7449
7476
|
});
|
|
7450
7477
|
}
|
|
7451
7478
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// src/build.ts
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
print
|
|
4
|
+
} from "graphql";
|
|
5
|
+
import { uniqBy as uniqBy2 } from "es-toolkit";
|
|
4
6
|
|
|
5
7
|
// src/util.ts
|
|
6
8
|
import * as yup from "yup";
|
|
@@ -56,7 +58,7 @@ var flattenDeep = (arr) => arr.flatMap(
|
|
|
56
58
|
);
|
|
57
59
|
|
|
58
60
|
// src/ast-builder/index.ts
|
|
59
|
-
import uniqBy from "
|
|
61
|
+
import { uniqBy } from "es-toolkit";
|
|
60
62
|
var SysFieldDefinition = {
|
|
61
63
|
kind: "Field",
|
|
62
64
|
name: {
|
|
@@ -977,6 +979,7 @@ var astBuilder = {
|
|
|
977
979
|
...extractInlineTypes(ast.globalTemplates),
|
|
978
980
|
...ast.definitions
|
|
979
981
|
],
|
|
982
|
+
// @ts-ignore - all nodes have a name property in practice
|
|
980
983
|
(field) => field.name.value
|
|
981
984
|
);
|
|
982
985
|
return {
|
|
@@ -2711,7 +2714,7 @@ var Builder = class {
|
|
|
2711
2714
|
this._buildDataField = async (field) => {
|
|
2712
2715
|
const listWarningMsg = `
|
|
2713
2716
|
WARNING: The user interface for ${field.type} does not support \`list: true\`
|
|
2714
|
-
Visit https://tina.io/docs/
|
|
2717
|
+
Visit https://tina.io/docs/r/content-fields/#list-fields/ for more information
|
|
2715
2718
|
|
|
2716
2719
|
`;
|
|
2717
2720
|
switch (field.type) {
|
|
@@ -2864,8 +2867,8 @@ import { TinaSchema } from "@tinacms/schema-tools";
|
|
|
2864
2867
|
|
|
2865
2868
|
// src/schema/validate.ts
|
|
2866
2869
|
import { addNamespaceToSchema } from "@tinacms/schema-tools";
|
|
2867
|
-
import deepClone from "lodash.clonedeep";
|
|
2868
2870
|
import * as yup2 from "yup";
|
|
2871
|
+
import { cloneDeep } from "es-toolkit";
|
|
2869
2872
|
import {
|
|
2870
2873
|
validateTinaCloudSchemaConfig
|
|
2871
2874
|
} from "@tinacms/schema-tools";
|
|
@@ -2882,7 +2885,7 @@ var FIELD_TYPES = [
|
|
|
2882
2885
|
];
|
|
2883
2886
|
var validateSchema = async (schema) => {
|
|
2884
2887
|
const schema2 = addNamespaceToSchema(
|
|
2885
|
-
|
|
2888
|
+
cloneDeep(schema)
|
|
2886
2889
|
);
|
|
2887
2890
|
const collections = await sequential(
|
|
2888
2891
|
schema2.collections,
|
|
@@ -3019,7 +3022,7 @@ var validateField = async (field) => {
|
|
|
3019
3022
|
// package.json
|
|
3020
3023
|
var package_default = {
|
|
3021
3024
|
name: "@tinacms/graphql",
|
|
3022
|
-
version: "1.6.
|
|
3025
|
+
version: "1.6.3",
|
|
3023
3026
|
main: "dist/index.js",
|
|
3024
3027
|
module: "dist/index.mjs",
|
|
3025
3028
|
typings: "dist/index.d.ts",
|
|
@@ -3054,6 +3057,7 @@ var package_default = {
|
|
|
3054
3057
|
"@tinacms/schema-tools": "workspace:*",
|
|
3055
3058
|
"abstract-level": "catalog:",
|
|
3056
3059
|
"date-fns": "^2.30.0",
|
|
3060
|
+
"es-toolkit": "^1.42.0",
|
|
3057
3061
|
"fast-glob": "catalog:",
|
|
3058
3062
|
"fs-extra": "catalog:",
|
|
3059
3063
|
"glob-parent": "catalog:",
|
|
@@ -3063,15 +3067,12 @@ var package_default = {
|
|
|
3063
3067
|
"js-sha1": "catalog:",
|
|
3064
3068
|
"js-yaml": "^3.14.1",
|
|
3065
3069
|
"jsonpath-plus": "catalog:",
|
|
3066
|
-
"lodash.clonedeep": "catalog:",
|
|
3067
|
-
"lodash.set": "catalog:",
|
|
3068
|
-
"lodash.uniqby": "catalog:",
|
|
3069
3070
|
"many-level": "catalog:",
|
|
3070
3071
|
micromatch: "catalog:",
|
|
3071
3072
|
"normalize-path": "catalog:",
|
|
3072
3073
|
"readable-stream": "catalog:",
|
|
3073
3074
|
scmp: "catalog:",
|
|
3074
|
-
yup: "^
|
|
3075
|
+
yup: "^1.6.1"
|
|
3075
3076
|
},
|
|
3076
3077
|
publishConfig: {
|
|
3077
3078
|
registry: "https://registry.npmjs.org"
|
|
@@ -3088,21 +3089,18 @@ var package_default = {
|
|
|
3088
3089
|
"@types/express": "catalog:",
|
|
3089
3090
|
"@types/fs-extra": "^9.0.13",
|
|
3090
3091
|
"@types/js-yaml": "^3.12.10",
|
|
3091
|
-
"@types/lodash.camelcase": "catalog:",
|
|
3092
|
-
"@types/lodash.upperfirst": "catalog:",
|
|
3093
3092
|
"@types/lru-cache": "catalog:",
|
|
3094
3093
|
"@types/mdast": "catalog:",
|
|
3095
3094
|
"@types/micromatch": "catalog:",
|
|
3096
3095
|
"@types/node": "^22.13.1",
|
|
3097
3096
|
"@types/normalize-path": "catalog:",
|
|
3098
3097
|
"@types/ws": "catalog:",
|
|
3099
|
-
"@types/yup": "^0.29.14",
|
|
3100
3098
|
"jest-file-snapshot": "^0.5.0",
|
|
3101
3099
|
"memory-level": "catalog:",
|
|
3102
3100
|
typescript: "^5.7.3",
|
|
3103
3101
|
vite: "^4.5.9",
|
|
3104
3102
|
vitest: "^0.32.4",
|
|
3105
|
-
zod: "
|
|
3103
|
+
zod: "catalog:"
|
|
3106
3104
|
}
|
|
3107
3105
|
};
|
|
3108
3106
|
|
|
@@ -3173,8 +3171,8 @@ var _buildFragments = async (builder, tinaSchema) => {
|
|
|
3173
3171
|
const fragDoc = {
|
|
3174
3172
|
kind: "Document",
|
|
3175
3173
|
definitions: uniqBy2(
|
|
3176
|
-
// @ts-ignore
|
|
3177
3174
|
extractInlineTypes(fragmentDefinitionsFields),
|
|
3175
|
+
// @ts-ignore - all nodes returned by extractInlineTypes have a name property
|
|
3178
3176
|
(node) => node.name.value
|
|
3179
3177
|
)
|
|
3180
3178
|
};
|
|
@@ -3206,8 +3204,8 @@ var _buildQueries = async (builder, tinaSchema) => {
|
|
|
3206
3204
|
const queryDoc = {
|
|
3207
3205
|
kind: "Document",
|
|
3208
3206
|
definitions: uniqBy2(
|
|
3209
|
-
// @ts-ignore
|
|
3210
3207
|
extractInlineTypes(operationsDefinitions),
|
|
3208
|
+
// @ts-ignore - all nodes returned by extractInlineTypes have a name property
|
|
3211
3209
|
(node) => node.name.value
|
|
3212
3210
|
)
|
|
3213
3211
|
};
|
|
@@ -3294,14 +3292,15 @@ var _buildSchema = async (builder, tinaSchema) => {
|
|
|
3294
3292
|
fields: mutationTypeDefinitionFields
|
|
3295
3293
|
})
|
|
3296
3294
|
);
|
|
3297
|
-
|
|
3295
|
+
const schema = {
|
|
3298
3296
|
kind: "Document",
|
|
3299
3297
|
definitions: uniqBy2(
|
|
3300
|
-
// @ts-ignore
|
|
3301
3298
|
extractInlineTypes(definitions),
|
|
3299
|
+
// @ts-ignore - all nodes returned by extractInlineTypes have a name property
|
|
3302
3300
|
(node) => node.name.value
|
|
3303
3301
|
)
|
|
3304
3302
|
};
|
|
3303
|
+
return schema;
|
|
3305
3304
|
};
|
|
3306
3305
|
|
|
3307
3306
|
// src/resolve.ts
|
|
@@ -4385,7 +4384,6 @@ var TinaFetchError = class extends Error {
|
|
|
4385
4384
|
super(message);
|
|
4386
4385
|
this.name = "TinaFetchError";
|
|
4387
4386
|
this.collection = args.collection;
|
|
4388
|
-
this.stack = args.stack;
|
|
4389
4387
|
this.file = args.file;
|
|
4390
4388
|
this.originalError = args.originalError;
|
|
4391
4389
|
}
|
|
@@ -4767,8 +4765,7 @@ var transformDocumentIntoPayload = async (fullPath, rawData, tinaSchema, config,
|
|
|
4767
4765
|
originalError: e,
|
|
4768
4766
|
collection: collection.name,
|
|
4769
4767
|
includeAuditMessage: !isAudit,
|
|
4770
|
-
file: relativePath
|
|
4771
|
-
stack: e.stack
|
|
4768
|
+
file: relativePath
|
|
4772
4769
|
});
|
|
4773
4770
|
}
|
|
4774
4771
|
const titleField = template.fields.find((x) => {
|
|
@@ -5679,8 +5676,129 @@ var resolveDateInput = (value) => {
|
|
|
5679
5676
|
return date;
|
|
5680
5677
|
};
|
|
5681
5678
|
|
|
5682
|
-
// src/
|
|
5683
|
-
import set from "
|
|
5679
|
+
// src/resolver/auth-fields.ts
|
|
5680
|
+
import { set } from "es-toolkit/compat";
|
|
5681
|
+
async function getUserDocumentContext(tinaSchema, resolver) {
|
|
5682
|
+
const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
|
|
5683
|
+
if (!collection) {
|
|
5684
|
+
throw new Error("Auth collection not found");
|
|
5685
|
+
}
|
|
5686
|
+
const userFields = mapUserFields(collection, ["_rawData"]);
|
|
5687
|
+
if (!userFields.length) {
|
|
5688
|
+
throw new Error(`No user field found in collection ${collection.name}`);
|
|
5689
|
+
}
|
|
5690
|
+
if (userFields.length > 1) {
|
|
5691
|
+
throw new Error(
|
|
5692
|
+
`Multiple user fields found in collection ${collection.name}`
|
|
5693
|
+
);
|
|
5694
|
+
}
|
|
5695
|
+
const userField = userFields[0];
|
|
5696
|
+
const realPath = `${collection.path}/index.json`;
|
|
5697
|
+
const userDoc = await resolver.getDocument(realPath);
|
|
5698
|
+
const users = get(userDoc, userField.path);
|
|
5699
|
+
if (!users) {
|
|
5700
|
+
throw new Error("No users found");
|
|
5701
|
+
}
|
|
5702
|
+
return { collection, userField, users, userDoc, realPath };
|
|
5703
|
+
}
|
|
5704
|
+
function findUserInCollection(users, userField, userSub) {
|
|
5705
|
+
const { idFieldName } = userField;
|
|
5706
|
+
if (!idFieldName) {
|
|
5707
|
+
throw new Error("No uid field found on user field");
|
|
5708
|
+
}
|
|
5709
|
+
return users.find((u) => u[idFieldName] === userSub) || null;
|
|
5710
|
+
}
|
|
5711
|
+
async function handleAuthenticate({
|
|
5712
|
+
tinaSchema,
|
|
5713
|
+
resolver,
|
|
5714
|
+
sub,
|
|
5715
|
+
password,
|
|
5716
|
+
ctxUser
|
|
5717
|
+
}) {
|
|
5718
|
+
const userSub = sub || ctxUser?.sub;
|
|
5719
|
+
const { userField, users } = await getUserDocumentContext(
|
|
5720
|
+
tinaSchema,
|
|
5721
|
+
resolver
|
|
5722
|
+
);
|
|
5723
|
+
const user = findUserInCollection(users, userField, userSub);
|
|
5724
|
+
if (!user) {
|
|
5725
|
+
return null;
|
|
5726
|
+
}
|
|
5727
|
+
const { passwordFieldName } = userField;
|
|
5728
|
+
const saltedHash = get(user, [passwordFieldName || "", "value"]);
|
|
5729
|
+
if (!saltedHash) {
|
|
5730
|
+
throw new Error("No password field found on user field");
|
|
5731
|
+
}
|
|
5732
|
+
const matches = await checkPasswordHash({
|
|
5733
|
+
saltedHash,
|
|
5734
|
+
password
|
|
5735
|
+
});
|
|
5736
|
+
return matches ? user : null;
|
|
5737
|
+
}
|
|
5738
|
+
async function handleAuthorize({
|
|
5739
|
+
tinaSchema,
|
|
5740
|
+
resolver,
|
|
5741
|
+
sub,
|
|
5742
|
+
ctxUser
|
|
5743
|
+
}) {
|
|
5744
|
+
const userSub = sub || ctxUser?.sub;
|
|
5745
|
+
const { userField, users } = await getUserDocumentContext(
|
|
5746
|
+
tinaSchema,
|
|
5747
|
+
resolver
|
|
5748
|
+
);
|
|
5749
|
+
const user = findUserInCollection(users, userField, userSub);
|
|
5750
|
+
return user ? user : null;
|
|
5751
|
+
}
|
|
5752
|
+
async function handleUpdatePassword({
|
|
5753
|
+
tinaSchema,
|
|
5754
|
+
resolver,
|
|
5755
|
+
password,
|
|
5756
|
+
ctxUser
|
|
5757
|
+
}) {
|
|
5758
|
+
if (!ctxUser?.sub) {
|
|
5759
|
+
throw new Error("Not authorized");
|
|
5760
|
+
}
|
|
5761
|
+
if (!password) {
|
|
5762
|
+
throw new Error("No password provided");
|
|
5763
|
+
}
|
|
5764
|
+
const { collection, userField, users, realPath } = await getUserDocumentContext(tinaSchema, resolver);
|
|
5765
|
+
const { idFieldName, passwordFieldName } = userField;
|
|
5766
|
+
const user = users.find((u) => u[idFieldName] === ctxUser.sub);
|
|
5767
|
+
if (!user) {
|
|
5768
|
+
throw new Error("Not authorized");
|
|
5769
|
+
}
|
|
5770
|
+
user[passwordFieldName] = {
|
|
5771
|
+
value: password,
|
|
5772
|
+
passwordChangeRequired: false
|
|
5773
|
+
};
|
|
5774
|
+
const params = {};
|
|
5775
|
+
set(
|
|
5776
|
+
params,
|
|
5777
|
+
userField.path.slice(1),
|
|
5778
|
+
// remove _rawData from users path
|
|
5779
|
+
users.map((u) => {
|
|
5780
|
+
if (user[idFieldName] === u[idFieldName]) {
|
|
5781
|
+
return user;
|
|
5782
|
+
}
|
|
5783
|
+
return {
|
|
5784
|
+
// don't overwrite other users' passwords
|
|
5785
|
+
...u,
|
|
5786
|
+
[passwordFieldName]: {
|
|
5787
|
+
...u[passwordFieldName],
|
|
5788
|
+
value: ""
|
|
5789
|
+
}
|
|
5790
|
+
};
|
|
5791
|
+
})
|
|
5792
|
+
);
|
|
5793
|
+
await resolver.updateResolveDocument({
|
|
5794
|
+
collection,
|
|
5795
|
+
args: { params },
|
|
5796
|
+
realPath,
|
|
5797
|
+
isCollectionSpecific: true,
|
|
5798
|
+
isAddPendingDocument: false
|
|
5799
|
+
});
|
|
5800
|
+
return true;
|
|
5801
|
+
}
|
|
5684
5802
|
|
|
5685
5803
|
// src/error.ts
|
|
5686
5804
|
import { GraphQLError as GraphQLError3 } from "graphql";
|
|
@@ -5790,119 +5908,33 @@ var resolve = async ({
|
|
|
5790
5908
|
);
|
|
5791
5909
|
}
|
|
5792
5910
|
}
|
|
5793
|
-
if (info.fieldName === "authenticate"
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
|
|
5801
|
-
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
const realPath = `${collection.path}/index.json`;
|
|
5812
|
-
const userDoc = await resolver.getDocument(realPath);
|
|
5813
|
-
const users = get(userDoc, userField.path);
|
|
5814
|
-
if (!users) {
|
|
5815
|
-
throw new Error("No users found");
|
|
5816
|
-
}
|
|
5817
|
-
const { idFieldName, passwordFieldName } = userField;
|
|
5818
|
-
if (!idFieldName) {
|
|
5819
|
-
throw new Error("No uid field found on user field");
|
|
5820
|
-
}
|
|
5821
|
-
const user = users.find((u) => u[idFieldName] === sub);
|
|
5822
|
-
if (!user) {
|
|
5823
|
-
return null;
|
|
5824
|
-
}
|
|
5825
|
-
if (info.fieldName === "authenticate") {
|
|
5826
|
-
const saltedHash = get(user, [passwordFieldName || "", "value"]);
|
|
5827
|
-
if (!saltedHash) {
|
|
5828
|
-
throw new Error("No password field found on user field");
|
|
5829
|
-
}
|
|
5830
|
-
const matches = await checkPasswordHash({
|
|
5831
|
-
saltedHash,
|
|
5832
|
-
password: args.password
|
|
5833
|
-
});
|
|
5834
|
-
if (matches) {
|
|
5835
|
-
return user;
|
|
5836
|
-
}
|
|
5837
|
-
return null;
|
|
5838
|
-
}
|
|
5839
|
-
return user;
|
|
5911
|
+
if (info.fieldName === "authenticate") {
|
|
5912
|
+
return handleAuthenticate({
|
|
5913
|
+
tinaSchema,
|
|
5914
|
+
resolver,
|
|
5915
|
+
sub: args.sub,
|
|
5916
|
+
password: args.password,
|
|
5917
|
+
info,
|
|
5918
|
+
ctxUser
|
|
5919
|
+
});
|
|
5920
|
+
}
|
|
5921
|
+
if (info.fieldName === "authorize") {
|
|
5922
|
+
return handleAuthorize({
|
|
5923
|
+
tinaSchema,
|
|
5924
|
+
resolver,
|
|
5925
|
+
sub: args.sub,
|
|
5926
|
+
info,
|
|
5927
|
+
ctxUser
|
|
5928
|
+
});
|
|
5840
5929
|
}
|
|
5841
5930
|
if (info.fieldName === "updatePassword") {
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
5845
|
-
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
const collection = tinaSchema.getCollections().find((c) => c.isAuthCollection);
|
|
5849
|
-
if (!collection) {
|
|
5850
|
-
throw new Error("Auth collection not found");
|
|
5851
|
-
}
|
|
5852
|
-
const userFields = mapUserFields(collection, ["_rawData"]);
|
|
5853
|
-
if (!userFields.length) {
|
|
5854
|
-
throw new Error(
|
|
5855
|
-
`No user field found in collection ${collection.name}`
|
|
5856
|
-
);
|
|
5857
|
-
}
|
|
5858
|
-
if (userFields.length > 1) {
|
|
5859
|
-
throw new Error(
|
|
5860
|
-
`Multiple user fields found in collection ${collection.name}`
|
|
5861
|
-
);
|
|
5862
|
-
}
|
|
5863
|
-
const userField = userFields[0];
|
|
5864
|
-
const realPath = `${collection.path}/index.json`;
|
|
5865
|
-
const userDoc = await resolver.getDocument(realPath);
|
|
5866
|
-
const users = get(userDoc, userField.path);
|
|
5867
|
-
if (!users) {
|
|
5868
|
-
throw new Error("No users found");
|
|
5869
|
-
}
|
|
5870
|
-
const { idFieldName, passwordFieldName } = userField;
|
|
5871
|
-
const user = users.find((u) => u[idFieldName] === ctxUser.sub);
|
|
5872
|
-
if (!user) {
|
|
5873
|
-
throw new Error("Not authorized");
|
|
5874
|
-
}
|
|
5875
|
-
user[passwordFieldName] = {
|
|
5876
|
-
value: args.password,
|
|
5877
|
-
passwordChangeRequired: false
|
|
5878
|
-
};
|
|
5879
|
-
const params = {};
|
|
5880
|
-
set(
|
|
5881
|
-
params,
|
|
5882
|
-
userField.path.slice(1),
|
|
5883
|
-
// remove _rawData from users path
|
|
5884
|
-
users.map((u) => {
|
|
5885
|
-
if (user[idFieldName] === u[idFieldName]) {
|
|
5886
|
-
return user;
|
|
5887
|
-
}
|
|
5888
|
-
return {
|
|
5889
|
-
// don't overwrite other users' passwords
|
|
5890
|
-
...u,
|
|
5891
|
-
[passwordFieldName]: {
|
|
5892
|
-
...u[passwordFieldName],
|
|
5893
|
-
value: ""
|
|
5894
|
-
}
|
|
5895
|
-
};
|
|
5896
|
-
})
|
|
5897
|
-
);
|
|
5898
|
-
await resolver.updateResolveDocument({
|
|
5899
|
-
collection,
|
|
5900
|
-
args: { params },
|
|
5901
|
-
realPath,
|
|
5902
|
-
isCollectionSpecific: true,
|
|
5903
|
-
isAddPendingDocument: false
|
|
5931
|
+
return handleUpdatePassword({
|
|
5932
|
+
tinaSchema,
|
|
5933
|
+
resolver,
|
|
5934
|
+
password: args.password,
|
|
5935
|
+
info,
|
|
5936
|
+
ctxUser
|
|
5904
5937
|
});
|
|
5905
|
-
return true;
|
|
5906
5938
|
}
|
|
5907
5939
|
if (!lookup) {
|
|
5908
5940
|
return value;
|
|
@@ -6115,7 +6147,7 @@ import path4 from "node:path";
|
|
|
6115
6147
|
import { GraphQLError as GraphQLError5 } from "graphql";
|
|
6116
6148
|
import micromatch2 from "micromatch";
|
|
6117
6149
|
import sha2 from "js-sha1";
|
|
6118
|
-
import set2 from "
|
|
6150
|
+
import { set as set2 } from "es-toolkit/compat";
|
|
6119
6151
|
var createLocalDatabase = (config) => {
|
|
6120
6152
|
const level = new TinaLevelClient(config?.port);
|
|
6121
6153
|
level.openConnection();
|
|
@@ -6490,8 +6522,7 @@ var Database = class {
|
|
|
6490
6522
|
throw new TinaFetchError(`Error in PUT for ${filepath}`, {
|
|
6491
6523
|
originalError: error,
|
|
6492
6524
|
file: filepath,
|
|
6493
|
-
collection: collectionName
|
|
6494
|
-
stack: error.stack
|
|
6525
|
+
collection: collectionName
|
|
6495
6526
|
});
|
|
6496
6527
|
}
|
|
6497
6528
|
};
|
|
@@ -6851,8 +6882,7 @@ var Database = class {
|
|
|
6851
6882
|
throw new TinaQueryError({
|
|
6852
6883
|
originalError: error,
|
|
6853
6884
|
file: path7,
|
|
6854
|
-
collection: collection.name
|
|
6855
|
-
stack: error.stack
|
|
6885
|
+
collection: collection.name
|
|
6856
6886
|
});
|
|
6857
6887
|
}
|
|
6858
6888
|
throw error;
|
|
@@ -7382,8 +7412,7 @@ var _indexContent = async ({
|
|
|
7382
7412
|
throw new TinaFetchError(`Unable to seed ${filepath}`, {
|
|
7383
7413
|
originalError: error,
|
|
7384
7414
|
file: filepath,
|
|
7385
|
-
collection: collection?.name
|
|
7386
|
-
stack: error.stack
|
|
7415
|
+
collection: collection?.name
|
|
7387
7416
|
});
|
|
7388
7417
|
}
|
|
7389
7418
|
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { TinaSchema } from '@tinacms/schema-tools';
|
|
2
|
+
import type { GraphQLResolveInfo } from 'graphql';
|
|
3
|
+
import type { Resolver } from './index';
|
|
4
|
+
export declare function handleAuthenticate({ tinaSchema, resolver, sub, password, ctxUser, }: {
|
|
5
|
+
tinaSchema: TinaSchema;
|
|
6
|
+
resolver: Resolver;
|
|
7
|
+
sub?: string;
|
|
8
|
+
password: string;
|
|
9
|
+
info: GraphQLResolveInfo;
|
|
10
|
+
ctxUser?: {
|
|
11
|
+
sub?: string;
|
|
12
|
+
};
|
|
13
|
+
}): Promise<any>;
|
|
14
|
+
export declare function handleAuthorize({ tinaSchema, resolver, sub, ctxUser, }: {
|
|
15
|
+
tinaSchema: TinaSchema;
|
|
16
|
+
resolver: Resolver;
|
|
17
|
+
sub?: string;
|
|
18
|
+
info: GraphQLResolveInfo;
|
|
19
|
+
ctxUser?: {
|
|
20
|
+
sub?: string;
|
|
21
|
+
};
|
|
22
|
+
}): Promise<any>;
|
|
23
|
+
export declare function handleUpdatePassword({ tinaSchema, resolver, password, ctxUser, }: {
|
|
24
|
+
tinaSchema: TinaSchema;
|
|
25
|
+
resolver: Resolver;
|
|
26
|
+
password: string;
|
|
27
|
+
info: GraphQLResolveInfo;
|
|
28
|
+
ctxUser?: {
|
|
29
|
+
sub?: string;
|
|
30
|
+
};
|
|
31
|
+
}): Promise<boolean>;
|
package/dist/resolver/error.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export declare class TinaGraphQLError extends Error implements GraphQLError {
|
|
|
15
15
|
constructor(message: string, extensions?: Record<string, any>);
|
|
16
16
|
}
|
|
17
17
|
export type TypeFetchErrorArgs = {
|
|
18
|
+
/** @deprecated */
|
|
18
19
|
stack?: string;
|
|
19
20
|
file?: string;
|
|
20
21
|
includeAuditMessage?: boolean;
|
|
@@ -22,7 +23,6 @@ export type TypeFetchErrorArgs = {
|
|
|
22
23
|
collection?: string;
|
|
23
24
|
};
|
|
24
25
|
export declare class TinaFetchError extends Error {
|
|
25
|
-
stack?: string;
|
|
26
26
|
collection?: string;
|
|
27
27
|
file?: string;
|
|
28
28
|
originalError: Error;
|
|
@@ -36,7 +36,6 @@ export declare class TinaQueryError extends TinaFetchError {
|
|
|
36
36
|
constructor(args: TypeFetchErrorArgs);
|
|
37
37
|
}
|
|
38
38
|
export declare class TinaParseDocumentError extends TinaFetchError {
|
|
39
|
-
stack?: string;
|
|
40
39
|
collection?: string;
|
|
41
40
|
file?: string;
|
|
42
41
|
originalError: Error;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tinacms/graphql",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.3",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"@iarna/toml": "^2.2.5",
|
|
27
27
|
"abstract-level": "^1.0.4",
|
|
28
28
|
"date-fns": "^2.30.0",
|
|
29
|
+
"es-toolkit": "^1.42.0",
|
|
29
30
|
"fast-glob": "^3.3.3",
|
|
30
31
|
"fs-extra": "^11.3.0",
|
|
31
32
|
"glob-parent": "^6.0.2",
|
|
@@ -35,17 +36,14 @@
|
|
|
35
36
|
"js-sha1": "^0.6.0",
|
|
36
37
|
"js-yaml": "^3.14.1",
|
|
37
38
|
"jsonpath-plus": "10.1.0",
|
|
38
|
-
"lodash.clonedeep": "^4.5.0",
|
|
39
|
-
"lodash.set": "^4.3.2",
|
|
40
|
-
"lodash.uniqby": "^4.7.0",
|
|
41
39
|
"many-level": "^2.0.0",
|
|
42
40
|
"micromatch": "4.0.8",
|
|
43
41
|
"normalize-path": "^3.0.0",
|
|
44
42
|
"readable-stream": "^4.7.0",
|
|
45
43
|
"scmp": "^2.1.0",
|
|
46
|
-
"yup": "^
|
|
47
|
-
"@tinacms/
|
|
48
|
-
"@tinacms/
|
|
44
|
+
"yup": "^1.6.1",
|
|
45
|
+
"@tinacms/mdx": "1.8.3",
|
|
46
|
+
"@tinacms/schema-tools": "1.10.1"
|
|
49
47
|
},
|
|
50
48
|
"publishConfig": {
|
|
51
49
|
"registry": "https://registry.npmjs.org"
|
|
@@ -60,23 +58,20 @@
|
|
|
60
58
|
"@types/express": "^4.17.21",
|
|
61
59
|
"@types/fs-extra": "^9.0.13",
|
|
62
60
|
"@types/js-yaml": "^3.12.10",
|
|
63
|
-
"@types/lodash.camelcase": "^4.3.9",
|
|
64
|
-
"@types/lodash.upperfirst": "^4.3.9",
|
|
65
61
|
"@types/lru-cache": "^5.1.1",
|
|
66
62
|
"@types/mdast": "^3.0.15",
|
|
67
63
|
"@types/micromatch": "^4.0.9",
|
|
68
64
|
"@types/node": "^22.13.1",
|
|
69
65
|
"@types/normalize-path": "^3.0.2",
|
|
70
66
|
"@types/ws": "^7.4.7",
|
|
71
|
-
"@types/yup": "^0.29.14",
|
|
72
67
|
"jest-file-snapshot": "^0.5.0",
|
|
73
68
|
"memory-level": "^1.0.0",
|
|
74
69
|
"typescript": "^5.7.3",
|
|
75
70
|
"vite": "^4.5.9",
|
|
76
71
|
"vitest": "^0.32.4",
|
|
77
72
|
"zod": "^3.24.2",
|
|
78
|
-
"@tinacms/
|
|
79
|
-
"@tinacms/
|
|
73
|
+
"@tinacms/schema-tools": "1.10.1",
|
|
74
|
+
"@tinacms/scripts": "1.4.1"
|
|
80
75
|
},
|
|
81
76
|
"scripts": {
|
|
82
77
|
"types": "pnpm tsc",
|