Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
}
const authExpression = this.authorizationExpressionOnSingleObject(rules, 'ctx.source')
if (protectPrivateFields) {
if (field.type.kind === Kind.NON_NULL_TYPE) {
throw new InvalidDirectiveError(`\nPer-field auth on the required field ${field.name.value} is not supported with subscriptions.
Either make the field optional, set auth on the object and not the field, or disable subscriptions for the object (setting level to OFF or PUBLIC)\n`)
}
// add operation to queryField
this.protectMutations(ctx, typeName, ctx.getMutationTypeName())
// add operation check in the field resolver
resolver.Properties.ResponseMappingTemplate = print(
this.resources.operationCheckExpression(ctx.getMutationTypeName(), field.name.value));
}
// If a resolver exists, a @connection for example. Prepend it to the req.
const templateParts = [
print(authExpression),
resolver.Properties.RequestMappingTemplate
]
resolver.Properties.RequestMappingTemplate = templateParts.join('\n\n')
ctx.setResource(resolverResourceId, resolver)
}
}
const fieldIsList = (fieldName: string) => {
const field = parent.fields.find(field => field.name.value === fieldName);
if (field) {
return isListType(field.type);
}
return false;
};
const ownerAuthorizationExpression = this.resources.ownerAuthorizationExpressionForSubscriptions(
ownerAuthorizationRules,
fieldIsList
);
const throwIfUnauthorizedExpression = this.resources.throwIfSubscriptionUnauthorized();
const templateParts = [
print(
compoundExpression([
staticGroupAuthorizationExpression,
newline(),
ownerAuthorizationExpression,
newline(),
throwIfUnauthorizedExpression
])
),
resolver.Properties.ResponseMappingTemplate
];
resolver.Properties.ResponseMappingTemplate = templateParts.join('\n\n');
ctx.setResource(resolverResourceId, resolver);
// check if owner is enabled in auth
const hasOwner = rules.find( rule => rule.allow === OWNER_AUTH_STRATEGY && !rule.ownerField);
const hasStaticGroupAuth = rules.find( rule => rule.allow === GROUPS_AUTH_STRATEGY && !rule.groupsField);
public makeDeleteResolver({ type, nameOverride, syncConfig, mutationTypeName = 'Mutation' }: MutationResolverInput) {
const fieldName = nameOverride ? nameOverride : graphqlName('delete' + toUpper(type));
const isSyncEnabled = syncConfig ? true : false;
return new AppSync.Resolver({
ApiId: Fn.GetAtt(ResourceConstants.RESOURCES.GraphQLAPILogicalID, 'ApiId'),
DataSourceName: Fn.GetAtt(ModelResourceIDs.ModelTableDataSourceID(type), 'Name'),
FieldName: fieldName,
TypeName: mutationTypeName,
RequestMappingTemplate: print(
compoundExpression([
ifElse(
ref(ResourceConstants.SNIPPETS.AuthCondition),
compoundExpression([
set(ref('condition'), ref(ResourceConstants.SNIPPETS.AuthCondition)),
ifElse(
ref(ResourceConstants.SNIPPETS.ModelObjectKey),
forEach(ref('entry'), ref(`${ResourceConstants.SNIPPETS.ModelObjectKey}.entrySet()`), [
qref('$condition.put("expression", "$condition.expression AND attribute_exists(#keyCondition$velocityCount)")'),
qref('$condition.expressionNames.put("#keyCondition$velocityCount", "$entry.key")'),
]),
compoundExpression([
qref('$condition.put("expression", "$condition.expression AND attribute_exists(#id)")'),
qref('$condition.expressionNames.put("#id", "id")'),
])
),
private makeListRelationalResolver(type: string, queryTypeName: string = 'Query') {
const fieldName = graphqlName('list' + plurality(toUpper(type)));
const sql = `SELECT * FROM ${type}`;
const reqFileName = `${queryTypeName}.${fieldName}.req.vtl`;
const resFileName = `${queryTypeName}.${fieldName}.res.vtl`;
const reqTemplate = print(
RelationalDBMappingTemplate.rdsQuery({
statements: list([str(sql)]),
})
);
const resTemplate = print(ref('utils.toJson($utils.rds.toJsonObject($ctx.result)[0])'));
fs.writeFileSync(`${this.resolverFilePath}/${reqFileName}`, reqTemplate, 'utf8');
fs.writeFileSync(`${this.resolverFilePath}/${resFileName}`, resTemplate, 'utf8');
let resolver = new AppSync.Resolver({
ApiId: Fn.Ref(ResourceConstants.PARAMETERS.AppSyncApiId),
DataSourceName: Fn.GetAtt(ResourceConstants.RESOURCES.RelationalDatabaseDataSource, 'Name'),
TypeName: queryTypeName,
FieldName: fieldName,
RequestMappingTemplateS3Location: Fn.Sub(s3BaseUrl, {
[ResourceConstants.PARAMETERS.S3DeploymentBucket]: Fn.Ref(ResourceConstants.PARAMETERS.S3DeploymentBucket),
public blankResolver(type: string, field: string) {
return new AppSync.Resolver({
ApiId: Fn.GetAtt(ResourceConstants.RESOURCES.GraphQLAPILogicalID, 'ApiId'),
DataSourceName: 'NONE',
FieldName: field,
TypeName: type,
RequestMappingTemplate: print(obj({
"version": str("2017-02-28"),
"payload": obj({})
})),
ResponseMappingTemplate: print(ref(`util.toJson($context.source.${field})`))
})
}
const fieldIsList = (fieldName: string) => {
const field = parent.fields.find(field => field.name.value === fieldName);
if (field) {
return isListType(field.type);
}
return false;
}
const ownerAuthorizationExpression = this.resources.ownerAuthorizationExpressionForCreateOperationsByField(
ownerAuthorizationRules,
field.name.value,
fieldIsList
)
const throwIfUnauthorizedExpression = this.resources.throwIfUnauthorized()
const templateParts = [
print(
iff(
raw(`$ctx.args.input.containsKey("${field.name.value}")`),
compoundExpression([
staticGroupAuthorizationExpression,
newline(),
dynamicGroupAuthorizationExpression,
newline(),
ownerAuthorizationExpression,
newline(),
throwIfUnauthorizedExpression
])
)
),
createResolverResource.Properties.RequestMappingTemplate
]
createResolverResource.Properties.RequestMappingTemplate = templateParts.join('\n\n')
),
DynamoDBMappingTemplate.deleteItem({
key: ifElse(
ref(ResourceConstants.SNIPPETS.ModelObjectKey),
raw(`$util.toJson(\$${ResourceConstants.SNIPPETS.ModelObjectKey})`),
obj({
id: ref('util.dynamodb.toDynamoDBJson($ctx.args.input.id)'),
}),
true
),
condition: ref('util.toJson($condition)'),
isSyncEnabled,
}),
])
),
ResponseMappingTemplate: isSyncEnabled ? print(DynamoDBMappingTemplate.dynamoDBResponse()) : print(ref('util.toJson($ctx.result)')),
...(syncConfig && { SyncConfig: SyncUtils.syncResolverConfig(syncConfig) }),
});
}
}
public makeGetItemConnectionResolver(type: string, field: string, relatedType: string, connectionAttribute: string): Resolver {
return new Resolver({
ApiId: Fn.GetAtt(ResourceConstants.RESOURCES.GraphQLAPILogicalID, 'ApiId'),
DataSourceName: Fn.GetAtt(ModelResourceIDs.ModelTableDataSourceID(relatedType), 'Name'),
FieldName: field,
TypeName: type,
RequestMappingTemplate: print(
DynamoDBMappingTemplate.getItem({
key: obj({
id: ref(`util.dynamodb.toDynamoDBJson($util.defaultIfNullOrBlank($ctx.source.${connectionAttribute}, "${NONE_VALUE}"))`)
})
})
),
ResponseMappingTemplate: print(
ref('util.toJson($context.result)')
)
}).dependsOn(ResourceConstants.RESOURCES.GraphQLSchemaLogicalID)
}
public generateSubscriptionResolver(fieldName: string, subscriptionTypeName: string = 'Subscription') {
return new AppSync.Resolver({
ApiId: Fn.GetAtt(ResourceConstants.RESOURCES.GraphQLAPILogicalID, 'ApiId'),
DataSourceName: 'NONE',
FieldName: fieldName,
TypeName: subscriptionTypeName,
RequestMappingTemplate: print(
raw(`{
"version": "2018-05-29",
"payload": {}
}`)
),
ResponseMappingTemplate: print(raw(`$util.toJson(null)`)),
});
}
private protectListQuery(ctx: TransformerContext, resolverResourceId: string, rules: AuthRule[]) {
const resolver = ctx.getResource(resolverResourceId)
if (!rules || rules.length === 0 || !resolver) {
return
} else {
const authExpression = this.authorizationExpressionForListResult(rules)
const templateParts = [
print(authExpression),
resolver.Properties.ResponseMappingTemplate
]
resolver.Properties.ResponseMappingTemplate = templateParts.join('\n\n')
ctx.setResource(resolverResourceId, resolver)
}
}