const AWS = require("aws-sdk");
const {
CognitoIdentityProvider,
AdminCreateUserCommand,
CreateUserPoolClientCommand,
ListUsersCommand,
AdminSetUserPasswordCommand,
InitiateAuthCommand,
} = require("@aws-sdk/client-cognito-identity-provider");
const dotenv = require("dotenv");
const crypto = require('crypto');
dotenv.config();
const AWS_COGNITO_KEY = process.env.ACCESS_KEY_ID;
const AWS_COGNITO_SECRET = process.env.SECRET_ACCESS_KEY;
const COGNITO_REGION = process.env.COGNITO_REGION;
AWS.config.update({
accessKeyId: AWS_COGNITO_KEY,
secretAccessKey: AWS_COGNITO_SECRET,
region: COGNITO_REGION,
});
const cognitoISP = new CognitoIdentityProvider({ region: COGNITO_REGION });
const userPoolConfig = {
Policies: {
PasswordPolicy: {
MinimumLength: 8,
RequireUppercase: true,
RequireLowercase: true,
RequireNumbers: true,
RequireSymbols: true,
TemporaryPasswordValidityDays: 7,
},
},
UsernameAttributes: ['email'],
UsernameConfiguration: {
CaseSensitive: false,
},
DeletionProtection: 'ACTIVE',
MfaConfiguration: 'OFF',
AdminCreateUserConfig: {
AllowAdminCreateUserOnly: true,
},
EmailConfiguration: {
EmailSendingAccount: 'COGNITO_DEFAULT', // Disable automatic email sending or 'DEVELOPER', with ARN SourceArn: 'your-source-arn'
// SourceArn: 'arn:aws:ses:ap-south-1:929476570592:identity/dummy@example.com'
},
Schema: [
{
AttributeDataType: 'String',
DeveloperOnlyAttribute: false,
Mutable: false,
Name: 'sub',
Required: true,
StringAttributeConstraints: {
MaxLength: '200',
MinLength: '1',
},
},
{
AttributeDataType: 'String',
DeveloperOnlyAttribute: false,
Mutable: true,
Name: 'name',
Required: false,
StringAttributeConstraints: {
MaxLength: '35',
MinLength: '0',
},
},
{
AttributeDataType: 'String',
DeveloperOnlyAttribute: false,
Mutable: true,
Name: 'email',
Required: false,
StringAttributeConstraints: {
MaxLength: '200',
MinLength: '0',
},
},
{
AttributeDataType: 'String',
DeveloperOnlyAttribute: false,
Mutable: true,
Name: 'phone_number',
Required: false,
StringAttributeConstraints: {
MaxLength: '2048',
MinLength: '0',
},
},
// Add more custom attributes if needed
],
UserPoolTags: {
// You can add tags here if needed
},
UserPoolAddOns: {
AdvancedSecurityMode: 'ENFORCED', // Enable token revocation and prevent user existence errors
},
};
module.exports.createClientPool = async (params) => {
return new Promise(async (resolve, reject) => {
try {
let userPoolDetails = await createClientPool(params.poolName);
const appClientParams = {
UserPoolId: userPoolDetails.UserPool.Id,
ClientName: params.client_name,
GenerateSecret: true
}
let userPoolClientDetails = await createUserPoolClient(appClientParams);
let poolDetails = {
pool_id: userPoolClientDetails.UserPoolClient.UserPoolId,
pool_name: userPoolDetails.UserPool.Name,
client_name: userPoolClientDetails.UserPoolClient.ClientName,
client_id: userPoolClientDetails.UserPoolClient.ClientId,
client_secret: userPoolClientDetails.UserPoolClient.ClientSecret,
pool_created_at: userPoolDetails.UserPool.CreationDate,
pool_modified_at: userPoolDetails.UserPool.LastModifiedDate,
}
resolve(poolDetails);
} catch (error) {
reject(error);
}
});
}
module.exports.createUserCognitoProfile = async (params) => {
return new Promise(async (resolve, reject) => {
try {
const data = await cognitoISP.send(new AdminCreateUserCommand(params));
resolve(data);
} catch (error) {
console.error('Error signing up:', error);
reject(error);
}
});
}
module.exports.getUserCognitoProfileDetails = async (checkPayload) => {
return new Promise(async (resolve, reject) => {
try {
const data = await cognitoISP.send(new ListUsersCommand(checkPayload));
if (data && data.Users && data.Users.length > 0) {
console.log('User details:', data.Users);
resolve(data);
} else {
reject({ error: 'User not found' });
}
} catch (error) {
console.error('Error fetching user details:', error);
reject(error);
}
});
};
module.exports.generateResetPassword = async (payload) => {
return new Promise(async (resolve, reject) => {
try {
const data = await cognitoISP.send(new AdminSetUserPasswordCommand(payload));
resolve(data);
} catch (error) {
reject(error);
}
});
};
module.exports.signIn = async (payload) => {
return new Promise(async (resolve, reject) => {
const secretHash = generateSecretHash(payload.aws_client_id, payload.aws_client_secret, payload.username);
const params = {
AuthFlow: process.env.AUTH_FLOW,
ClientId: payload.aws_client_id,
AuthParameters: {
USERNAME: payload.username,
PASSWORD: payload.password,
SECRET_HASH: secretHash,
},
};
try {
const data = await cognitoISP.send(new InitiateAuthCommand(params));
resolve(data);
} catch (error) {
reject(error);
}
});
};
function generateSecretHash(CLIENT_ID, CLIENT_SECRET, username) {
const hmac = crypto.createHmac("sha256", CLIENT_SECRET);
hmac.update(username + CLIENT_ID);
return hmac.digest("base64");
}
function createClientPool(poolName) {
return new Promise((resolve, reject) => {
userPoolConfig.PoolName = poolName;
cognitoISP.send(new AdminCreateUserCommand(userPoolConfig), (error, data) => {
if (error) {
console.error('Error creating user pool:', error);
reject(error);
}
resolve(data);
});
});
}
function createUserPoolClient(appClientParams) {
return new Promise((resolve, reject) => {
cognitoISP.send(new CreateUserPoolClientCommand(appClientParams), (error, data) => {
if (error) {
console.error('Error creating app client:', error);
reject(error);
}
resolve(data);
});
});
}
Thanks Michael, I had found the solution and it was related to AWS IAM credentials