Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
function validateKeyField(field: FieldDefinitionNode): void {
if (!field) {
return
}
const isNonNull = isNonNullType(field.type);
const isAList = isListType(field.type)
// The only valid key fields are single non-null fields.
if (!isAList && isNonNull) {
return;
}
throw new InvalidDirectiveError(`All fields used for a relation cannot be lists and must be of Non-Null types.`)
}
for (const otherDirective of definition.directives.filter(d => d.name.value === 'key')) {
const otherArgs = getDirectiveArguments(otherDirective);
if (otherDirective !== directive && !otherArgs.name) {
throw new InvalidDirectiveError(`You may only supply one primary @key on type '${definition.name.value}'.`);
}
// 5. If there is no primary sort key, make sure there are no more LSIs.
const hasPrimarySortKey = directiveArgs.fields.length > 1;
const primaryHashField = directiveArgs.fields[0];
const otherHashField = otherArgs.fields[0];
if (
otherDirective !== directive &&
!hasPrimarySortKey &&
// If the primary key and other key share the first field and are not the same directive it is an LSI.
primaryHashField === otherHashField
) {
throw new InvalidDirectiveError(
`Invalid @key "${otherArgs.name}". You may not create a @key where the first field in 'fields' ` +
`is the same as that of the primary @key unless the primary @key has multiple 'fields'. ` +
`You cannot have a local secondary index without a sort key in the primary index.`
);
}
}
// 4. Make sure that a 'queryField' is not included on a primary @key.
if (directiveArgs.queryField) {
throw new InvalidDirectiveError(`You cannot pass 'queryField' to the primary @key on type '${definition.name.value}'.`);
}
} else {
// 2. Make sure there are no more directives with the same name.
for (const otherDirective of definition.directives.filter(d => d.name.value === 'key')) {
const otherArgs = getDirectiveArguments(otherDirective);
if (otherDirective !== directive && otherArgs.name === directiveArgs.name) {
throw new InvalidDirectiveError(`You may only supply one @key with the name '${directiveArgs.name}' on type '${definition.name.value}'.`);
function validateKeyField(field: FieldDefinitionNode): void {
if (!field) {
return
}
const baseType = getBaseType(field.type);
const isAList = isListType(field.type)
// The only valid key fields are single String and ID fields.
if (
(baseType === 'ID' || baseType === 'String') &&
(!isAList)
) {
return;
}
throw new InvalidDirectiveError(`If you define a field and specify it as a 'keyField', it must be of type 'ID' or 'String'.`)
}
public object = (def: ObjectTypeDefinitionNode, directive: DirectiveNode, ctx: TransformerContext): void => {
const get = (s: string) => (arg: ArgumentNode) => arg.name.value === s
const getArg = (arg: string, dflt?: any) => {
const argument = directive.arguments.find(get(arg))
return argument ? valueFromASTUntyped(argument.value) : dflt
}
const modelDirective = def.directives.find((dir) => dir.name.value === 'model')
if (!modelDirective) {
throw new InvalidDirectiveError('Types annotated with @auth must also be annotated with @model.')
}
// Get and validate the auth rules.
const rules = getArg('rules', []) as AuthRule[]
this.validateRules(rules)
const { operationRules, queryRules } = this.splitRules(rules);
// For each operation evaluate the rules and apply the changes to the relevant resolver.
this.protectCreateMutation(ctx, ResolverResourceIDs.DynamoDBCreateResolverResourceID(def.name.value), operationRules.create, def)
this.protectUpdateMutation(ctx, ResolverResourceIDs.DynamoDBUpdateResolverResourceID(def.name.value), operationRules.update, def)
this.protectDeleteMutation(ctx, ResolverResourceIDs.DynamoDBDeleteResolverResourceID(def.name.value), operationRules.delete, def)
this.protectGetQuery(ctx, ResolverResourceIDs.DynamoDBGetResolverResourceID(def.name.value), queryRules.get)
this.protectListQuery(ctx, ResolverResourceIDs.DynamoDBListResolverResourceID(def.name.value), queryRules.list)
this.protectConnections(ctx, def, operationRules.read)
this.protectQueries(ctx, def, operationRules.read)
private commonRuleValidation(rule: AuthRule) {
const { identityField, identityClaim, allow,
groups, groupsField, groupClaim
} = rule;
if ( allow === 'groups' && (identityClaim || identityField)) {
throw new InvalidDirectiveError(`
@auth identityField/Claim can only be used for 'allow: owner'`)
}
if (allow === 'owner' && groupClaim) {
throw new InvalidDirectiveError(`
@auth groupClaim can only be used 'allow: groups'`);
}
if ( groupsField && groups) {
throw new InvalidDirectiveError("This rule has groupsField and groups, please use one or the other")
}
if (identityField && identityClaim) {
throw new InvalidDirectiveError("Please use consider IdentifyClaim over IdentityField as it is deprecated.")
}
}
function checkFieldsAgainstIndex(parentFields: ReadonlyArray,
relatedTypeFields: ReadonlyArray,
inputFieldNames: string[],
keySchema: KeySchema[]): void {
let hashAttributeName = keySchema[0].AttributeName;
let tablePKType = relatedTypeFields.find(f => f.name.value === hashAttributeName).type;
let queryPKType = parentFields.find(f => f.name.value === inputFieldNames[0]).type;
let numFields = inputFieldNames.length;
if (getBaseType(tablePKType) !== getBaseType(queryPKType)) {
throw new InvalidDirectiveError(inputFieldNames[0] + ' field is not of type ' + getBaseType(tablePKType))
}
if (numFields > keySchema.length) {
throw new InvalidDirectiveError('Too many fields passed in for relation.')
}
if (numFields > 1) {
let sortAttributeName = keySchema[1].AttributeName;
let tableSKType = relatedTypeFields.find(f => f.name.value === sortAttributeName).type;
let querySKType = parentFields.find(f => f.name.value === inputFieldNames[1]).type;
if (getBaseType(tableSKType) !== getBaseType(querySKType)) {
throw new InvalidDirectiveError(inputFieldNames[1] + ' field is not of type ' + getBaseType(tableSKType))
}
}
}
private stripCreateInputVersionedField(ctx: TransformerContext, typeName: string, versionField: string) {
const createInputName = ModelResourceIDs.ModelCreateInputObjectName(typeName);
const input = ctx.getType(createInputName);
if (input && input.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION) {
const updatedFields = input.fields.filter(f => f.name.value !== versionField);
if (updatedFields.length === 0) {
throw new InvalidDirectiveError(
`After stripping away version field "${versionField}", \
the create input for type "${typeName}" cannot be created \
with 0 fields. Add another field to type "${typeName}" to continue.`
);
}
const updatedInput = {
...input,
fields: updatedFields,
};
ctx.putType(updatedInput);
}
}
private commonRuleValidation(rule: AuthRule) {
const { identityField, identityClaim, allow,
groups, groupsField, groupClaim
} = rule;
if ( allow === 'groups' && (identityClaim || identityField)) {
throw new InvalidDirectiveError(`
@auth identityField/Claim can only be used for 'allow: owner'`)
}
if (allow === 'owner' && groupClaim) {
throw new InvalidDirectiveError(`
@auth groupClaim can only be used 'allow: groups'`);
}
if ( groupsField && groups) {
throw new InvalidDirectiveError("This rule has groupsField and groups, please use one or the other")
}
if (identityField && identityClaim) {
throw new InvalidDirectiveError("Please use consider IdentifyClaim over IdentityField as it is deprecated.")
}
}
const { identityField, identityClaim, allow,
groups, groupsField, groupClaim
} = rule;
if ( allow === 'groups' && (identityClaim || identityField)) {
throw new InvalidDirectiveError(`
@auth identityField/Claim can only be used for 'allow: owner'`)
}
if (allow === 'owner' && groupClaim) {
throw new InvalidDirectiveError(`
@auth groupClaim can only be used 'allow: groups'`);
}
if ( groupsField && groups) {
throw new InvalidDirectiveError("This rule has groupsField and groups, please use one or the other")
}
if (identityField && identityClaim) {
throw new InvalidDirectiveError("Please use consider IdentifyClaim over IdentityField as it is deprecated.")
}
}