how to check if database needs auth or not - javascript

I'm working on a project which allows user to login to a mongodb database. Basically I have
db.authenticate(username, password, function(err, isAuthPass) {...}
to check if the user pass the authentication. However, sometimes the server doesn't need authentication. If I provide username/password, it will fail. So I need to know how to check auth mode with mongo-native-client. Any idea?

Well I suppose you could just interrogate the database for the config information. This does come with the caveat that you should also be using the "test/fail" methods as discussed before as you would not be able to get this information from a server with authentication enabled that is not running on localhost:
var mongo = require('mongodb'),
MongoClient = mongo.MongoClient;
MongoClient.connect('mongodb://localhost:30000/test',function(err,db) {
var adminDb = db.admin();
adminDb.command({ "getCmdLineOpts": 1 },function(err,result) {
console.log( JSON.stringify( result, undefined, 4 ) );
});
});
That shows the "parsed" options, and it does not matter whether they are actually sent from the command line or picked up from a config file as the output here suggests:
{
"documents": [
{
"argv": [
"mongod",
"--config",
"mongod.conf"
],
"parsed": {
"config": "mongod.conf",
"net": {
"bindIp": "0.0.0.0",
"port": 30000
},
"security": {
"authorization": "enabled"
},
"storage": {
"dbPath": "data"
},
"systemLog": {
"destination": "file",
"logAppend": true,
"path": "log/mongod.log"
}
},
"ok": 1
}
],
"index": 338,
"messageLength": 338,
"requestId": 25,
"responseTo": 3,
"responseFlag": 8,
"cursorId": "0",
"startingFrom": 0,
"numberReturned": 1
}
So here the presence of "security.authorization.enabled": true tells you that further operations are going to require authorized credentials to be supplied.
Also see getCmdLineOpts and other diagnostic information commands that should be useful for your tool.

Sometimes? always use a password. and if you don't need one, like your local environment, you should use a config file for that environment like ./config/dev.js which has the credentials for that environment.

Related

unable to perform CRUD in JSON-SERVER

I am trying to add, update, delete in JSON server with Redux Axios. But I am unable to perform CRUD action. I am always getting an error 404. I am using the following code example. this my db.json
{
"orderdetails": [
{
"OrderID": 111,
"CustomerID": "VINET",
}
]
}
I am using the following code for importing Axios from redux. Please find my server.js
import axios from 'axios';
export default axios.create({
baseURL: "http://localhost:3007/",
headers: {
"Content-type": "application/json"
}
})
I am using the following code example for performing CRUD action in the JSON-Sever. But, I am got a error
import http from "../serverapi";
create(data) {
return http.post("/orderdetails/posts", data);
}
update(id, data) {
return http.put(`/orderdetails/${id}`, data);
}
delete(id) {
return http.delete(`/orderdetails/${id}`);
}
could you please provide the suggestion?
If you are using the json-server npm package, there are a couple of problems with your usage.
First, you db.json is invalid. It should be somewhat like this:
{
"orderdetails": [
{
"OrderID": 111,
"CustomerID": "VINET"
},
{
"OrderID": 12,
"CustomerID": "VINET"
}
]
}
Make sure to check the API url in the browser first.
Second, json-server by default runs on localhost:3000 (Not sure if it can be changed, check the docs here https://www.npmjs.com/package/json-server). Your API is pointing to port 3007 as seen here baseURL: "http://localhost:3007/,
Lastly, you cannot do a request like http://localhost:3000/orderdetails/111. The last part in the api url by default corresponds to the id key in db.json, but since your key is OrderID, your API end point should be modified to http://localhost:3000/orderdetails?OrderID=111. Try this url in your browser, it should return the correct object.
UPDATE
Update operations in json-server require the id key to be present in the db.json file. Hence, update your db.json as follows:
{
"orderdetails": [
{
"id": 1,
"OrderID": 111,
"CustomerID": "VINET"
},
{
"id": 2,
"OrderID": 12,
"CustomerID": "VINET"
}
]
}
Then, you can try running a POST request on the url http://localhost:3000/orderdetails and json body :
{
"OrderID": 12333,
"CustomerID": "VINET"
}
This will create a new object in the db, with incremented id. PUT, DELETE requests can be made using the id param in the url like http://localhost:3000/orderdetails/3.

Dialogflow Fulfilment webhook call failed

I am new to dialogflow fulfillment and I am trying to retrieve news from news API based on user questions. I followed documentation provided by news API, but I am not able to catch any responses from the search results, when I run the function in console it is not errors. I changed the code and it looks like now it is reaching to the newsapi endpoint but it is not fetching any results. I am utilizing https://newsapi.org/docs/client-libraries/node-js to make a request to search everything about the topic. when I diagnoise the function it says " Webhook call failed. Error: UNAVAILABLE. "
'use strict';
const functions = require('firebase-functions');
const {WebhookClient} = require('dialogflow-fulfillment');
const {Card, Suggestion} = require('dialogflow-fulfillment');
const http = require('http');
const host = 'newsapi.org';
const NewsAPI = require('newsapi');
const newsapi = new NewsAPI('63756dc5caca424fb3d0343406295021');
process.env.DEBUG = 'dialogflow:debug';
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((req, res) =>
{
// Get the city
let search = req.body.queryResult.parameters['search'];// search is a required param
// Call the weather API
callNewsApi(search).then((response) => {
res.json({ 'fulfillmentText': response }); // Return the results of the news API to Dialogflow
}).catch((xx) => {
console.error(xx);
res.json({ 'fulfillmentText': `I don't know the news but I hope it's good!` });
});
});
function callNewsApi(search)
{
console.log(search);
newsapi.v2.everything
(
{
q: 'search',
langauge: 'en',
sortBy: 'relevancy',
source: 'cbc-news',
domains: 'cbc.ca',
from: '2019-12-31',
to: '2020-12-12',
page: 2
}
).then (response => {console.log(response);
{
let articles = response['data']['articles'][0];
// Create response
let responce = `Current news in the $search with following title is ${articles['titile']} which says that
${articles['description']}`;
// Resolve the promise with the output text
console.log(output);
}
});
}
Also here is RAW API response
{
"responseId": "a871b8d2-16f2-4873-a5d1-b907a07adb9a-b4ef8d5f",
"queryResult": {
"queryText": "what is the latest news about toronto",
"parameters": {
"search": [
"toronto"
]
},
"allRequiredParamsPresent": true,
"fulfillmentMessages": [
{
"text": {
"text": [
""
]
}
}
],
"intent": {
"name": "projects/misty-ktsarh/agent/intents/b52c5774-e5b7-494a-8f4c-f783ebae558b",
"displayName": "misty.news"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {
"webhook_latency_ms": 543
},
"languageCode": "en"
},
"webhookStatus": {
"code": 14,
"message": "Webhook call failed. Error: UNAVAILABLE."
},
"outputAudio": "UklGRlQqAABXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAAZGF0YTAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA... (The content is truncated. Click `COPY` for the original JSON.)",
"outputAudioConfig": {
"audioEncoding": "OUTPUT_AUDIO_ENCODING_LINEAR_16",
"synthesizeSpeechConfig": {
"speakingRate": 1,
"voice": {}
}
}
}
And Here is fulfillment request:
{
"responseId": "a871b8d2-16f2-4873-a5d1-b907a07adb9a-b4ef8d5f",
"queryResult": {
"queryText": "what is the latest news about toronto",
"parameters": {
"search": [
"toronto"
]
},
"allRequiredParamsPresent": true,
"fulfillmentMessages": [
{
"text": {
"text": [
""
]
}
}
],
"intent": {
"name": "projects/misty-ktsarh/agent/intents/b52c5774-e5b7-494a-8f4c-f783ebae558b",
"displayName": "misty.news"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {
"webhook_latency_ms": 543
},
"languageCode": "en"
},
"webhookStatus": {
"code": 14,
"message": "Webhook call failed. Error: UNAVAILABLE."
},
"outputAudio": "UklGRlQqAABXQVZFZm10IBAAAAABAAEAwF0AAIC7AAACABAAZGF0YTAqAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA... (The content is truncated. Click `COPY` for the original JSON.)",
"outputAudioConfig": {
"audioEncoding": "OUTPUT_AUDIO_ENCODING_LINEAR_16",
"synthesizeSpeechConfig": {
"speakingRate": 1,
"voice": {}
}
}
}
Also here is the screenshot from the firebase console.
Can anyone guide me what is that I am missing in here?
The key is the first three lines in the error message:
Function failed on loading user code. Error message: Code in file index.js can't be loaded.
Did you list all required modules in the package.json dependencies?
Detailed stack trace: Error: Cannot find module 'newsapi'
It is saying that the newsapi module couldn't be loaded and that the most likely cause of this is that you didn't list this as a dependency in your package.json file.
If you are using the Dialogflow Inline Editor, you need to select the package.json tab and add a line in the dependencies section.
Update
It isn't clear exactly when/where you're getting the "UNAVAILABLE" error, but one likely cause if you're using Dialogflow's Inline Editor is that it is using the Firebase "Spark" pricing plan, which has limitations on network calls outside Google's network.
You can upgrade to the Blaze plan, which does require a credit card on file, but does include the Spark plan's free tier, so you shouldn't incur any costs during light usage. This will allow for network calls.
Update based on TypeError: Cannot read property '0' of undefined
This indicates that either a property (or possibly an index of a property) is trying to reference against something that is undefined.
It isn't clear which line, exactly, this may be, but these lines all are suspicious:
let response = JSON.parse(body);
let source = response['data']['source'][0];
let id = response['data']['id'][0];
let name = response['data']['name'][0];
let author = response['author'][0];
let title = response['title'][0];
let description = response['description'][0];
since they are all referencing a property. I would check to see exactly what comes back and gets stored in response. For example, could it be that there is no "data" or "author" field in what is sent back?
Looking at https://newsapi.org/docs/endpoints/everything, it looks like none of these are fields, but that there is an articles property sent back which contains an array of articles. You may wish to index off that and get the attributes you want.
Update
It looks like that, although you are loading the parameter into a variable with this line
// Get the city and date from the request
let search = req.body.queryResult.parameters['search'];// city is a required param
You don't actually use the search variable anywhere. Instead, you seem to be passing a literal string "search" to your function with this line
callNewsApi('search').then((output) => {
which does a search for the word "search", I guess.
You indicated that "it goes to the catch portion", which indicates that something went wrong in the call. You don't show any logging in the catch portion, and it may be useful to log the exception that is thrown, so you know why it is going to the catch portion. Something like
}).catch((xx) => {
console.error(xx);
res.json({ 'fulfillmentText': `I don't know the news but I hope it's good!` });
});
is normal, but since it looks like you're logging it in the .on('error') portion, showing that error might be useful.
The name of the intent and the variable I was using to make the call had a difference in Casing, I guess calls are case sensitive just be aware of that

Fetch all emails across all Gmail contact groups

I am trying to fetch all the emails from the user contacts using JS library.
Setup
1.) Initialised the gapi client using
gapi.client.init({
apiKey: config['google']['apiKey'],
discoveryDocs:
["https://www.googleapis.com/discovery/v1/apis/people/v1/rest"],
clientId: config['google']['appId'],
scope: "https://www.googleapis.com/auth/contacts.readonly"
})
2.) After the user grants permission, I try to fetch the contact details
gapi.client.people.people.connections.list({
'resourceName': 'people/me',
'pageSize': 500,
'personFields': 'names,emailAddresses'
}).then((response) => {
let connections = response.result.connections;
console.warn(connections);
})
3.) From step 2, I get zero connections.
However, when I perform
gapi.client.people.contactGroups.list()
I get following response
{
"contactGroups": [
{
"resourceName": "contactGroups/all",
"groupType": "SYSTEM_CONTACT_GROUP",
"name": "all",
"formattedName": "All Contacts",
"memberCount": 13
},
...
],
"totalItems": 9,
"nextSyncToken": "EJjRiq3lnNYC"
}
From the response, I can see that in contactGroups/all group, I have 13 contacts and in my account i can see the same number of contacts.
So, what is the proper way to get all the contacts across all the contact groups using JS library?
I've tried using gapi.client.people.people.connections.list and successfully got 200 response. I also don't get equal values.
Using gapi.client.people.people.connections.list, here is the response:
....
],
"nextSyncToken": "^***",
"totalPeople": 19,
"totalItems": 19
}
While in gapi.client.people.contactGroups.list(),
{
"resourceName": "contactGroups/all",
"groupType": "SYSTEM_CONTACT_GROUP",
"name": "all",
"formattedName": "All Contacts",
"memberCount": 155
},
Be noted that people.connections.list only provides a list of the authenticated user's contacts merged with any connected profiles. While contactGroups.list lists all contact groups owned by the authenticated user. Members of the contact groups are not populated.

login page not working (javascript, firebase)

HELP!
I'm not sure what's going on, but my login page isn't working. It simply reloads even though I'm entering valid user/password.
I think the problem is it's getting stuck on issues with my data-structure, security-rules, and app.js, but I'm at a loss.
I was provided a sinatra/ruby simple api to work with users & groups (just a small project).
here's the site:
https://starter-vicks9985.firebaseapp.com/index.html
here's the code:
$.post/("https://starter-vicks9985.firebaseapp.com/main.rb",
{
"name": "admin",
"email": "admin#example.com",
"password": "secret",
"admin": true,
"role-value": 99,
}
), console.log("success");
{
"rules": {
".read": true,
"users": {
"$user": {
//can add a message if authenticated
".write": "auth.uid === $user"
}
},
"rooms": {
"$room": {
"users": {
// can write to the users list only if ADMINISTRATOR
"$user": {
"write":"newData.parent().child(auth.uid).val() === 99"
}
}
}
},
"messages": {
"$room": {
"$message": {
//can add a message if they are a MEMBER (if there was message/chat capability)
".write": "(!data.exists() && newData.exists() && root.child('rooms/' + $room + '/users/' + auth.uid).val() >= 10)"
}
}
}
}
}
$(document).ready(function() {
/**
*Set initial firebase ref. Use set to write in first admin user.
*/
var ref = new Firebase("https://starter-vicks9985.firebaseio.com/");
ref.set({
"name": "Admin",
"email": "admin#example.com",
"password": "secret",
"admin": true
});
/** Get email address from loginform, format email, get password
* Firebase keys cannot have a period (.) in them, so this converts the emails to valid keys
*/
var emailAddress = function emailToKey(emailAddress){
return btoa(emailAddress);
};
var password = document.getElementById('password');
/**
* Authorize user with email and password, passing in values from form.
*/
ref.authWithPassword({
email : emailAddress,
password : password,
}, function(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
return authData;
}
});
/**
* If user is logged in (valid), redirect to user profile
*/
ref.onAuth(function(authData) {
window.open="https://starter-vicks9985.firebaseio.com/userprofile/userprofile.html";
})
});
Like #Kato said, this is a code dump so please consider creating an mcve. Although, first check out my comments below.
The Code You Posted
After glancing at your code, I see some errors that I will point out:
1. Your jQuery post syntax is incorrect, and wouldn't work even if it was correct.
Most importantly, you are making a post request to a Ruby file. Firebase Hosting is not a server, it is hosting for static files.
See this answer by Frank. He says:
Firebase hosting is a product to serve so-called static application, which consist only of files that the client interprets. Firebase's servers will not interpret any code that you upload. So Firebase hosting is not suited to host your Ruby-on-Rails application.
To quote Firebase hosting's documentation:
We deliver all your static content (html, js, images, etc)
That being said, take a look at the jQuery documentation for $.post().
See my comments on your code:
$.post/("https://starter-vicks9985.firebaseapp.com/main.rb",
// ^ What is this '/'?
{
"name": "admin",
"email": "admin#example.com",
"password": "secret",
"admin": true,
"role-value": 99,
}
), console.log("success");
// ^ You are closing the function call, 'console.log' falls outside of it.
What it should look like:
$.post("https://starter-vicks9985.firebaseapp.com/main.rb", {
"name": "admin",
"email": "admin#example.com",
"password": "secret",
"admin": true,
"role-value": 99,
}, function() {
console.log("success");
});
2. What's even going on with the login functions?
Assuming you fix Uncaught SyntaxError: Unexpected token { in data-structure.js:14...
If you take a look at the console, you will see Uncaught Error: Firebase.authWithPassword failed: First argument must contain the key "email" with type "string".
That is because you are passing a function, emailAddress to .authWithPassword().
You declare emailAddress() like so:
var emailAddress = function emailToKey(emailAddress){
return btoa(emailAddress);
};
So the email parameter in the following is being passed emailAddress(), not a string that is an email address.
ref.authWithPassword({
email : emailAddress,
password : password,
}, function(error, authData) {
if (error) {
console.log("Login Failed!", error);
} else {
return authData;
}
});
Most importantly, all of these login functions are being called immediately after the page loads. Nothing in your code (app.js) waits for, and responds to, the submission of the form.
The Code on Your Website
I also went on your page, looked at your source code, and found some more issues.
1. Error in form HTML in index.html
<section class="loginform cf">
<form id= "login" form name="login" form type= "submit" accept-charset="utf-8">
<!-- extra^space ^duplicate "form"^ ^again, space -->
...
</form>
</section>
2. Syntax Errors in data-structures.js
Again, you have the same errors here as I described above ('/' and closing parentheses), but the object that you're passing the post is incorrectly formatted
$.post/("https://starter-vicks9985.firebaseapp.com/main.rb",
{
"users" //missing ':' after users
//the following objects do not have keys - should be {"users":{"someUserKey1":{...},"someUserKey2":{...}}} etc.
{
"name": "admin",
"email": "...",
"password": "...",
"admin": true,
"role-value": 99,
},
{
"name": "aaa",
...
},
{
"name": "bbb",
...
}
},
), console.log("success");
And the same things apply for the post call for "groups".
I hope that provides some clarity.
I would suggest reading over other answers here on StackOverflow, like:
jQuery AJAX submit form
jQuery form submit
And search for more answers like:
https://stackoverflow.com/search?q=jquery+form+submit
In conclusion, I'd suggest doing some more research and reading documentation :)

Redirection after the login succeeds or fails in loopback framework

I have recently started with loopback framework and made a simple login functionality by creating a 'customer' model inheriting from base 'User' like this:
CUSTOMER.JSON
{
"name": "customer",
"base": "User",
"idInjection": true,
"properties": {
"email":{
"type":"string",
"required":false
},
"username":{
"type":"string",
"required":false
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": []
}
CUSTOMER.JS
module.exports = function(customer){
}
I then made a entry in model-config.json like this:
"customer": {
"dataSource": "mango-database",
"public": true
}
And yes I was able to login and logout easily. I have a login screen with fields username and password. I submit this form to customers/login and as soon as it gets the login, I get a screen:
{
id: "lvrTjKBKXCFPTMFej6AyegQUFYe5mSc1BiYbROZwCBM0jqae7kZ7v8ZfGujfDGgy",
ttl: 1209600,
created: "2014-12-07T08:12:17.572Z",
userId: "5483e88b5e9cf2fe0c64dd6c"
}
Now I want that instead of this screen, I should be able to redirect user to some other page (dashboard) and if the login fails, it should go back to the login screen.
I googled up a lot on this and all i found was the suggestions to use hooks. But hooks doesn't have such event. Where do I write the redirection functionality? My guess is CUSTOMER.JS
I found the documentation quiet confusing !
Use context.res provided in a remote hook. For example:
Customer.afterRemote('create', function(context, customer, next) {
var res = context.res; //this is the same response object you get in Express
res.send('hello world');
})
Basically, you have access to request and response objects, so just respond as you would in Express. See http://expressjs.com/4x/api.html for more info.

Categories

Resources