Validation of username OR phone number - compare - javascript

I am currently just doing a very simple and basic login system with either a email address or a phone number. No password.
Nothing major to hide, just an information hub.
What i want to achieve:
Check if user entered email exists within users array.
Check if users entered phone exists within users array. Check if both email and phone match the same user.
Check if email is wrong and phone is drop (or vice versa) - it still finds the right user.
Whats currently happening:
It finds the right user if the email is entered in.
If email is entered in wrong and phone number is correct, i get a undefined error.
If both are wrong i get a server error stating email is undefined.
The code:
Users object
const users = [
{
email: "jon#doe.com",
phone: "0798888888",
name: "John Doe",
access: ["home", "blah", "etc"]
},
{
email: "fakedoe#john.com",
phone: "079000000",
name: "Fake Doe",
access: ["home", "etc"]
}
];
Main code:
app.post("/in", async (req, res) => {
let email = req.body.email,
phone = req.body.phone;
let conditions = !!email ? { email } : { phone };
let data = users.find((x) => x.email === conditions.email || x.phone === conditions.phone);
let pass = data.email || data.phone !== undefined;
console.log(pass);
if (pass) {
if (conditions.email && conditions.email === data.email) {
pass = true;
}
if (conditions.phone && conditions.phone === data.phone) {
pass = true;
}
}
if (pass) {
res.cookie("JWT", jwtSign(req.body.email, data.name, data.access));
res.status(200);
res.send("OK");
} else {
res.status(200);
res.send("Invalid user/password");
}
});

login system with either a email address or a phone number
Had to find a way to play around with the code. Here is a working version!
const users = [{
email: "fakedoe#john.com",
phone: "079000000",
name: "Fake Doe",
access: ["home", "etc"]
}
];
function checkUserExists(email, phone) {
return !!users.find((x) => x.email === email || x.phone === phone);
}
console.log(checkUserExists('fakedoe#john.com', '0490')); //email
console.log(checkUserExists('fakedoe#joh.com', '079000000')); //phone
console.log(checkUserExists('fakedoe#john.com', '079000000')); //both
console.log(checkUserExists('fakedoe#joh.com', '0490')); //none
So replace this:
app.post("/in", async (req, res) => {
let email = req.body.email,
phone = req.body.phone;
let conditions = !!email ? { email } : { phone };
let data = users.find((x) => x.email === conditions.email || x.phone === conditions.phone);
let pass = data.email || data.phone !== undefined;
console.log(pass);
if (pass) {
if (conditions.email && conditions.email === data.email) {
pass = true;
}
if (conditions.phone && conditions.phone === data.phone) {
pass = true;
}
}
if (pass) {
res.cookie("JWT", jwtSign(req.body.email, data.name, data.access));
res.status(200);
res.send("OK");
} else {
res.status(200);
res.send("Invalid user/password");
}
});
with this:
function userExists(email, phone) {
return !!users.find((x) => x.email === email || x.phone === phone);
}
app.post("/in", async (req, res) => {
if (userExists(req.body.email, req.body.phone)) {
res.cookie("JWT", jwtSign(req.body.email, data.name, data.access));
res.status(200);
res.send("OK");
} else {
res.status(200);
res.send("Invalid user/password");
}
});

Related

Error: Firebase reCAPTCHA placeholder element must be empty

I am using firebase authentication with phone number, and that requires Recaptcha verification. I had initially used the normal visible recaptcha, and that worked fine, but a need came in to make the recaptcha an invisible one.
I used Firebase's documentations on this and here's my code below:
const generateRecaptcha = () => {
window.recaptchaVerifier = new RecaptchaVerifier(
"signin_btn",
{
size: "invisible",
callback: (response) => {
onSignInSubmit();
},
},
auth
);
};
const onSignInSubmit = async () => {
setLoading(true);
const q = query(doc(db, "users", phone));
const querySnapshot = await getDoc(q);
console.log("Snapshot", querySnapshot.exists());
if (
phone === "" ||
password === "" ||
repeatPassword === "" ||
lastname === "" ||
firstname === ""
) {
setLoading(false);
setErrors("Please fill the needed fields.");
} else if (password !== repeatPassword) {
setErrors("Passwords do not match.");
setLoading(false);
} else if (querySnapshot.exists()) {
setErrors(
"This phone number already exists on the server. Please try another number."
);
setLoading(false);
} else {
setErrors("Complete ReCaptcha to get verification code");
generateRecaptcha();
let appVerifier = window.recaptchaVerifier;
console.log("Did we get here?");
signInWithPhoneNumber(auth, phone, appVerifier)
.then((confirmationResult) => {
console.log("We got here..!!");
window.confirmationResult = confirmationResult;
setLoading(false);
})
.catch((err) => {
console.error(err);
});
}
};
I end up getting this error though
Please I need help on this issue.

Error in uploading marks Expected string but received array

I have a school management project, and in the "UploadMarks" tab, when I click on the button to send the form with the students attendance, the error "Error in uploading marks Expected string but received array", I've heard that it's a problem with lib validator for validations, but I canĀ“t resolve this error.
uploadMarks:
const Validator = require('validator');
const isEmpty = require('./is-empty');
const validateFacultyUploadMarks = (data) => {
let errors = {}
data.subjectCode = !isEmpty(data.subjectCode) ? data.subjectCode : '';
data.exam = !isEmpty(data.exam) ? data.exam : '';
data.totalMarks = !isEmpty(data.totalMarks) ? data.totalMarks : '';
if (Validator.isEmpty(data.subjectCode)) {
errors.subjectCode = 'Subject Code field is required';
}
if (Validator.isEmpty(data.exam)) {
errors.exam = 'Exam field is required';
}
if (Validator.isEmpty(data.totalMarks)) {
errors.totalMarks = 'Total marks field is required';
}
return {
errors,
isValid: isEmpty(errors)
};
}
module.exports = validateFacultyUploadMarks
teacherController:
uploadMarks: async (req, res, next) => {
try {
const { errors, isValid } = validateFacultyUploadMarks(req.body);
// Check Validation
if (!isValid) {
return res.status(400).json(errors);
}
const {exam, totalMarks, marks, department, year } = req.body
const isAlready = await Mark.find({ exam, department})
if (isAlready.length !== 0) {
errors.exam = "You have already uploaded marks of given exam"
return res.status(400).json(errors);
}
for (var i = 0; i < marks.length; i++) {
const newMarks = await new Mark({
student: marks[i]._id,
exam,
department,
marks: marks[i].value,
totalMarks
})
await newMarks.save()
}
res.status(200).json({message:"Marks uploaded successfully"})
}
catch (err) {
console.log("Error in uploading marks",err.message)
}
},
is-Empty:
const isEmpty = value =>
value === undefined ||
value === null ||
(typeof value === 'object' && Object.keys(value).length === 0) ||
(typeof value === 'string' && value.trim().length === 0);
module.exports = isEmpty;

Twitch bot multiple channels but message only at 1

So my bot is connected to 3 channels and if all 3 channels are online how can bot only work on First channel if he's going offline so swap to next channel
const tmi = require('tmi.js'),
{ channel, username, password } = require('./settings.json');
const options = {
options: { debug: true },
connection: {
reconnect: true,
secure: true
},
identity : {
username,
password
},
channels: [
'#Pok1',
'#Pok2',
'#Pok3',
]
};
const client = new tmi.Client(options);
client.connect().catch(console.error);
client.on('connected', () => {
client.say(channel, ``);
});
client.on('message', (channel, user, message, self) => {
if(self) return;
if(user.username == 'asd' && message === "zxc") {
client.say(channel, 'abc');
}
});
To say something in a channel you use client.say(channel, message);.
So if you only want to say something in only one channel, you would have to save the channel somewhere:
const TALK_CHANNEL = '#Pok_X';
client.on('message', (channel, user, message, self) => {
if(self) return;
if(user.username == 'asd' && message === "zxc") {
client.say(TALK_CHANNEL, 'abc');
}
Handling the channel swapping would look like this:
const USERNAME = 'asd';
const CHANNELS = ['#pok1', '#pok2', '#pok3', ];
let current_channel = null;
let last_joined_channel = null;
// From docs:
// Username has joined a channel. Not available on large channels and is also sent in batch every 30-60secs.
client.on("join", (channel, username, self) => {
if (username != USERNAME || !CHANNELS.includes(channel))
return;
last_joined_channel = channel;
if (current_channel === null)
current_channel = channel;
});
// user left a channel
client.on("part", (channel, username, self) => {
if (username != USERNAME || !CHANNELS.includes(channel))
return;
current_channel = last_joined_channel;
last_joined_channel = null;
});
client.on('message', (channel, user, message, self) => {
if(self)
return;
if(user.username == USERNAME && message === "zxc" && current_channel != null) {
client.say(current_channel, 'abc');
}

Close Modal Only When Authenticated

In order to create a transaction the user must first be authenticated(password) in the confirm dialog modal. Once the user is authenticated the modal is closed and the transaction is shown. If a user is not authenticated correctly the modal still closes and a toast message is displayed with the error. I would like to change this logic so that the user must re-enter the password if their attempt was not authenticated.
setting the state inside createTransaction is done in an async way. this.closeModal in newTransactionModal is whats causing the modal to be closed and the state to be reset.
NewTransactionModal.js
this.state.showConfirmDialog ? (
<ConfirmDialog
type="New Transaction"
onPasswordChange={this.changePassword}
onConfirm={this.handleCreateClick}
onCancel={this.handleClose}
errMsg = {this.props.passwordErrMsg}
/>
) : null
NewTransactionModal.js
handleCreateClick = () => {
if (this.formIsValid()) {
let path = '/transaction',
transaction = {
type: this.state.transactionType.id,
amount: this.state.transactionAmount,
internalComment: this.state.comment,
userPassword: this.state.password
},
extraDataForError = {
typeName: this.state.transactionType.name,
advertiserName: this.state.advertiser.name,
fundingType: this.state.advertiser.fundingType,
financialDocumentId: this.state.documentId,
financialDocumentType: this.state.document && this.state.document.documentMetadata.documentType
};
if (this.state.transactionType.creditType) {
path += '/transfer';
transaction.debitAdvertiserId = this.state.advertiserId;
transaction.creditAdvertiserId = this.state.transferAdvertiserId;
transaction.debitFinancialDocumentId = this.state.documentId;
transaction.creditFinancialDocumentId = this.state.documentId;
} else {
transaction.advertiserId = this.state.advertiserId;
transaction.financialDocumentId = this.state.documentId;
}
this.props.createTransaction(path, transaction, extraDataForError);
this.closeModal();
}
};
ListTransaction.js
createTransaction = (path, data, extra) => {
const failureMsg = 'Failed to create transaction';
if (!path || !data) {
this.setState({
toastMessage: failureMsg,
toastType: 'error'
});
return;
}
const getErrTransactions = res => {
return [{ transaction: {...data, ...extra}, validations: res.validations, result: res.result }];
};
this.setState({ toastType: 'pending' }, async () => {
try {
const res = await ApiService.post(path, data, this.abortController.signal);
if (res && res.result !== 'FAILURE') {
this.setState({
toastMessage: 'Transaction created',
toastType: 'success',
selected: []
}, () => this.loadData(1));
} else if (res) {
this.handleError(getErrTransactions(res), failureMsg);
} else {
this.setState({toastType: null})
}
} catch (err) {
if (err) {
if (err.name === 'AbortError') {
return false;
} else if (err.json) {
this.setState({
passwordErrMsg: "Please enter a valid password"
})
const jsonErr = await err.json();
this.handleError(jsonErr.result ? getErrTransactions(jsonErr) : jsonErr, failureMsg);
} else {
this.handleError(err, failureMsg);
}
} else {
this.setState({ toastType: null });
}
}
});
};
ListTransactions.js
canCreate ? (
<NewTransactionModal
show={showNewTransactionModal}
types={allowedTransactionTypes}
createTransaction={this.createTransaction}
passwordErrMsg = {this.state.passwordErrMsg}
handlePasswordAttempt = {this.handlePasswordAttempt}
handleRecent={this.handleRecent}
handleClose={this.hideModal}
/>
) : null
I expect that that the user must still enter their password after an invalid attempt and that the modal does not go away. Also after the user has entered the correct password than the modal is closed.

How to compare Inputs and JSON data

I'm working on a school project and I need to validate some users without making a real Database. My problem is that when I compare the information entered in the inputs with the information storaged in JSON, it pops an error for every option that doesn't match. What I want is to reduce the multiple errors into only one (in case that the username or the password doesn't matches with the information storaged in JSON). Here is My JavaScript:
const form = document.querySelector('form');
form.addEventListener('submit', function(e){
e.preventDefault();
const emailInput = document.querySelector('#email').value;
const pwdInput = document.querySelector('#pwd').value;
const object = {
email: emailInput,
pwd: pwdInput
};
fetch('users.json')
.then(res => res.json())
.then(data => {
data.forEach(function(user) {
const userInfo = JSON.stringify(user);
const databaseInfo = JSON.stringify(object);
if(userInfo === databaseInfo) {
console.log('success');
} else {
console.log('err');
}
});
})
.catch(error => console.log('error'));
});
And here is the fake database made with JSON:
[
{"email": "James", "pwd": "1111"},
{"email": "Peter", "pwd": "2222"},
{"email": "Josh", "pwd": "3333"}
]
Using vanilla JavaScript :
// This is only to simulate your fetch from JSON
function fakeFetch ()
{
return Promise.resolve([
{"email": "James", "pwd": "1111"},
{"email": "Peter", "pwd": "2222"},
{"email": "Josh", "pwd": "3333"}
]);
}
const form = document.querySelector('form');
form.addEventListener( 'submit', function(e){
e.preventDefault();
const emailInput = document.querySelector('#email').value;
const pwdInput = document.querySelector('#pwd').value;
const object = {
email: emailInput,
pwd: pwdInput
};
fakeFetch()
.then( users => {
// Check each user in users and try to find a match
for ( let user of users )
{
// Destructuring email and password from the current user
let { email, pwd } = user;
// Comparing email and pwd from active user with the ones in object
if ( email === object.email && pwd === object.pwd )
{
// Found, do something
console.log( 'found!' );
return;
}
}
// Not found, do something else
console.log( 'Not found...' );
})
.catch(error => console.log( error ) );
});
<form>
<input type="text" id="email"/>
<input type="test" id="pwd"/>
<input type="submit"/>
</form>
I tried explaining in the comments, but its probably easier to show you. I think its better to compare the smallest amount of data possible (rather than a big JSON string), like email to email and password to password.
So I changed your if to do a more simpler compare.
To condense all your errors into one, you can include a flag and set it to true if a match is found. Then outside the forEach loop you can check that flag and log just 1 error (if there is no match)
var users = [{
email: "user1",
pwd: "pass1"
}, {
email: "user2",
pwd: "pass2"
}];
var object = {
email: "user3",
pwd: "pass3"
};
var isMatch = false;
users.forEach(function(user) {
if (user.email === object.email && user.pwd === object.pwd) {
console.log("success");
isMatch = true;
}
});
if (!isMatch) {
// only logs once even though there are multiple users
console.log("No Match!");
}
The main idea of your function is to, given a tuple (username, password), check if it exists in your database, which is an array of objects in this case.
You could say you want to filter from the array the entries whose username and password match what was inserted by the user. Since there should be no repeated tuples of username/password, your filter should either return the matching tuple or null.
An approach for this could be the following:
function verifyLogin(loginObject) {
return new Promise((resolve, reject) => {
fetch('users.json')
.then(res => res.json())
.then(data => data.filter(entry => entry.email ===
loginObject.email && loginObject.pwd === object.pwd).length > 0 ? resolve(true) : resolve(false))
.catch(error => reject(error));
});
})
}
verifyLogin(loginObject)
.then(result => result === true ? console.log('Login successful!') : console.log('Login failed'))
.catch(error => console.log(error))
This way the code shows what you are trying to accomplish and does it with no side effects.

Categories