CDK Add Policy to Custom Created SES Verified Email - amazon-ses

Using the AWS SDK, I can create an SES verified email address. But how do I create a policy to give SendEmail and SendRawEmail permissions to the email (like in the console)? My understanding is the AwsCustomResource policy attribute gives permissions to the Lambda function creating the resource and NOT to the created resource itself.
const customResource = new cr.AwsCustomResource(this, 'VerifyEmailIdentity', {
onCreate: {
service: 'SES',
action: 'verifyEmailIdentity',
parameters: {
EmailAddress: cognitoEmailAddress,
},
physicalResourceId: cr.PhysicalResourceId.of(`verify-${cognitoEmailAddress}`)
},
onDelete: {
service: 'SES',
action: 'deleteIdentity',
parameters: {
Identity: cognitoEmailAddress
}
},
policy: cr.AwsCustomResourcePolicy.fromStatements([
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['ses:VerifyEmailIdentity', 'ses:DeleteIdentity'],
resources: ['*']
})
])
});

Add the following additional code which calls the SES putIdentityPolicy allowing (for example) the Cognito service to SendEmail and SendRawEmail.
import * as cr from '#aws-cdk/custom-resources';
import * as iam from '#aws-cdk/aws-iam';
const cognitoEmailAddress = 'myemail#mydomain.com';
const cognitoEmailAddressArn = `arn:aws:ses:${myRegion}:${myAccount}:identity/${cognitoEmailAddress}`;
const policy = {
Version: '2008-10-17',
Statement: [
{
Sid: 'stmt1621717794524',
Effect: 'Allow',
Principal: {
Service: 'cognito-idp.amazonaws.com'
},
Action: [
'ses:SendEmail',
'ses:SendRawEmail'
],
Resource: cognitoEmailAddressArn
}
]
};
new cr.AwsCustomResource(this, 'PutIdentityPolicy', {
onCreate: {
service: 'SES',
action: 'putIdentityPolicy',
parameters: {
Identity: cognitoEmailAddress,
Policy: JSON.stringify(policy),
PolicyName: 'CognitoSESEmail'
},
physicalResourceId: cr.PhysicalResourceId.of(`policy-${cognitoEmailAddress}`)
},
onDelete: {
service: 'SES',
action: 'deleteIdentityPolicy',
parameters: {
Identity: cognitoEmailAddress,
PolicyName: 'CognitoSESEmail'
}
},
// There is a policy bug in the CDK for custom resources: https://github.com/aws/aws-cdk/issues/4533
// Use the following policy workaround. https://stackoverflow.com/questions/65886628/verify-ses-email-address-through-cdk
policy: cr.AwsCustomResourcePolicy.fromStatements([
new iam.PolicyStatement({
effect: iam.Effect.ALLOW,
actions: ['ses:PutIdentityPolicy', 'ses:DeleteIdentityPolicy'],
resources: ['*']
})
])
});

Related

How to restrict users for authentication in Adonis.js?

I'd like to restrict users to be authenticated in Adonis.js, specifically to only authenticate users that have their active attribute set to true.
Route.post('login', async ({ auth, request, response }) => {
const { email, password } = request.only(['email', 'password'])
try {
const token = await auth.use('api').attempt(email, password)
return token
} catch {
return response.unauthorized('Invalid credentials')
}
})
I couldn't find a way to hook into the user retrieval by the auth module to add a constraint for active users. What would be a good approach to this?
Auth configuration:
const authConfig: AuthConfig = {
guard: 'api',
guards: {
api: {
driver: 'oat',
tokenProvider: {
type: 'api',
driver: 'database',
table: 'api_tokens',
foreignKey: 'user_id',
},
provider: {
driver: 'lucid',
identifierKey: 'id',
uids: ['email'],
model: () => import('App/Models/User'),
},
},
},
}

Bucketeer persigned links?

I currently use AWS s3's createPresignedPost service to get a url from my server that I can then upload files to directly to from my web app (rather than sending the file to my server).
I am currently looking at moving to Heroku and wondering if Bucketeer will offer me the same options?
const params = {
Bucket: `${config.clusterName}-${config.projectName}-s3`,
Expires: 3600,
Fields: { key: `uploads/${filename}` },
Conditions: [
['content-length-range', 0, 10000000], // 10 Mb
],
}
console.log("calling createPresignedPost")
S3.createPresignedPost(params, (e, data) => {
if (e) return reject(e)
ret = {
hostedUrl,
url: data.url,
fields: {
key: data.fields.key,
bucket: data.fields.bucket,
algorithm: data.fields['X-Amz-Algorithm'],
credential: data.fields['X-Amz-Credential'],
date: data.fields['X-Amz-Date'],
policy: data.fields.Policy,
signature: data.fields['X-Amz-Signature'],
},
}
resolve(ret)
})

How to set session using Nuxt-Auth?

I am trying to use Nuxt/auth, but run into problem with session saving in localStorage.
Login.vue
methods: {
sendLoginLink() {
this.$auth.loginWith('local', {
data: {
username: "test#gmail.com",
password: "testpassword"
}
}).then((date) => {
console.log("data", date)
}).catch((err) => {
console.error("err", err)
})
}
Nuxt.config.js
auth: {
strategies: {
local: {
endpoints: {
login: { url: '/dashboard', method: 'post', propertyName: 'token' }
},
tokenType: ''
}
}
axios: {
baseURL: 'http://localhost:1234'
},
modules: [
'#nuxtjs/axios',
'#nuxtjs/auth-next',
]
When the user logs in, the function sendLoginLink is called and throw error in console:
Which means that the auth-token is so large that it cannot be stored in localStorage, but all other things related to this function are saved in localStorage. For example:
I googled a lot but didn't find a good solution to the problem. For example, I tried to clear all localStorage memory before running sendLoginLink() function but the result is the same. Different browsers have the same problem

Express sessionID changed on every Nuxt Auth request

I'm new to Nuxt Auth and express session, when I perform this.$auth.loginWith('local', { data: '' }), I will set req.session.loggedIn = true in the server, and I can see my req.session.id = 'xxx' for example.
After that, the nuxt auth will make another call to /api/auth/user, but I can see the sessionID has been changed, and req.session.loggedIn was undefined.
How can I maintain the same session for every request?
Below is my config
auth: {
strategies: {
local: {
token: {
required: false,
type: false
},
endpoints: {
login: { url: '/api/auth/login', method: 'POST' },
logout: { url: '/api/auth/logout', method: 'POST' },
user: { url: '/api/auth/user', method: 'get' }
}
}
}
},
I'm using v5
"#nuxtjs/auth-next": "5.0.0-1616003482.75c20e6",

How can I override builtin login method in Loopback?

I've created a new User model, based on builtin one. I'm trying this:
module.exports = function(TiUser) {
TiUser.on('dataSourceAttached', function(obj) {
var login = TiUser.login;
TiUser.login = function(credentials, include, cb) {
var result = login.apply(this, credentials);
// Do my stuff
cb(null, my_data);
};
});
};
But I can't get it working... What is wrong? or how could this be done right?
Thanks
You may want to consider adding an afterRemote() hook to login(). Now you can achieve to add role( using Role model ) to user. For example:
TiUser.afterRemote('login', function(ctx, next) {
//add role to the user.
next();
});
At the end I've created a new method instead of overriding a current one:
module.exports = function(TiUser) {
TiUser.auth = function(credentials, include, fn) {
var self = this;
self.login(credentials, include, function(err, token) {
authInfo = {
token: token
};
fn(err, authInfo);
});
};
TiUser.remoteMethod(
'auth',
{
description: 'Login method with Role data information embedded in return',
accepts: [
{arg: 'credentials', type: 'object', required: true, http: {source: 'body'}},
{arg: 'include', type: ['string'], http: {source: 'query' },
description: 'Related objects to include in the response. ' +
'See the description of return value for more details.'}
],
returns: {
arg: 'accessToken', type: 'object', root: true,
description: 'User Model'
},
http: {verb: 'post'}
}
);
};