Closed lafeer closed 1 month ago
Hi @lafeer I think the issue might be using allow: owner
as an auth rule. I'm not sure that works on a mutation the same way it does on a model. I'll have to confirm with the team. However, in the meantime, you could try simply allowing authenticated users to perform the mutation (allow: private
) and in the lambda logic you are already checking and making use of the event.identity
to make sure only to delete the records of the user making the request.
Let me know if that helps!
Also, in case the owner
auth rule is expected to work with a custom mutation, what exactly do you expect the auth resolver to do with the owner field before the custom lambda is invoked?
Hi @chrisbonifacio. Thank you for getting back to me on this.
I've tried using allow: private
, and I run into the same "Not Authorized to access deleteUserData on type Mutation" as with allow: owner
When I remove allow: owner
or allow: private
, I end up with the following event object in my lambda, where the identity
is null.
{
"typeName": "Mutation",
"fieldName": "deleteUserData",
"arguments": {},
"identity": null,
"source": null,
"request": {
"headers": {
"x-forwarded-for": "xxxxxxxxxxxxxxxx",
"cloudfront-viewer-country": "ID",
"cloudfront-is-tablet-viewer": "false",
"x-amzn-requestid": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"via": "2.0 xxxxxxxxxxxxxxxxxxxxxxxx.cloudfront.net (CloudFront)",
"cloudfront-forwarded-proto": "https",
"content-length": "75",
"accept-language": "en-US,en;q=0.9",
"host": "xxxxxxxxxxxxxxxxx.appsync-api.ap-southeast-1.amazonaws.com",
"x-forwarded-proto": "https",
"user-agent": "wishwell/1 CFNetwork/1498.700.2 Darwin/23.6.0",
"cloudfront-is-mobile-viewer": "false",
"accept": "*/*",
"cloudfront-viewer-asn": "xxxxx",
"cloudfront-is-smarttv-viewer": "false",
"x-amzn-appsync-is-vpce-request": "false",
"accept-encoding": "gzip, deflate, br",
"x-amzn-remote-ip": "103.175.213.136",
"content-type": "application/json; charset=UTF-8",
"x-api-key": "xxx-ccccccccccccccccccccccc",
"x-amz-cf-id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"x-amzn-trace-id": "Root=1-66e66baf-xxxxxxxxxxxxxxxxxxxx",
"x-amz-user-agent": "aws-amplify/6.0.16 api/1 framework/202",
"cloudfront-is-desktop-viewer": "true",
"x-forwarded-port": "443"
},
"domainName": null
},
"prev": {
"result": {}
}
}
Hi @lafeer the identity will be null
because without the allow: private
auth rule, you're using an auth mode where an identity doesn't get passed along. Does your schema have a global auth rule at the top?
So even with allow: private
added like below, I get the "Not Authorized to access deleteUserData on type Mutation".
type Mutation { deleteUserData: Boolean! @auth(rules: [{ allow: private }]) @function(name: "deleteUserData-${env}") }
No, my schema is exactly like it is in the description above.
Hi @lafeer it seems like your default auth mode is API_KEY according to the config shared:
"aws_appsync_authenticationType": "API_KEY",
You should try setting the auth mode on the request like so:
const deletedUser = await client.graphql({
query: deleteUserData,
variables: {},
},
{authMode: 'userPool'}
);
This should set the Authorization header to the current authenticated user's Cognito access token rather than the x-api-key
header that is currently being applied as shown in the network logs you shared.
Hi 👋 Closing this as we have not heard back from you. If you are still experiencing this issue and in need of assistance, please feel free to comment and provide us with any information previously requested by our team members so we can re-open this issue and be better able to assist you.
Thank you!
Hi,
I got the same issue "Not Authorized to access deleteUserData on type Mutation". I well followed the doc from aws: Steps to clean up user data
When I test the function from the lambda console, it works.
When I test from my app or from the AppSync query editor, I got the error. If I set the "allow: private", it works as well, but not with "allow: owner"
My schema:
type Item @model @auth(rules: [{allow: owner}]) {
ownerId: ID!
lastUseDateTime: AWSDateTime!
contentEncrypted: String!
itemKeyEncrypted: String!
itemType: String!
createdAt: AWSDateTime!
}
type Device @model @auth(rules: [{allow: owner}]) {
id: ID! @primaryKey
ownerId: ID!
name: String!
brand: String!
model: String!
systemName: String!
deviceType: String!
createdAt: AWSDateTime!
}
type Mutation {
deleteUserData: Boolean
@function(name: "deleteUserDataAfterAccountDelete-${env}")
@auth(rules: [{allow: owner}])
}
My function:
const AWS = require('aws-sdk');
AWS.config.update({ region: process.env.REGION });
const dynamodb = new AWS.DynamoDB.DocumentClient();
const tableName = process.env.API_SIMPLIPASSAMPLIFYG1_ITEMTABLE_NAME;
const THIRTY_DAYS_IN_SECONDS = 30 * 24 * 60 * 60;
exports.handler = async (event) => {
const ownerField = 'owner'; // Default owner field when using allow: owner
const identityClaim = 'sub'; // Cognito uses 'sub' for user identification by default
// Define the query condition to find items owned by the user
var condition = {
[ownerField]: {
ComparisonOperator: 'EQ',
AttributeValueList: [event.identity.claims[identityClaim]]
},
'_deleted': {
ComparisonOperator: 'NE',
AttributeValueList: [true]
}
};
await new Promise(async (res) => {
let LastEvaluatedKey;
do {
let queryParams = {
TableName: tableName,
ScanFilter: condition,
ExclusiveStartKey: LastEvaluatedKey
};
const items = await new Promise(resolve => {
dynamodb.scan(queryParams, (err, data) => {
if (err) {
console.log({ error: 'Could not load items: ' + err });
resolve([]);
} else {
LastEvaluatedKey = data.LastEvaluatedKey;
resolve(data.Items);
}
});
});
const dateNow = new Date();
if (items.length > 0) {
let deleteParams = {
RequestItems: {
[tableName]: items.map(item => {
return {
PutRequest: {
Item: {
...item,
_deleted: true,
_ttl: Math.floor(dateNow.getTime() / 1000) + THIRTY_DAYS_IN_SECONDS,
_version: item._version + 1,
_lastChangedAt: dateNow.getTime(),
updatedAt: dateNow.toISOString(),
}
}
};
})
}
};
await new Promise(resolve => {
dynamodb.batchWrite(deleteParams, (err, data) => {
if (err) {
console.log({ error: 'Could not delete items: ' + err });
}
resolve();
});
});
}
} while (LastEvaluatedKey);
res();
});
return true;
};
Any idea?
Before opening, please confirm:
JavaScript Framework
React Native
Amplify APIs
Authentication, GraphQL API, DataStore
Amplify Version
v6
Amplify Categories
auth, storage, function, api
Backend
Amplify CLI
Environment information
Describe the bug
Getting error "Not Authorized to access deleteUserData on type Mutation" for cleaning up user data when following user data cleanup instructions as described here: Steps for cleaning user data for owner based auth schema
schema.graphql
deleteUserData lambda function
calling deleteUserData
Expected behavior
Expecting the
deleteUserData
function to be successfully calledReproduction steps
deleteUserData
as shown in Describe the bug section above.Code Snippet
Log output
aws-exports.js
No response
Manual configuration
Additional configuration
No response
Mobile Device
No response
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Additional information and screenshots
No response