How can I create a simple secure login system without registration? - javascript

I am trying to create a simple login system on my website which does not require any registration process. I will be setting the username and password for each client to use.
Basically, the idea is to have a login page that allows clients to access and view files and information (instead of using email).
The problem with the code below is that the 'username' and 'password' are hardcoded i.e easily viewed with the 'inspect element' feature.
Since I am a newbie, I was wondering if I can create a simple secure system without making use of database and php.
HTML:
<form name="login" class="form">
<p class="title">Client Dashboard</p>
<p class="login-description">This dashboard allows you to manage your project and files</p>
<input type="text" name="userid" placeholder="Username" class="text-field"/>
<input type="password" name="pswrd" placeholder="Password" class="text-field"/>
<input type="submit" class="button" onclick="check(this.form)" value="Login"/>
</form>
Javascript:
function check(form) { /*function to check userid & password*/
/*the following code checkes whether the entered userid and password are matching*/
if(form.userid.value == "johnsmith" && form.pswrd.value == "password123") {
window.open('dashboard.html')/*opens the target page while Id & password matches*/
}
else {
alert("Error Password or Username")/*displays error message*/
}
}

Although this is dangerous for client side code to have login credentials, you can store user info in Array of objects then check if the array has those values.
var users = [{
username: 'admin',
password: 'abc123'
},{
username: 'user1',
password: '321cba'
}];
var index = users.indexof(function (user) {
return users.username === user.username &&
users.password === user.password;
})
if (index !== -1) {
window.open('dashboard.html')/*opens the target page while Id & password matches*/
}
else {
alert("Error Password or Username"
)/*displays error message*/

Related

v-model on input returning input element instead of value

I am attempting to set up user login and role authentication with Vue, without using Vuex, as it's a bit much for the scope of our application. After a failed initial attempt to use jQuery AJAX outside of Vue, I resigned myself to making it work with Vue's data-oriented model, which I've been struggling with (I'm a designer by trade, not really a developer). My backend developer is writing in plain PHP and using mySQL, for reference.
Taking inspiration from this tutorial, I am trying to use v-model to send the form data to the server via axios.
Template:
<form class="login-form" id="loginform" #submit.prevent="login">
<div class="form-group space">
<label class="float-label" for="username">Username</label>
<input v-model="username" type="username" id="username" class="form-control" placeholder="username">
</div>
<div class="form-group">
<label class="float-label" for="username">Password</label>
<input v-model="password" type="password" id="password" class="form-control" placeholder="password">
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary float-right" id="login">Log in</button>
</div>
</form>
Script:
export default {
name: 'Login',
data () {
return {
username: '',
password: ''
}
},
methods: {
login: function () {
const loginInfo = { username, password }
console.log(loginInfo)
new Promise ((resolve, reject) => {
axios({url: 'api.com/index.php', data: loginInfo, method: 'POST' })
.then(resp => {
const token = resp.data.token
localStorage.setItem('user_token', token) // store the token in localstorage
const employeeId = resp.data.employee_id
localStorage.setItem('employee_id', employeeId) // store the id in localstorage
resolve(resp)
console.log(resp);
})
.catch(err => {
localStorage.removeItem('user_token') // if the request fails, remove any possible user token if possible
reject(err)
})
})
// myLoginRoutine(loginInfo).then(() => {
// this.$router.push('/')
// })
}
}
}
The request was going through no problem, but wasn't returning anything! I decided to check and see what I was sending him... and lo and behold, const loginInfo was not the input value, as expected, but {username: input#username.form-control, password: input#password.form-control}
I am, quite frankly, very confused. I've used v-model previously on form inputs with no issues, and have no clue why this is happening or how to fix it. Any thoughts?
For future visitors: The axios data expects an object with those keys for the backend, but you don't fill the object properly.
Change
const loginInfo = { username, password }
to
const loginInfo = { username: this.username, password: this.password }

Vuejs: Show error messages as popups

I have created a login section using Vuex and Axios to authenticate the login by allowing the user to enter the email and password. I have created and stored the variables I need by using a getter. I have also, placed the tokens I needed into a function, post url and console.
But, know I need to show the responses according to the tokens being seen in the inspector/console.
What I need is to show the error messages when the user tries to login. So, when the console responds showing 200 (email and password is correct) I need it to store that token, when the console responds showing 400 (incorrect/missing characters in either email or password) I need it to print out the error messages that I have already placed with an array, lastly, when the console responds showing 401 (both email and password incorrect) I need it to print out the messageFour that is in the array.
HTML:
<template>
<form>
<div class="login">
<div>
<input type="text" v-model="email" placeholder="Email" class="eSection" id="email">
<p v-for="message in errorM" :key="message.errorM" v-show="message in errorM">
{{ message }}
</p>
<input type="password" v-model="password" placeholder="Password" class="pSection" id="password">
<p v-for="message in errorM" :key="message.errorM">
{{message}}
</p>
<button type="button" class="log" #click="login">LogIn</button>
</div>
</div>
</form>
</template>
Javascript:
<script>
import axios from 'axios';
export default {
data() {
return {
email: "test#gmail.com",
password: "123456",
flag: false,
errorM:[],
errorMessages: [
{
messageOne: "The email that has been entered is incorrect. Please try again!"
},
{
messageTwo: "Email/Password is missing. Please try again!"
},
{
messageThree: "The password that has been entered is incorrect. Please try again!"
},
{
messageFour: "Both Email and Password that have been entered are incorrect!"
},
]
}
},
methods: {
login: function (index) {
axios.post(`https://api.ticket.co/auth/login`, {
email: this.email,
password: this.password
})
.then(response => {
// JSON responses are automatically parsed.
console.log(response.data)
console.log(response.status)
})
.catch(e => {
console.log(e)
console.log(e.response.status)
var vueObject = this
switch (e.response.status) {
case 400:
if(!vueObject.email || !vueObject.password){
vueObject.errorM.push(vueObject.errorMessages.messageTwo)
};
if(!vueObject.email){
vueObject.errorM.push(vueObject.errorMessages.messageOne)
};
if(!vueObject.password){
vueObject.errorM.push(vueObject.errorMessages.messageThree)
};
break;
case 401:
if(vueObject.email && vueObject.password == ""){
vueObject.errorM.push(vueObject.errorMessages.messageFour)
}
break;
}
})
},
},
}
</script>
Many thanks!
It's not clear from the description what's not working, so I'll just point out some issues I see.
One thing to mention is, there is no evidence of you using vuex, no getters, no setters, no state.
Most notable is that you have the messages defined as an array of objects, which makes it difficult to look up
instead of this, which is harder to look up:
errorMessages: [
{
messageOne: "The email that has been entered is incorrect. Please try again!"
},
// etc... {}, {}, {}
]
... you should do
errorMessages: {
messageOne: "The email that has been entered is incorrect. Please try again!",
messageTwo: "Email/Password is missing. Please try again!",
messageThree: "The password that has been entered is incorrect. Please try again!",
messageFour: "Both Email and Password that have been entered are incorrect!",
}
so that you can find a message using this.errorMessages.messageTwo
Or better yet, define it outside of your vue component, since you're not using them in your template
const MESSAGE_INCORRECTEMAIL = "The email that has been entered is incorrect. Please try again!";
const MESSAGE_MISSINGFIELD = "Email/Password is missing. Please try again!";
const MESSAGE_INCORRECTPASSWORD = "The password that has been entered is incorrect. Please try again!";
const MESSAGE_INCORRECTEMAILPASSWORD = "Both Email and Password that have been entered are incorrect!";
and then just call them as MESSAGE_MISSINGFIELD from your script
From security standpoint, it's a bad idea to indicate whether the username or the password is wrong, as it makes hacking easier by confirming what usernames exist.
You can determine if the user had errors or fields are missing before sending the form for remote processing.
to do that, you would call
login: function (index) {
if (this.email.trim() === '' || vueObject.password.trim() === ''){
this.errorM.push(MESSAGE_MISSINGFIELD);
return // <- prevents further execution
}
// repeat for other local validations before remote request
// ... then process request
axios.post(`https://api.ticket.co/auth/login`, {
anyway, you might also need t break your question up into individual errors you encounter.

Firebase: Email verification and user login to be able to access the page

I have created a form "main.html#!/register" to allow users to enter their: firstname, lastname, email and login. Once all those entered an email verification is sent, so that they cannot get to the page "main.html#!/success" before verifying the email.
The good news is: If they try to get to the access page from the login page without confirming the Email, they will not be able to access.
The bad news is: Right after the registration, if they enter the "main.html#!/success" they will be able to open this page !!
Use case:
The user is not able to access to "main.html#!/success" without any registration
The user is not able to access the "main.html#!/success" from the login page "main.html#!/login", if he has not verified his email
The problem is : The user is able to access the "main.html#!/success" right after the registration without email confirmation.
Question:
How can I use the email verification condition user.emailVerified and the user auth $requireSignIn() to allow the access to the page "main.html#!/success" ?
I had put a resolve function to prevent any access without the registration.
Here is my codes
1-resolve function:
Authentication is a service I have created
when('/success', {
templateUrl: 'views/success.html',
controller: 'SuccessController',
resolve: {
currentAuth: function(Authentication) {
return Authentication.requireAuth();
} //currentAuth
}//resolve
}).
2-code in the Authentication service
requireAuth: function() {
return auth.$requireSignIn();
}, //require Authentication
3- the register function (it is in the service)
register: function(user) {
auth.$createUserWithEmailAndPassword(
user.email,
user.password
).then(function(regUser) {
var regRef = ref.child('users')
.child(regUser.uid).set({
date: firebase.database.ServerValue.TIMESTAMP,
regUser: regUser.uid,
firstname: user.firstname,
lastname: user.lastname,
email: user.email
}); //userinfo
regUser.sendEmailVerification().then(function() {
// Email sent.
alert("your Email is verified: " + regUser.emailVerified) ;
}).catch(function(error) {
// An error happened.
alert(error);
});
}).catch(function(error) {
$rootScope.message = error.message;
}); //createUserWithEmailAndPassword
} //register
3- login function
login: function(user) {
auth.$signInWithEmailAndPassword(
user.email,
user.password
).then(function(user) {
if(user.emailVerified){
$location.path('/success');
}
else{
$rootScope.message= "Please validate your registration first : "+user.emailVerified;
}
}).catch(function(error) {
$rootScope.message = error.message;
}); //signInWithEmailAndPassword
}, //login
You are trying to enforce this on the client side. Instead you should enforce access for verified signed in users from your Firebase rules. For example:
".write": "$user_id === auth.uid && auth.token.email_verified == true"

Email address is invalid response from campaign monitor api in meteor js

I am having trouble in a meteor project. I am trying to add a email address to a subscriber list using the campaign monitor api. I am using a npm package called createsend-node, it is a wrapper of the api. I have successfully added a subscriber to a list using the api, however when I try to fire a meteor server method from a form submit event the api kicks back a email address not valid response code 1. I will include my code below. When I added the subscriber manually without the method it is successful. The email address was a string when I passed it manually, which is the same for the method. Code Below.
html
<template name="info">
<h2>Signup For Our Newsletter</h2>
<form id="cm-subscribe">
<input field name="email" type="email" value="email">
<input field name="name" type="text" value="name">
<input type="submit">
</form>
</template>
Client side js
Template.info.events({
'submit #cm-subscribe'(event){
event.preventDefault();
var form = event.target;
var email = form.email.value;
var name = form.name.value;
console.log(email + " / " + name);
Meteor.call('addSub', email, name);
}
});
Server side js
Meteor.methods({
addSub: function (name, email) {
console.log(name);
console.log(email);
var listId = 'someid' // The ID of the list
var details = {
EmailAddress: email,
Name: name,
CustomFields: [
{ Key: 'CustomKey', Value: 'Some Value' }
]
};
api.subscribers.addSubscriber(listId, details, (err, res) => {
if (err) console.log(err);
});
}
});
You've reversed the arguments between the caller and the method.
Meteor.call('addSub', email, name)
Meteor.methods({
addSub: function (name, email) {

Meteor.users.update() does not work on logout + login

I have a user profile view where users can edit their profile information. Everything below works great and the update is successful. However, when I logout of the account and login with a different user account, the update fails and returns an Access denied error. It isn't until I refresh the page that I can edit the profile information again with the second account.
I know this case is very rare and a user would not normally be logging out of one account, logging in with another and trying to update their profile but I would like to better understand why this is happening. Is the client token not flushed when a user logs out or is there something else that's being preserved that requires a complete reload of the page?
On client JS:
Template.user_profile_form.events({
'click #submit_profile_btn': function(evt) {
evt.preventDefault();
var first_name = $('#profile_first_name').val()
,last_name = $('#profile_last_name').val()
,email = $('#profile_email').val()
,email_lower_case = email.toLowerCase()
,gravatar_hash = CryptoJS.MD5(email_lower_case)
;
gravatar_hash = gravatar_hash.toString(CryptoJS.enc.Hex);
// TODO need to create user sessions so that when you log out and log back in, you have a fresh session
Meteor.users.update({_id: this.userId }, {
$set: {
profile: {
first_name: first_name,
last_name: last_name,
gravatar_hash: gravatar_hash
}
}
}, function(error) {
if (!error) {
Session.set('profile_edit', 'success');
Meteor.setTimeout(function() {
Session.set('profile_edit', null);
}, 3000);
} else {
Session.set('profile_edit', 'error');
Template.user_profile_form.error_message = function() {
return error.reason;
};
}
});
Meteor.call('changeEmail', email);
}
});
The server JS:
Meteor.publish('list-all-users', function () {
return Meteor.users.find({_id: this.userId }, {
fields: {
profile: 1,
emails: 1
}
});
});
Meteor.methods({
sendEmail: function(to, from, subject, text) {
this.unblock();
Email.send({
to: to,
from: from,
subject: subject,
text: text
});
},
changeEmail: function(newEmail) {
// TODO Need to validate that new e-mail does not already exist
Meteor.users.update(Meteor.userId(), {
$set: {
emails: [{
address: newEmail,
verified: false
}]
}
});
}
});
The template:
<template name="user_profile_form">
<h2>Update Profile</h2>
<div id="profile-form">
{{#if success}}
<div class="alert alert-success">
<strong>Profile updated!</strong> Your profile has been successfully updated.
</div>
{{/if}}
{{#if error}}
<div class="alert alert-error">
<strong>Uh oh!</strong> Something went wrong and your profile was not updated. {{error_message}}.
</div>
{{/if}}
<p>
{{#each profile}}
<input type="text" id="profile_first_name" placeholder="First Name" value="{{first_name}}">
<input type="text" id="profile_last_name" placeholder="Last Name" value="{{last_name}}">
{{/each}}
<input type="email" id="profile_email" placeholder="Email" value="{{email_address}}">
</p>
</div>
<div id="submit-btn">
<input type="submit" id="submit_profile_btn" class="btn btn-primary">
</div>
</template>
The Meteor logout function does almost nothing. It certainly does not tear down Session state or the rest of your app's context. Your code must reset these variables during your app's logout event. A manual refresh of the page causes the client side JavaScript to reload wiping out existing Session data.
If you don't want to mess with the accounts-ui template internals you can use the following pattern (CoffeeScript code) to clear individual variables from the Session:
Deps.autorun (c) ->
user = Meteor.user()
if user
# Setup code on login (if required)
else if not user
# Clear session on logout
Session.set "profile_edit", undefined

Categories

Resources