Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const mutations = unique(
flatten([
...firstClassLists.map(list => list.getGqlMutations({ schemaName })),
this._extendedMutations
.filter(({ access }) => access[schemaName])
.map(({ schema }) => schema),
])
);
// Fields can be represented multiple times within and between lists.
// If a field defines a `getGqlAuxTypes()` method, it will be
// duplicated.
// graphql-tools will blow up (rightly so) on duplicated types.
// Deduping here avoids that problem.
return [
...unique(flatten(this.listsArray.map(list => list.getGqlTypes({ schemaName })))),
...unique(
this._extendedTypes.filter(({ access }) => access[schemaName]).map(({ type }) => type)
),
`"""NOTE: Can be JSON, or a Boolean/Int/String
Why not a union? GraphQL doesn't support a union including a scalar
(https://github.com/facebook/graphql/issues/215)"""
scalar JSON`,
`type _ListAccess {
"""Access Control settings for the currently logged in (or anonymous)
user when performing 'create' operations.
NOTE: 'create' can only return a Boolean.
It is not possible to specify a declarative Where clause for this
operation"""
create: Boolean
"""Access Control settings for the currently logged in (or anonymous)
flatten([
...firstClassLists.map(list => list.getGqlMutations({ schemaName })),
this._extendedMutations
.filter(({ access }) => access[schemaName])
.map(({ schema }) => schema),
])
);
// Fields can be represented multiple times within and between lists.
// If a field defines a `getGqlAuxTypes()` method, it will be
// duplicated.
// graphql-tools will blow up (rightly so) on duplicated types.
// Deduping here avoids that problem.
return [
...unique(flatten(this.listsArray.map(list => list.getGqlTypes({ schemaName })))),
...unique(
this._extendedTypes.filter(({ access }) => access[schemaName]).map(({ type }) => type)
),
`"""NOTE: Can be JSON, or a Boolean/Int/String
Why not a union? GraphQL doesn't support a union including a scalar
(https://github.com/facebook/graphql/issues/215)"""
scalar JSON`,
`type _ListAccess {
"""Access Control settings for the currently logged in (or anonymous)
user when performing 'create' operations.
NOTE: 'create' can only return a Boolean.
It is not possible to specify a declarative Where clause for this
operation"""
create: Boolean
"""Access Control settings for the currently logged in (or anonymous)
user when performing 'read' operations."""
if (access === true) {
return await this._itemsQuery({ where: { id_in: uniqueIds } }, { context, info });
}
let idFilters = {};
if (access.id || access.id_in) {
const accessControlIdsAllowed = unique([].concat(access.id, access.id_in).filter(id => id));
idFilters.id_in = intersection(accessControlIdsAllowed, uniqueIds);
} else {
idFilters.id_in = uniqueIds;
}
if (access.id_not || access.id_not_in) {
const accessControlIdsDisallowed = unique(
[].concat(access.id_not, access.id_not_in).filter(id => id)
);
idFilters.id_not_in = intersection(accessControlIdsDisallowed, uniqueIds);
}
// It's odd, but conceivable the access control specifies a single id
// the user has access to. So we have to do a check here to see if the
// ID they're requesting matches that ID.
// Nice side-effect: We can throw without having to ever query the DB.
if (
// Only some ids are allowed, and none of them have been passed in
(idFilters.id_in && idFilters.id_in.length === 0) ||
// All the passed in ids have been explicitly disallowed
(idFilters.id_not_in && idFilters.id_not_in.length === uniqueIds.length)
) {
async getAccessControlledItems(ids, access, { context, info } = {}) {
if (ids.length === 0) {
return [];
}
const uniqueIds = unique(ids);
// Early out - the user has full access to operate on this list
if (access === true) {
return await this._itemsQuery({ where: { id_in: uniqueIds } }, { context, info });
}
let idFilters = {};
if (access.id || access.id_in) {
const accessControlIdsAllowed = unique([].concat(access.id, access.id_in).filter(id => id));
idFilters.id_in = intersection(accessControlIdsAllowed, uniqueIds);
} else {
idFilters.id_in = uniqueIds;
}
getTypeDefs({ schemaName }) {
// Aux lists are only there for typing and internal operations, they should
// not have any GraphQL operations performed on them
const firstClassLists = this.listsArray.filter(list => !list.isAuxList);
const mutations = unique(
flatten([
...firstClassLists.map(list => list.getGqlMutations({ schemaName })),
this._extendedMutations
.filter(({ access }) => access[schemaName])
.map(({ schema }) => schema),
])
);
// Fields can be represented multiple times within and between lists.
// If a field defines a `getGqlAuxTypes()` method, it will be
// duplicated.
// graphql-tools will blow up (rightly so) on duplicated types.
// Deduping here avoids that problem.
return [
...unique(flatten(this.listsArray.map(list => list.getGqlTypes({ schemaName })))),
...unique(
async getAccessControlledItems(ids, access, { context, info } = {}) {
if (ids.length === 0) {
return [];
}
const uniqueIds = unique(ids);
// Early out - the user has full access to operate on this list
if (access === true) {
return await this._itemsQuery({ where: { id_in: uniqueIds } }, { context, info });
}
let idFilters = {};
if (access.id || access.id_in) {
const accessControlIdsAllowed = unique([].concat(access.id, access.id_in).filter(id => id));
idFilters.id_in = intersection(accessControlIdsAllowed, uniqueIds);
} else {
idFilters.id_in = uniqueIds;
}
if (access.id_not || access.id_not_in) {
const accessControlIdsDisallowed = unique(
[].concat(access.id_not, access.id_not_in).filter(id => id)
);
idFilters.id_not_in = intersection(accessControlIdsDisallowed, uniqueIds);
}
// It's odd, but conceivable the access control specifies a single id
// the user has access to. So we have to do a check here to see if the
`type _ListMeta {
"""The Keystone List name"""
name: String
"""Access control configuration for the currently authenticated
request"""
access: _ListAccess
"""Information on the generated GraphQL schema"""
schema: _ListSchema
}`,
`type _QueryMeta {
count: Int
}`,
`type Query {
${unique(
flatten([
...firstClassLists.map(list => list.getGqlQueries({ schemaName })),
this.appVersion.access[schemaName]
? [
`"""The version of the Keystone application serving this API."""
appVersion: String`,
]
: [],
this._extendedQueries
.filter(({ access }) => access[schemaName])
.map(({ schema }) => schema),
])
).join('\n')}
""" Retrieve the meta-data for all lists. """
_ksListsMeta: [_ListMeta]
}`,
extendAdminViews(views) {
return {
...views,
blocks: unique(flatMap(this.blocks, block => block.getAdminViews())),
};
}