Safari Push Notificatin + permission "denied" and no log found - javascript

I am try to integrate safari push notification. I referred following link.
http://samuli.hakoniemi.net/how-to-implement-safari-push-notifications-on-your-website/#resources
My client file is at...
-public_html/push/index.html
Server configuration files are at...
-public_html/push/node_modules/express/index.js
Push packages and log file are at...
-public_html/push/v1/pushPackages/[my push id]/myPackage.zip
-public_html/push/v1/pushPackages/[my push id]/log (file)
My index.js file has following code.
'use strict';
module.exports = require('./lib/express');
//Test code for Safari push notification
var express = require('express');
var app = express();
var port = process.env.PORT || 3000;
app.listen(port);
app.get('/', function(req, res) {
res.sendfile('index.html');
});
app.post('/v1/pushPackages/[my push id]', function(req, res) {
alert('hello');
res.sendfile('myPushPackage.zip');
});
app.post('/v1/log', function(req, res) {
});
My client file (index.html) has following code :
!doctype html>
<html>
<head>
<title> Safari Push Notifications</title>
</head>
<body>
<h1>Safari Push Notifications</h1>
Subscribe
<script>
var pushId = [my push id];
document.body.onload = function() {
// Ensure that the user can receive Safari Push Notifications.
if ('safari' in window && 'pushNotification' in window.safari) {
var permissionData = window.safari.pushNotification.permission(pushId);
checkRemotePermission(permissionData);
} else {
alert("Push notifications not supported.");
}
};
var checkRemotePermission = function (permissionData) {
if (permissionData.permission === 'default') {
alert("default.");
// This is a new web service URL and its validity is unknown.
console.log("The user is making a decision");
//alert('The user is making a decision');
var userinfo={};
window.safari.pushNotification.requestPermission(
'https://[mydomain]/push', // The web service URL.
pushId, // The Website Push ID.
userinfo, // Data that you choose to send to your server to help you identify the user.
checkRemotePermission // The callback function.
);
}
else if (permissionData.permission === 'denied') {
alert("denied.");
// The user said no.
console.log('denied');
}
else if (permissionData.permission === 'granted') {
alert("granted.");
// The web service URL is a valid push provider, and the user said yes.
// permissionData.deviceToken is now available to use.
console.log("The user said yes, with token: "+ permissionData.deviceToken);
}
};
</script>
</body>
</html>
It give us the alert of "default" then after "denied" alert.
Please help me.

app.post('/v1/pushPackages/[pushid]', function(req, res) {
console.log('Serving File');
res.sendFile('aa.zip', { root: __dirname });
});
app.post('/v1/log', function(req, res) {
console.log('Received LOG');
console.log(req.body);
});
This Solved my problem having tha aa.zip file on same location of index.js file. For more check your node log as console.log(req.body) show the error.

Related

Express.js: How to refresh on DB change in backend?

I decided to make a janky chat site type thing to get me started working with requests and such.
My approach was to create an express.js server that takes in requests when the '/messageReciever' is posted to.
app.post("/messageReciever", (req, res) => {
logMessage(req.body.message);
});
The next step was to make a 'client' that could send information to this end point:
var XMLHttpRequest = require("XMLHttpRequest").XMLHttpRequest;
function makePostRequest(url, json)
{
let http = new XMLHttpRequest();
http.open("POST", url, true);
http.setRequestHeader("Content-Type", "application/json");
http.send(JSON.stringify(json));
}
function sendMessage(url, message)
{
makePostRequest(url, {message: message});
logMessage(message);
}
Both of these are fine. The issue I'm running into is, once I receive the post request I want to refresh the main page of my site (to show the messages)
app.get('/', (req, res) => {
res.render('index', data = retrieveMessages());
});
I've tried basically everything I've found online:
res.redirect('back');
res.redirect(req.get('referer'));
res.redirect(req.originalUrl)
I used res.redirect('back') previously in my code, and it works. The issue is that I'm trying to refresh someone's connection to a site based on someone else's connection; meaning I can't use the response information like I normally could.
I've tried looking for ways to refresh pages from outside functions but I can't find anything.
(I realize that there are easier ways to make a chat site that don't include weirdly sending data back and forth between two server's)
You can use a package called socket.io. Socket.io allows you to send requests to a client once the server has some data.
Example:
Server:
// Define express
const express = require('express');
const app = express();
// Create the server
const http = require('http');
const server = http.createServer(app);
// Define socket.io
const io = require('socket.io')(server);
// Define the port for the server to listen on
let port = 3000;
function logMessage(message, id) {
...
io.emit('message_sent_' + id, { message }); // Emit that a message was sent to the clients
}
function recieveMessages(id) {
// Get the messages somehow
}
app.post('/messageReciever', (req, res) => {
// req.body.message is your message and req.cookies.id is the clients random ID
logMessage(req.body.message, req.cookies.id);
});
app.get('/', (req, res) => {
res.cookie('id', 'some-generated-id'); // Set a cookie for the unique ID to fetch user messages
res.render('index', { data: retrieveMessages() });
});
// Get the server listening to incoming requests
server.listen(port, () => console.log('my app is online');
Client:
<!doctype html>
<html>
<body>
...
</body>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io.connect();
socket.on('message_sent_' + 'some-id', function(data) {
// Do something with the data
});
</script>
</html>
References:
https://socket.io/docs/v4/
http://expressjs.com/
https://marques-robinson-project.medium.com/chat-app-with-socket-io-and-express-using-node-js-2293b87f47c3

How to grant access to a folder after authentication in nodejs with express?

I am new to nodejs and I have been looking for a solution quite a while now and none solves my specific problem unfortunately. Or at least I just don't get it.
In my nodejs project I am using a public folder where all my html and js files are stored.
In server.js, which is outside of the public folder I do:
app.use(express.static(__dirname + '/public'));
A specific user, let's call him Tom, will access tom-page.html.
Another user, let's call him Fred, will access fred-page.html.
These files and their scripts (javascript) are all in that public folder.
Now what I am trying to do is to protect the public folder with a static password. If Tom logs in, then he should be redirected to /public/tom-page.html and for Fred it should be /public/fred-page.html. And they should have access to all the other files in that folder.
What I did so far:
const express = require('express');
const app = express();
var basicAuth = require('basic-auth');
var is_tom = false;
var auth = function(req, res, next) {
function unauthorized(res) {
res.set('WWW-Authenticate', 'Basic realm=Authorization Required');
return res.send(401);
};
var user = basicAuth(req);
if (!user || !user.name || !user.pass) {
return unauthorized(res);
};
if (user.name === 'fred' && user.pass === 'fred-pwd') {
is_tom = false;
return next();
} else if (user.name === 'tom' && user.pass === 'tom-pwd') {
is_tom = true;
return next();
} else {
return unauthorized(res);
}
};
const http = require('http');
server = http.createServer(app);
app.get('/', auth, function(req, res) {
if (is_tom) {
res.send('hi tom');
} else {
res.send('hi fred');
}
});
This works. But I don't know how to grant them access to the public folder aka app.use(express.static(__dirname + '/public')); and also redirect them to their page.
Could anyone help please?
I've just found a solution that works:
app.use(auth, express.static(__dirname + '/public'));
I've just put auth before specifying the the static folder that I am using.
Does anyone else have a better suggestion?
You can put all the pages in the folder WEB-INF, this directory is only accessible for your application. If the user is logged in, you can send it to the file inside that folder.

Microsoft botframework (node.js): how to trigger bot from HTTP request

I want to trigger my bot with http request (for example just entering http://localhost:3978/api/messages/http) so after triggering it, it will send every user that is connected to this bot some message.
I have seen this topic: How to send message later in bot framework?
And this is what I have so far:
var restify = require('restify');
var builder = require('botbuilder');
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
console.log('%s listening to %s', server.name, server.url);
});
var connector = new builder.ChatConnector({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});
server.post('/api/messages', connector.listen());
var bot = new builder.UniversalBot(connector);
bot.dialog('/',function (session) {
var reply = session.message; // address: reply.address
reply.text = 'Wake up!'
console.log(reply.text);
bot.send(reply);
});
// Create response function
function respond(req, res, next) {
res.send('hello ' + req.params.name);
bot.send(reply);
next();
}
server.get('/api/messages/:name', respond);
Unfortunately, it doesn't send any messages while I am acessing my http://localhost:3978/api/messages/http. I also tried to use
connector.send('message');
But it always throughs me "ERROR: ChatConnector: send - message is missing address or serviceUrl."
UPDATE:
I have announced a global var for the reply with
var globalreply;
bot.dialog('/',function (session) {
globalreply = session.message; // address: reply.address
globalreply.text = 'Wake up!'
console.log(globalreply.text);
bot.send(globalreply);
});
// Create response function
function respond(req, res, next) {
res.send('hello ' + req.params.name);
bot.beginDialog;
bot.send(globalreply);
next();
}
But now it throughs me an error:
TypeError: Cannot read property 'conversation' of undefined.
At my bot.send(globalreply); line.
Looking forward your help.
Best regards.
If you want to set up a normal HTTP API route, I suggest using the Restify API style routing, rather than the bot's /api/messages route handler.
For example:
function apiResponseHandler(req, res, next) {
// trigger botbuilder actions/dialogs here
next();
}
server.get('/hello/:name', apiResponseHandler);

How to broadcast and get notification using Express, AngularJS, Socket.io?

I am trying to make notification system. To demonstrate this, User 1 is sending friend request to User 2. I am using express.js, angularjs and socket.io. On click of the button User1 sends request. On end of User2, there is a socket,on() which is listening on friend-request event. But when I am broadcasting, the other user is not able to receive any message.
app.js (Node Server File)
var express = require('express'),
app = express();
var port = process.env.PORT || 3000;
var io = require('socket.io').listen(app.listen(port));
require('./config')(app,io);
require('./routes')(app,io);
config.js
// This file handles the configuration of the app.
// It is required by app.js
var express = require('express');
module.exports = function(app, io){
// Set .html as the default template extension
app.set('view engine', 'html');
// Initialize the ejs template engine
app.engine('html', require('ejs').renderFile);
// Tell express where it can find the templates
app.set('views', __dirname + '/views');
// Make the files in the public folder available to the world
app.use(express.static(__dirname + '/public'));
};
routes.js (Emitting Friend Request From this File)
var gravatar = require('gravatar');
var mysql = require('mysql');
// This is needed if the app is run on heroku:
var connection = mysql.createConnection({
host : "localhost",
user : "root",
password : "",
database : "two_way_demo"
});
connection.connect(function(error){
if(error)
{
console.log("Problem with MySQL"+error);
}
else {
console.log("Connected with Database");
}
});
module.exports = function(app,io){
app.get('/',function(req,res){
res.render('index');
});
app.get('/create', function(req,res){
// Generate unique id for the room
var id = Math.round((Math.random() * 1000000));
// Redirect to the random room
res.redirect('/chat/'+id);
});
app.get('/home/:id', function(req,res){
// Render the chant.html view
res.render('home');
});
// Initialize a new socket.io application, named 'chat'
var chat = io.on('connection', function (socket) {
socket.on('get-user-id',function(data){
connection.query("SELECT * from user_info WHERE email='"+data.userEmail+"'",function(err,rows){
if(err)
{
console.log("Problem with MySQL"+err);
}
else
{
//console.log(rows);
JSON.stringify(rows);
socket.emit('user-id',rows);
}
});
});
socket.on('send-request',function(data){
console.log(data);
*********************************************************************
// Tried the emit here but its not working
//io.emit('friend request', {
// receiverid: data.receiverid
//});
*********************************************************************
});
});
}
angular-code.js (angular code file)
$(function () {
var app = angular.module("notificationApp", []);
app.controller("chatCTRL", ["$scope", "$http", "$interval", function ($scope, $http, $interval) {
// connect to the socket
//var socket = io();
//socket.on('connect', function () {
// io.on('friend request', function (data) {
// alert("here")
// });
//});
$scope.senderId = Number(window.location.pathname.match(/(\d+)$/)[1]);
$scope.sendrequest = function (senderid, receiverid) {
var socket = io();
socket.on('connect', function () {
socket.emit('send-request', {
senderid: senderid,
receiverid : receiverid
});
});
}
}]);
app.controller("loginCTRL", ["$scope", "$http", "$interval", "$window", function ($scope, $http, $interval, $window) {
$scope.sendLogin = function () {
var socket = io();
socket.on('connect', function () {
socket.emit('get-user-id', {
userEmail: $scope.hisEmail
});
});
socket.on('connect', function () {
socket.on('user-id', function (data) {
$scope.UserId = data[0].user_id;
$window.location = "http://localhost:3000/home/" + $scope.UserId;
});
});
}
}]);
}());
home.html
<!DOCTYPE html>
<html ng-app="notificationApp">
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body ng-controller="chatCTRL">
<h1>welcome</h1>
<div id="createbutton">
<div id="little"><button ng-click="sendrequest(senderId,6)">Send Friend Request to User#6</button></div>
</div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="../angular/angular.js"></script>
<script src="../angular/common_angular.js"></script>
</body>
</html>
Some client side architecture things:
In most cases on angular client side it is better to move your socket connection to service. And make connection when service is initialized (service is singleton, therefore there will be one connection on start) and inject this service in your controllers.
It may be convenient to create some parent abstract controller with
all socket listeners, therefore whether angular controller is active, all listeners are watching. When parent controller get data from socket it can broadcast it to children controllers
In your commented code you have:
//var socket = io();
//socket.on('connect', function () {
// io.on('friend request', function (data) {
// alert("here")
// });
//});
change it to this (if you make connection in service you should omit connect part):
var socket = io();
socket.on('connect', function () {
socket.on('friend request', function (data) {
alert("here")
});
});
Backend:
In your commented code you have:
//io.emit('friend request', {
// receiverid: data.receiverid
//});
You should use socket's from var chat = io.on('connection', function (socket) {... to emit instead of io.emit
Create array variable where you will store all your sockets with users id before connection part:
var socketList = [];
var chat = io.on('connection', function (socket) {
socketList.push({id:someId,socket:socket})
...
}
Now in send-request user should send id of his frient (we have to know which user should be notified- of course we can notify everybody):
socket.on('send-request',function(data){
socketList.forEach(function(soc){
if(soc.id === someId){
soc.socket.emit('friend request', {
receiverid: data.receiverid
})
}
});
Also i don't like this part receiverid: data.receiverid, because it means that taget user get id of receiver from receiver client side. And this may be unsafe (user can change his id and send some other id). I prefere to create id in server side and when user A send notification to user B I get user A id from server variable.
Some time age I create simple prototype of chat application (angular and express), there are some things which I mention here. I you have still problems with your application go there and check my code :
https://github.com/uhlryk/chat-prototype

How to update and read a collection in MongoDB using Mongoose

I am having trouble with a project I am working on. I want to create a database in which I can store dates and links to YouTube videos in a MongoDB database. I am using Mongoose as the ORM. The problem seems to be that the database and collection is created and I can read and update it outside the routes but not inside (if anyone can understand what I am saying). I want to be able to make a GET request for the current items in the database on the /database route as well as make a POST to the /database route.
My code is below. Please help:
//grab express and Mongoose
var express = require('express');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//create an express app
var app = express();
app.use(express.static('/public/css', {"root": __dirname}));
//create a database
mongoose.connect('mongodb://localhost/__dirname/data');
//connect to the data store on the set up the database
var db = mongoose.connection;
//Create a model which connects to the schema and entries collection in the __dirname database
var Entry = mongoose.model("Entry", new Schema({date: 'date', link: 'string'}), "entries");
mongoose.connection.on("open", function() {
console.log("mongodb is connected!");
});
//start the server on the port 8080
app.listen(8080);
//The routes
//The route for getting data for the database
app.get("/database", function(req, res) {
Entry.find({}, function(err, data) {console.log(err, data, data.length); });
});
//The route for posting data on the database
app.post("/database", function(req, res) {
//test new post
var newMonth = new Entry({date: '1997-10-30', link: 'https://wwww.youtube.com/'});
newMonth.save(function(err) {
if (err !== null) {
//object was not save
console.log(err);
} else {
console.log("it was saved!")
};
});
});
//create an express route for the home page at http://localhost:8080/
app.get('/', function(req, res) {
res.send('ok');
res.sendFile('/views/index.html', {"root": __dirname + ''});
});
//Send a message to the console
console.log('The server has started');
Your GET request should have worked because a browser executes a GET request by default. Try the following.
app.get("/database", function(req, res) {
Entry.find(function(err, data) {
if(err) {
console.log(err);
} else {
console.log(data);
}
});
});
As far as testing your POST route is concerned, install a plugin for Google Chrome called Postman. You can execute all sorts of requests using it. It's great for testing purposes.

Categories

Resources