I have a little bit of a problem with an email function. I tried 'nodemailer' package and it worked when I wrote the code in a .js file. When i called the .js file (node emailfile.js) it worked and I received an email (code below).
var nodemailer = require('nodemailer');
let transporter = nodemailer.createTransport({
service: 'gmail',
secure: false,
port: 25,
auth: {
user: 'MYUSERNAME', // this is not an error, I don't want to share my data
pass: 'ok1994ka'
},
tls: {
rejectUnauthorized: false
}
});
let HelperOptions = {
from: '"Sportot App" <fiziohome#gmail.com>',
to: 'fiziohome#gmail.com',
subject: 'Hello World',
text: 'Good day to you!'
};
transporter.sendMail(HelperOptions, (error, info) => {
if (error) {
return console.log("error");
}
console.log("Epasts aizsūtīts");
});
Now, what I want to do is call this .js file from my HTML file.
<button ion-button block color="danger" (click)=pasts()>Sūtīt e-pastu</button>
And in my html file inside tags I inserted:
<script src="email.js"></script>
And inserted a line "function pasts(){"inside there is the whole code from email.js file"}". I hope you can understand my question and somebody of you got answer to this. Thank you!
You will not be able to call that code directly from the browser. You will need to host that file on a webserver and from Angular you will need to make a http request to the webserver running node.
You need to understand which parts of a web application are client and which parts are server. The Angular app is downloaded by the browser and runs on the client machine. The node side of the application runs on the server and Angular makes requests to the server via http.
There is more to this can can be explained in a Stack Overflow answer as there are many parts to answering how to set this up.
Related
I have this in my html:
<angular-file-uploader
[(ngModel)]="pdfUrl"
(ngModelChange)="onChangeCN('pdf')"
[config]="afuConfig"
(ApiResponse)="pdfUpload($event)"
name="file-uploader"
ngDefaultControl
class="ion-padding-top ion-float-left"
></angular-file-uploader>
This is my afuConfig in my component:
afuConfig = {
formatsAllowed: '.pdf',
uploadAPI: {
url: `${SERVER_URL}`,
method: 'POST',
responseType: 'blob',
params: {
token: this.loginService.token,
},
},
}
Attaching a file triggers an http post request to my express server (SERVER_URL) and I can see the the token from the params in req.query.token (although thinking about it, I am not sure if this a secure way of getting the token).
What I can't seem to see anywhere when I debug the call as it hits the express server is the actual file!!
I have been looking at this for a while now and I just can't see it.
Does anyone know what property to look for or maybe what format the file comes across in so I can track it down?
It was because the angular file uploader library sends the data as a multipart form and needs to be handled accordingly on the server (I used the npm library multer).
There are similar questions about it, but it's not very clear how to apply the solution, and keep to receive an error.
I explain. I'd like to create a simply html/js app using service worker technology.
I have:
Index.html
js/app.js
js/sw.js
in app.js the code is (see //*** comments to clearify):
// *** I receive always the error:
// *** ERROR: The path of the provided scope ('/') is not under the max scope allowed ('/js/').
// *** Adjust the scope, move the Service Worker script, or use the Service-Worker-Allowed HTTP header to allow the scope.
var headers = new Headers();
// *** I set the header in order to solve the error above:
// *** The value is set to "/" because this js is included in html file in upper folder.
// *** I tried even "../" and many more others values...
headers.append('Service-Worker-Allowed', '/');
console.log(headers.get('Service-Worker-Allowed'));
if ('serviceWorker' in navigator) {
console.log('Start trying Registrating Scope');
// *** I register the service worker.
// *** The path of service worker is "js/sw.js" because this js is included in html file in upper folder.
// *** The path of scope is "../" because is the path used by service worker, and I want it uses upper folder scope.
navigator.serviceWorker.register('js/sw.js', {scope: '../'})
.then(function(reg) {
// registration worked
console.log('Registration succeeded. Scope is ' + reg.scope);
})
.catch(function(error) {
// registration failed
console.log('Registration failed with ' + error);
});
console.log('End trying Registrating Scope');
}
As you see in the comment I still get the error "The path of the provided scope ('/') is not under the max scope allowed ('/js/'). Adjust the scope, move the Service Worker script, or use the Service-Worker-Allowed HTTP header to allow the scope."
Maybe I could move the sw.js file, but I'd like to know what's wrong.
Sure the problem is in how to register the header in the first 3 not commented lines of code.
Any advice of the code on how exactly register it?
EDIT:
What I'm missing is that what is to set is the request header, the header sent with the request, before asking the html page...
I'm creating headers, useful eventually for a future new request.
So js maybe is not the right place to put setting...
The setting must be setted before the request to index.html is made, because what's setted in the html or js is setted for the response, or prepared for other requests
now...
My approach now is to call another html page (register.html), in this page I'm tryng to $.ajax() the index.html page, with the right header setted:
(I now it could be done with pure js, but for time saving I copy/pasted some already tested code)
$(document).ready(function(){
$.ajax({
type: "GET",
beforeSend: function(request) {
request.setRequestHeader("Service-Worker-Allowed", "/");
},
url: "index.html",
complete: function () {
window.location = "index.html";
}
});
});
I was hoping the first time hit on ajax call I could register the service worker, then redirecting on complete on index.html, I could find it already registered, but event this doesn't work...
I repeat, quickest way is to move sw.js in upper folder. But it's interesting to know how to take control of how to register the service worker, despite of its position in tree folder application...
other advices...?
Ok... I was a little confused, and even now I guess I have to get deep in the facts and study http headers better...
Anyway as stated in many questions & answer on stackoverflow, it's not possible to alter headers during http request, unless it's not an ajax request (and that's not this case).
now on this post Understanding Service Worker scope for a similar question
#Ashraf Sabry answered he could alter the headers using web.config file of IIS Web Server. --> So finally I understood that the header to add is a response header, but before the response is interpreted by the browser --> As stated here https://learn.microsoft.com/en-us/iis/configuration/system.webserver/httpprotocol/customheaders/
that configuration is for response header.
I guess there is not clear way to control that header to make service worker doing his work in a subfolder using html/javascript... It's a problem that could be solved only with server configurations.
A was doing my tests on Node, for didactical porpouse I tried to write a simple http server to test this issue starting from this tutorial https://ilovecoding.org/lessons/create-a-simple-http-server-with-nodejs
the result is here (a "server.js" file runned on Node):
var http = require('http');
var url = require('url');
var querystring = require('querystring');
var fs = require('fs');
http.createServer(function(request, response){
pathName = url.parse(request.url).pathname;
console.log(pathName);
fs.readFile(__dirname + pathName, function(err, data){
if(err){
response.writeHead(404, {'Content-type':'text/plain'});
response.write('Page Was Not Found');
response.end();
}else{
if(pathName.endsWith(".html")){
//response.writeHead(200, {'Service-Worker-Allowed':'/', 'Content-Type':'text/html'});
response.writeHead(200, {'Content-Type':'text/html'});
console.log("serving html");
}else if(pathName.endsWith(".js")){
response.writeHead(200, {'Service-Worker-Allowed':'/', 'Content-Type':'application/javascript'});
//response.writeHead(200, {'Content-Type':'text/javascript'});
console.log("serving js");
}else if(pathName.endsWith(".css")){
//response.writeHead(200, {'Service-Worker-Allowed':'/', 'Content-Type':'text/css'});
response.writeHead(200, {'Content-Type':'text/css'});
console.log("serving css");
}else{
response.writeHead(200);
console.log("serving other");
}
response.write(data);
response.end();
}
})
}).listen(8080);
Using this js Node Server I could reach the same result stated for settings in IIS in the above link.
Note that after some test with this js, I reached that the file which needs "Service-Worker-Allowed:/" is the app.js file.
Now the application work as wanted returning no error.
As final prove tracing requests on fiddler I can clearly see the initial request for app.js, with "Service-Worker-Allowed: /" in the response;
My conclusion is that not always it is possible to handle server configuration, so putting service worker file on root folder of the app is the best approach.
Hope this could be helpful for some others...
the way I was able to register the worker with root scope was
navigator.serviceWorker.register(href = '/service_worker.js', { scope: '/' })
and the way I added the header was to make a new endpoint that served that service_worker file:
#app.route('/service_worker.js')
def service_worker():
from flask import make_response, send_from_directory
response = make_response(send_from_directory('static',filename='service_worker.js'))
response.headers['Content-Type'] = 'application/javascript'
response.headers['Service-Worker-Allowed'] = '/'
return response
Service Workers cannot control pages that do not fall within their scope. Service worker /js/sw.js cannot control page /index.html, because that html file does not exist in the /js/ folder (or subfolders of /js/). If you'd like /index.html to be controlled by a service worker, move the service worker to /sw.js.
It's easier to keep your code simple and put SWs in the proper folders (root if you manage the entire domain). This simplification avoids the unnecessary need to modify HTTP headers.
I'm a very beginner backend developer, so my apologies if this question is rather novice. For a certain javascript file, the script performs perfectly when I execute it using
$ node hello.js
However, I wish to execute this javascript code through a button click on my form. Encapsulating this code into a function and calling the function seems to result in an error every single time.
tls.connect is not a function
Is there a way to manually reproduce the terminal command $ node hello.js from javascript? Any solutions or helpful links would be greatly appreciated.
For some context, the code in question is meant to forward an email with a message to a single recipient when activated. I am using nodemailer to achieve this alongside a server hosted on DigitalOcean. The webapp is built using React.
sendMyMail(event) {
var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');
let transporter = nodemailer.createTransport(smtpTransport({
service: 'gmail',
secure: false,
port: 25,
auth: {
user: 'myemail#gmail.com',
pass: 'mypass'
},
tls: {
rejectUnauthorized: false
}
}));
let HelperOptions = {
from: '"Contact Form" <myemail#gmail.com',
to: 'myforward#gmail.com',
subject: 'Hello World',
text: 'Hello World 2.0'
};
transporter.sendMail(HelperOptions, (error, info) => {
if (error) {
console.log("Unable to send mail!");
return console.log(error);
}
console.log("The message was sent!");
console.log(info);
});
}
You will need a node server in order to send an email via the script you wrote. The script must be invoked in order to send the mail. In order to invoke that particular script, you'll need a server that will serve that script when route (which handles the script invocation) is encountered.
For details, see: https://appdividend.com/2017/08/11/send-email-in-node-js/#
I'm trying few days to composing mail sending with node.js to gmail with no success :-(
at the beginning of tries I try to send form submittion to my gmail but first I need to understand how do I sent simple mail from body to gmail,
perhaps I wrong with syntax or missing something?
actually I uses "heroku" as storage and domain for my site
I tried several plugins (such as mailgun, send grid and more) but the process was too complicated integrate their API's into my site.
actually,
I find this article in stack overflow that describe how to send the via nodemailer in relation to my error - URL: node.js nodemailer gmail error
when i copy the answer1 to my code i still receiving error.
I' also pass trough all gmail setup how to turn off security block for less secured apps but i'm still receiving error.
all the requires installed over my npm
npm install --save
** code **
var nodemailer = require('nodemailer');
var smtpTransport = require('nodemailer-smtp-transport');
function handleSayHello(req, res) {
var transport = nodemailer.createTransport(smtpTransport({
service: 'gmail',
auth: {
user: 'myGmail#gmail.com', // my mail
pass: 'myPassword'
}
}));
var mailOptions = {
from: 'myGmail#gmail.com', // sender address
to: 'myGmail#gmail.com', // list of receivers
subject: 'Email Example' // Subject line
//text: text //, // plaintext body
//html: '<b>Hello world ?</b>' // You can choose to send an HTML body instead
};
transport.sendMail(mailOptions, function (error, info) {
if (error) {
console.log(error);
res.json({
yo: 'error',
err: error
});
} else {
console.log('Message sent: ' + info.response);
res.json({
yo: info.response,
info: info
});
};
});
}
router.get('/', function (req, res, next) {
handleSayHello(req, res);
});
then i receive this error:
{
"yo": "error",
"err": {
"code": "EAUTH",
"response": "534-5.7.14 <https://accounts.google.com/signin/continue?sarp=1&scc=1&plt=AKgnsbtx\n534-5.7.14 e8jnXXDaDg-dpFfc3H5ljeaBdmnxbXBDXMh-aXS-mmV4gQsXMSZLiiJHDXuOr3wy-IR2Zp\n534-5.7.14 xnznWLf5y5e3xTbJNlZBNcxBMajM9-SFQGy1MQM2XZRpHgtywuDtEj5iPiP0b2T6Wjbsxg\n534-5.7.14 hgehfzufG6h13qhjQK5IgRPNQsSICRQBtRCl3E1J62wFo8bnvZv4peY5aK55JMpwhSavJb\n534-5.7.14 ho-b9ExGGsXFmw_Er6lc8m3vCmO_Q> Please log in via your web browser and\n534-5.7.14 then try again.\n534-5.7.14 Learn more at\n534 5.7.14 https://support.google.com/mail/answer/78754 t35sm887733qtc.40 - gsmtp",
"responseCode": 534,
"command": "AUTH PLAIN"
}
}
if someone can take my code and fix it (if needed) and explain simply what do i need to modify in my google account I'll be great-full so much!
to allow from google/gmail, you should follow these links and allow to less secure apps access:
unlock account
and
Less secure apps
Let me know if still have issue, I'll check/debug your code.
When I try to use Node.js and Tedioius to connect to a local SQL Server instance I get this error:
{ [ConnectionError: Failed to connect to XXXXX:1433 - connect ECONNREFUSED]
name: 'ConnectionError',
message: 'Failed to connect to XXXXX:1433 - connect ECONNREFUSED',
code: 'ESOCKET' }
Here is my connection object:
var config = {
userName: 'username',
password: 'password',
server: 'XXXXX',
options: {
database: 'databasename',
instancename: 'SQLEXPRESS'
}
};
I have checked and TCP/IP is enabled and broadcasting on port 1443 according to Configuration Manager. The SQL Server Browser service is also running, which I read may be causing this type of issue if not. I have disabled my antivirus and firewall and that hasn't helped either.
Any insight?
So what I am guessing happens is that even though Tedious lets you include instance name in 'options' it either doesn't use it or can't use it as it needs to be used. After doing some research, what should be happening is when you give SQL Server the instance name, it redirects you from port 1433 to the dynamic port it is using for that instance. I didn't know it was using a dynamic port, but if your instance is named the port will always be dynamic. I don't know where I saw it broadcasting on 1433, that was my mistake.
To check the dynamic port, look here:
From this information, I changed my code to this:
var config = {
userName: 'username',
password: 'password',
server: 'XXXXX',
options: {
port: 49175,
database: 'databasename',
instancename: 'SQLEXPRESS'
}
};
All is good now, hope this helps someone.
If anyone else is new to SQL Server like I am, and is dealing with this issue, once you enable TCP/IP in SQL Server Config Manager by following these steps:
> SQL Server Network Config
> Protocols for YOURSQLSERVERINSTANCE
> TCP/IP
> Enable
you get a warning message that looks like this:
Any changes made will be saved; however, they will not take effect until the service is stopped and restarted.
I took this to mean, disconnect from the database service in SQL Server Management Studio and reconnect, but this needs to happen in SQL Server Config Manager under the SQL Server Services tab. Find you SQL Server instance, stop and restart it, and hopefully you will be golden! This worked like a charm for me. Oddly, enabling the Named Pipes protocol seemed to work without a restart (I could see the difference in the error message), so I thought for sure it had stopped and restarted as needed.
Also, be sure to enable SQL Server Browser services as well. This and enabling TCP/IP and restarting the service were the keys for me.
If you still have problems after enabling TCP/IP protocol, I would suggest you check that SQL Server Browser Service is running. In my case I spent a lot of time till I realised it wasn't running.
This configuration run fine for me:
var config = {
user: 'user',
password: 'userPwd',
server: 'localhost',
database: 'myDatabase',
options: {
truestedConnection: true,
instanceName: 'SQLEXPRESS'
}
If you still got this error,
"...'Failed to connect to Server:1433 - connect ECONNREFUSED Server IP:1433',
code: 'ESOCKET' }"
and you've checked all the following:
Enable TCP/IP
Open Port 1433
Config setup correctly (database, server, username and password}
No Dynamic ports configured
Check your SQL server version. In my case, I discovered that I could connect to SQL 2012, but not SQL server 2016 with the same code. It appears SQL Server 2016 is not supported by the tedious driver yet.
...
You have to enabled tcp/ip on protocol for MSSQLSERVER
and activate both authentication
here is the complete code
const {
Request
} = require('tedious');
var Connection = require('tedious').Connection;
var config = {
server: 'DESKTOP-RU9C12L', //update me
authentication: {
type: 'default',
options: {
userName: 'begaak', //update me
password: 'begaak#123', //update me
}
},
options: {
encrypt: true,
enableArithAbort: true,
integratedSecurity: true,
trustServerCertificate: true,
rowCollectionOnDone: true,
database: 'selvapoc' //update me
}
};
var connection = new Connection(config);
connection.connect(function(err) {
console.log('testing')
// var request = new Request("Select * from products", function(err, rowCount, rows) {
// console.log(rowCount);
// console.log(JSON.stringify(rows))
// });
// connection.execSql(request);
connection.execSql(new Request('SELECT * FROM Products', function(err, rowCount, rows) {
if (err) {
throw err;
}
})
.on('doneInProc', function(rowCount, more, rows) {
console.log(more, rows[0], rowCount); // not empty
}));
});
connection.on('connect', function(err) {
// If no error, then good to proceed.
if (err) console.log(err)
console.log("Connected");
});
before starting the code configure these with SQL SERVER CONFIGURATION MANAGER