Angular AWS Cognito Force Change password - javascript

I am creating a Cognito user from the AWS Console. I am asked to change the password at first login. I want to prompt up a new page or hide a div in the login page to allow the user to pass the new password . Could you please help me how to prompt the new password page with the below code
login.tml
<div class="login">
<div>
<form class="login-form"
[formGroup]="loginForm"
(ngSubmit)="onLogin()" >
<div >
<div fxFlexFill>
<mat-form-field >
<input
type="email"
matInput
placeholder="Your email"
formControlName="email">
<mat-error>Invalid or missing email.</mat-error>
</mat-form-field>
</div>
</div>
<div >
<div >
<mat-form-field >
<input
type="password"
matInput
placeholder="password"
formControlName="password">
<mat-error>Missing password.</mat-error>
</mat-form-field>
</div>
</div>
Login.ts
export class Login implements OnInit {
constructor(private example:ExampleService,
private _router: Router) {
}
onLogin() {
const email=this.loginForm.get('email').value
const password=this.loginForm.get('password').value
this.example.LogIn(email, password).subscribe((data) => {
this._router.navigate(['/home']);
}, (err)=> {
});
}
ExampleService.ts
LogIn(email, password) {
return Observable.create(observ => {
cognitoUser.authenticateUser(authenticationDetails, {
newPasswordRequired: function(userAttributes, requiredAttributes) {
//How do I prompt a new password page from here and collect the form
value
and pass the value on below password paramaters
const email1={
email:email
};
cognitoUser.completeNewPasswordChallenge(password, email1, this)
},
onSuccess: function (result) {
observ.next(result);
observ.complete();
},
onFailure: function(err) {
console.log(err);
observ.error(err);
},
});
});
}
don't know how do I verify the user is a first time user or not. If It is a first-time user how do I show a new page within a call back function(newPasswordRequired: function()).

Related

Can't figure out how to make a function for creating new users into the database

I am new to working with databases. I've been trying to create a login/register webpage using only HTML, Js and MongoDB in my codes in order to practice. I have successfully made a function for login, yet I've been struggling to create a function for registering using the Fetch API.
I am aware that my register code is used rather for a login function, but I used it as a template for the sign up one.
I'd appreciate it if anyone can help me fix the register function using Fetch() in order to not give me 401 and to be able to add the new user's email and password to my database. Thank you.
const btnAccount = document.querySelector('.account .submit')
btnAccount.addEventListener('click', event => {
event.preventDefault()
const email = emailAccount.value
const pass = passAccount.value
const pass2 = pass2Account.value
if (email && pass && pass2) {
if (pass === pass2) {
// The data i wish to add to my mongoDB users database:
const account = {
strategy: "local",
email : emailAccount.value,
password: passAccount.value
}
fetch('http://localhost:3030/authentication', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(account)
}).then(response => {
return response.json()
}).then(result => {
console.log(result)
document.forms[1].reset();
})
.catch(err => {
// If I got some errors regardings the DB or in the code itself:
console.log('eroare:', err)
alert(`Something's wrong. I can feel it!`)
})
}
else {
// Passwords not the same:
alert('Parolele nu coincid!')
}
}
else {
// Not all fields written:
alert('Completeaza bah campurile...')
}
})
<main>
<form class="account">
<div>
<label for="email">Email:</label>
<input required type="email">
</div>
<div>
<label for="password">Password:</label>
<input required type="password" class="password">
</div>
<div>
<label for="password2">Verify Password:</label>
<input type="password" class="password2">
</div>
<div>
<button class="submit">Create new account</button>
</div>
<div>
I already have an account
</div>
</form>
<button class="fetchItems">Load ITEMS</button>
<div class="output"></div>
</main>

Firestore won't add signup email to new database collection

When signing up a user, I get no error what so ever, the signup works, but it doesn't create a new DB collection with the signup email.
Furthermore, redirecting the user to /account/dashboard.html doesn't work.
Any ideas? I am very new to all of this, only 4 days in so if you could please explain things a little simpler to me that would be very much appreciated.
// sign up the user
firebase.auth().createUserWithEmailAndPassword(email, password).then(cred => {
return db.collection('users').doc(cred.user.uid).set({
email: "signupForm['signupEmail'].value"
});
}).then(function() {
window.location.replace('/account/dashboard.html');
})
.catch(function (error) {
var errorCode = error.code;
var errorMessage = error.message;
console.log('Error code: ' + errorCode);
console.log('Error message: ' + errorMessage);
signupButton.style.display = 'flex';
signupError.innerText = errorMessage;
signupError.style.display = 'flex';
signupForm.reset();
});
})
// Trigger button click on enter
var input = document.getElementById("signupPasswordConfirm");
// Execute a function when the user releases a key on the keyboard
input.addEventListener("keyup", function(event) {
// Number 13 is the "Enter" key on the keyboard
if (event.keyCode === 13) {
// Trigger the button element with a click
document.getElementById("signupButton").click();
}
});
My HTML
<div class="form-content"><label for="signupPassword-2" id="signupError" class="error-message">Error message</label>
<div class="form-wrap extra-space"><input type="text" class="text-field w-input" maxlength="256" name="signupEmail" data-name="signupEmail" placeholder="E-mail" id="signupEmail"></div>
<div class="form-wrap extra-space"><input type="password" class="text-field w-input" maxlength="256" name="signupPassword" data-name="signupPassword" placeholder="Password" id="signupPassword"></div>
<div class="form-wrap extra-space"><input type="password" class="text-field w-input" maxlength="256" name="signupPasswordConfirm" data-name="signupPasswordConfirm" placeholder="Confirm your Password" id="signupPasswordConfirm"></div>
<div class="button-wrap"><a id="signupButton" href="#" class="button w-button">Signup</a>
<h5 class="h5 black centered">Already have an account?</h5>
</div>
Turns out I forgot to declare the DB variable. Also changed the output of email:
// sign up the user
const db = firebase.firestore();
firebase.auth().createUserWithEmailAndPassword(email, password).then(cred => {
return db.collection('users').doc(cred.user.uid).set({
email: signupForm['signupEmail'].value
});

Now to pass form values from React to Node server

I have an EmailList component in react with a form that calls EmailServer.js 'NodeMailer' on the server. I am able to send emails with test subject and message defined in the MailServer.js file statically. How can I pass the subject and message as state to be used in NodeMailer.
EmailList Component
var EmailList = React.createClass({
getInitialState() {
return {
subject: '',
message: ''
}
},
subjectChange(e) {
this.setState({subject: e.target.value})
},
messageChange(e) {
this.setState({message: e.target.value})
},
render() {
return (
<div>
<div>
<Breadcrumb title={this.props.route.title + ' - ' + this.props.location.state.title} />
</div>
<div className='ui-outer'>
<h2 className='text-center'>Email List</h2>
<form action='../EmailServer.js'>
<div className="form-group">
<label htmlFor="subject">Subject</label>
<input type="text" name="subject" className="form-control" onChange={this.subjectChange} value={this.state.subject} />
</div>
<div className="form-group">
<label htmlFor="message">Message</label>
<textarea rows="8" name="message" className="form-control" onChange={this.messageChange} value={this.state.message} />
</div>
<button type="submit" className="btn btn-success">Submit</button>
</form>
</div>
</div>
)
}
})
EmailServer.js
var nodemailer = require('nodemailer');
// Create reusable transporter object using the default SMTP transport
var transporter = nodemailer.createTransport('smtps://user%40gmail.com:pass#smtp.gmail.com');
// Setup e-mail data with unicode symbols
var mailOptions = {
from: 'em#il.com',
to: 'test#email.com',
subject: 'Hello', // <----Pass Subject State HERE
text: 'Hello World', // <-----Pass Message state HERE
html: '<b>Hello World</b>' // <-----Pass Message State HERE
};
// Send email with defined transport object
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
return console.log(error);
}
console.log('Message Sent: ' + info.response);
});
If i got your issue correct, there might be a number of issues here.
You might want to design your code on server side to handle email sending with nodejs express server requested from client.
app.get('/sendemail', function(req, res) {here you go and read request posted data/json})
Where app is nodejs express server instance.
Let react handler to submit a request with one of async http clients (like axios or jquery).
sendEmail: function(e){
e.preventDefault();
$.post(
"/sendemail",{
email: this.state.email,
password: this.state.password,
first_name: this.state.first_name,
last_name: this.state.last_name
}, function(result){
//track result here
});
}
Set form to be submitted with react function:
<form onSubmit={this.sendEmail} >...</form>

User Data is not inserting into mongodb using Node API

I am creating a Restful API on Node.js and storing data into Mongodb. and working on user registration API.
app.js
apiRoutes.post('/signup', function(req, res) {
if (!req.body.name || !req.body.password) {
res.json({success: false, msg: 'Please pass Name and Password.'});
} else {
var newUser = new User({
name:req.body.name,
password:req.body.password
});
console.log(req.body.name);
// save the user
newUser.save(function(err, data) {
if (err) {
return res.json({success: false, msg: 'Username already exists.'});
}else{
console.log(data);
res.json({success: true, msg: 'Successful created new user.'});}
});
}
});
Consuming API using Angular.js
//factory for user register
app.factory('RegistrationFactory', function($resource){
return $resource('/api/signup/:id',{id:'#_id'},{update:{method:'PUT'}});
});
//controller for registration
app.controller('registerCtrl', function($scope, RegistrationFactory, $location){
$scope.regUser=new RegistrationFactory();
$scope.register=function(){
console.log($scope.newUser);
$scope.regUser.$save(function(){
console.log("User Registerd");
});
} ;
})
register.html
<div class="post" ng-controller="registerCtrl">
<form method="post">
<div class="form-group">
<label>Name</label>
<input type="text" class="form-control" name="name" ng-model="newUser.name" />
</div>
<div class="form-group">
<label>Password</label>
<input type="text" class="form-control" name="password" ng-model="newUser.password"/>
</div>
<div class="form-group">
<button class="btn btn-success" ng-click="register()">Register</button>
</div>
</form>
</div>
So, My problem is that, this API is working fine on POSTMAN but its not working on my HTML form. Please review my code. Whenever I click on Register button its seems like that on button click API is not hitting. nothing is happening.
Please review my code and suggest me solution.
Thanks.
from angular controller you are not passing the newUser object to $resource or regUser change the controller code to below
//controller for registration
app.controller('registerCtrl', function($scope, RegistrationFactory, $location){
$scope.register=function(){
console.log($scope.newUser);
$scope.regUser=new RegistrationFactory($scope.newUser);
$scope.regUser.$save(function(){
console.log("User Registerd");
});
} ;
})

Roles - Parse.com Javascript

At the moment I have javascript that allows all users from the (_User) table to log in. I have set up a Role called (Admins) within the role table and assigned one user to this role. Would this be an if statement?
At the moment this is how the user logs in successfully
$scope.logIn = function(form) {
Parse.User.logIn(form.username, form.password, {
success: function(user) {
$scope.currentUser = user;
$scope.$apply();
window.location.href = "TEST.html";
},
It's easy to check whether any user belongs to a role. The only tricky part is to realize that the check includes a query, and is therefore an asynchronous operation. So first, a general purpose role checking function:
function userHasRole(user, roleName) {
var query = new Parse.Query(Parse.Role);
query.equalTo("name", roleName);
query.equalTo("users", user);
return query.find().then(function(roles) {
return roles.length > 0;
});
}
This returns a promise that will be fulfilled with a boolean, so you can call it like this:
var currentUser = Parse.User.current();
// is the user an "admin"?
userHasRole(currentUser, "admin").then(function(isAdmin) {
console.log((isAdmin)? "user is admin" : "user is not admin");
});
Apply it like this in your code. In the view:
<form role="form" name="loginForm">
<div class="form-group">
<label>Email</label>
<input type="email" class="form-control" name="email" ng-model="user.username" />
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" name="password" ng-model="user.password" />
</div>
<div class="form-group">
<button class="btn btn-ar btn-primary" ng-click="pressedLogIn()">Log in</button>
</div>
</form>
And in the controller:
(function() {
'use strict';
angular.module('myApp.controllers').controller('LogInController', LogInController);
LogInController.$inject = ['$scope'];
function LogInController($scope) {
$scope.user = { username:"", password:""};
function userHasRole(user, roleName) {
// defined exactly as above
// my real app has a user service, and this would be better placed there
}
$scope.pressedLogIn = function() {
if ($scope.loginForm.$valid) {
Parse.User.logIn($scope.user.username, $scope.user.password).then(function(user) {
$scope.user = user;
return userHasRole(user, "administrator");
}).then(function(isAdmin) {
alert("user is admin = " + isAdmin);
}, function(e) {
alert(error.message);
});
}
};
}
})();

Categories