How to run php code inside a template for node.js - php

There is some code to establish a node.js server with a html engine:
const express = require('express');
const paypal = require('paypal-rest-sdk');
var cons = require('consolidate');
var path = require('path');
const app = express();
app.engine('html', cons.swig)
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
app.get('/', (req, res) => res.render('index.html'));
However in my index.html file I wanna output some PHP variables. Let's say these look as follows:
<p class="places">
<?php echo $request['places_count'].' places are left now'; ?>
</p>
Is that even possible to show php veriables inside node.js and if not, what's the best way to solve the issue?

Related

React application failing to fetch once publicly hosted

can anyone help me with the following issue? This is all very new to me so I'm sorry for any incoveniences. I'm creating a ChatGPT tool which takes a text inputs from the user in the front end then passes that data into the back end which sends the user input to an open OpenAI API layer. The back end then receives a response back from the OpenAI layer and stores the text response into a text array and writes it back to the front end into a standard text area.
The website runs perfectly when it is hosted locally on localhost:3001 and port:3001. My issue stems when I deploy the website to firebase and attempt to submit a form request on another machine and different network it does not writing any text to the textarea. Below I have provided my code. I believe the issue has something to do with the localhost code in the handleSubmit function or could even be in the back end script i'm very unsure and would really appreciate any help I can get thanks to get this running publicly. Thanks for your time :)
Front End (App.js)
import React, { useState } from 'react';
import './App.css';
function App() {
const [message, setMessage] = useState('');
const [response, setResponse] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
fetch('http://localhost:3001', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({message}),
})
.then((res) => res.json())
.then((data) => setResponse(data.message));
};
return (
<body>
<div className="App">
<form onSubmit={handleSubmit}>
<div class="section"></div>
<header>
<nav>
<ul class="nav_links">
<li><a href='#'>Home</a></li>
<li><a href='#'>Pricing</a></li>
<li><a href='#'>About</a></li>
<li><a href='#'>Contact</a></li>
</ul>
</nav>
<button class="login">Login</button>
</header>
<input type="text" id="topic"
value={message}
onChange={(e) => setMessage(e.target.value)}
></input>
<textarea id="textarea" value={response} />
<div> <button id="generate" type="submit">Generate</button> </div>
</form>
</div>
</body>
);
}
Back End (Index.js)
const OpenAI = require('openai');
const { Configuration, OpenAIApi } = OpenAI;
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const app = express();
const port = 3001;
const configuration = new Configuration({
organization: "org-kEBxx4hVwFZ",
apiKey: "sk-jmYuTSCZvxCjidnbTpjFT3Blbk",
});
const openai = new OpenAIApi(configuration);
app.use(bodyParser.json());
app.use(cors());
app.post('/', async (req, res) => {
const { message } = req.body;
const response = await openai.createCompletion({
model: "text-davinci-003",
prompt: `${message}`,
max_tokens: 1000,
temperature: 0,
});
console.log(response.data)
if(response.data.choices[0].text){
res.json({message: response.data.choices[0].text})
}
});
app.listen(port, () => {
console.log("Listening...")
});
Since http://localhost:3001 is hardcoded into your code, even when you deploy it in production, the production website will still try to make a request to localhost:3001. To fix this, you need to dynamically set the url based on whether the code is in development or production. The recommended way to do this is using environment variables: https://create-react-app.dev/docs/adding-custom-environment-variables/, where you'd set the env variable to localhost:3001 during development and the url of the production server in production.

How to emit a socket.io event from a PHP controller?

I'm developping a PHP website using the Yii2 Framework and I'm trying to implement a socket.io service.
To execute socket.io I use PM2 and my file looks like this :
const { fstat } = require('fs');
var socket = require('socket.io'),
express = require('express'),
https = require('https');
fs = require('fs');
const credentials = {
key: fs.readFileSync('../../../ssl/keys/<path_to_cert_key.key>').toString(),
cert: fs.readFileSync('../../../ssl/certs/<path_to_cert.crt>').toString(),
}
var app = express();
var server = https.createServer(credentials, app);
var io = socket(server, {
cors: {
origin: '<origin_url>',
methods: ['POST', 'GET'],
credentials: true
},
allowEIO3: true,
secure: true
});
io.sockets.on('connection', function(client){
console.log('ok');
client.on('test', function(data){
console.log('test');
console.log(data);
io.sockets.emit('test_r', {message: 'ok'});
});
});
server.listen(30064);
It runs without any error:
pm2 start _socket.js
I can easily access this socket from a view by registering javascript :
var socket = io.connect('<socket_url:port>', {
withCredentials: false,
});
socket.on('test_r', function( data ) {
console.log('it works');
});
It works well if I connect to the socket and emit from a view.
But the thing is that I want to emit an event from a PHP Controller or from a CoreBootstrap Object in a php function like this :
$emitter = new \SocketIO\Emitter( array( 'port' => '30064', 'host' => '127.0.0.1') );
$emitter->broadcast->emit( 'test', ['message' => 'test_message'] );
The module I'm using is ashiina/socket.io-emitter (I also tried a bunch of ohters but they did not work as well).
Nothing happens when I do this. Nothing even happens when I look at the PM2 logs.
Would someone know why the event is not emitted or if there is another way to do it ?
Thanks in advance for your answers.

Socket.io-auth - hide the credentials from payload request

Im building my socket application with laravel broadcaasting. I made my server script and then added https like in this script: (The code may contain errors because it is written from memory)
var fs = require('fs');
var https = require('https');
var express = require('express');
var app = express();
var options = {
key: fs.readFileSync('./file.pem'),
cert: fs.readFileSync('./file.crt')
};
var serverPort = 3000;
var server = https.createServer(options, app);
var io = require('socket.io')(server);
require('socketio-auth')(io, {
authenticate: authenticate,
postAuthenticate: postAuthenticate,
disconnect: disconnect,
timeout: 1000
});
after that i added socketio-auth and modified it for just username and password authentication.
function authenticate(socket, data, callback) {
if (data.username != "username") {
return callback(new Error("User not found"));
}
return callback(null, user.password == "password");
}
}
My question is about credntials I'm sending via socket.
import VueSocketio from 'vue-socket.io';
Vue.use(VueSocketio, socketio('https://socketserver.com:1923', {secure: true}));
var vm = new Vue({
sockets:{
connect: function(){
console.log('socket connected')
this.$socket.emit('authentication', {username : "username", password: "password"});
},
},
})
Im actually using Vue with vue-socketio but its working with connection and with getting / sending information properly.
Problem I got is when Im going to console in google chrome im getting plain text socket emit authentication information like
(REQUEST PAYLOAD : {authentication: {username: "username", password : "password"}}).
Is that normal thing when Im using ssl? Something is wrong with my code?
Or I need to encrypt then decrypt this information myself?
I thought all Im sending via HTTPS is encrypted.
Looking for ur replay. Thanks!
Okey I made my own encryptor.
For client Im emiting encrypted information with data and the verify hash with socket.id.
And for server i decrypted and check hmac verification with socket.id.

Private chat (PHP + Socket.io) with PHP Sessions

I am developing a website which uses a private messaging system using php + socket.io.
From the beginning i passed the sender_id, recipient_id and text to socket.io using socket.emit but later realized that this could be easily tampered with and wanted to use my php sessions in some way to be sure that the sender_id is indeed the sender_id.
I have the following setup right now but i dont really understand how to pass the session from index.php to app.js and then connect to redis-server in app.js to get the PHPSESSID which holds the user_id.
Server 1 running nginx + php-fpm (index.php)
Server 2 running node.js with socket.io (app.js)
Server 3 running redis for session management
My code right now looks like the following but is obviously missing the redis part right now which i would really appriciate some help with.
Thanks!
index.php
<?php
session_start();
if ($_SESSION['user_id'] == false){
header("Location:login.php");die;
}
?>
<script>
var socket = io('https://app01.dev.domain.com:8895');
socket.on('connect', function(){
console.log("Connected to websockets");
});
socket.on('event', function(data){});
socket.on('disconnect', function(){});
$('.chat-message').keypress(function (e) {
if (e.which == 13) {
console.log("send message");
var friend_id = $(this).attr('id');
friend_id = friend_id.split("-");
friend_id = friend_id[3];
var obj = {
recipient_id: friend_id,
text: $(this).val()
};
socket.emit('chat_message', obj);
$(this).val('');
return false;
}
});
</script>
app.js
var https = require("https"), fs = require("fs");
var options = {
key: fs.readFileSync('/etc/letsencrypt/live/domain/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/domain/cert.pem'),
ca: fs.readFileSync('/etc/letsencrypt/live/domain/chain.pem')
};
var app = https.createServer(options);
var io = require("socket.io")(app);
var redis = require("redis");
// This i want to fill with for example PHPSESSION:user_id that i get from redis and later use it as sender
// var all_clients = {};
io.set("transports", ["websocket", "polling"]);
io.on("connection", function(client){
console.log("Client connected");
// Here i would like to connect to redis in some way and get the user_id but dont really understand how
//all_clients[USER_ID_FROM_REDIS] = client.id;
//var user_id = USER_ID_FROM_REDIS;
client.on("chat_message", function(data){
var obj = {
to: data.recipient_id,
text: data.text
};
console.log("Message inbound from socket: "+client.id+" from: "+data.user_id+" to: "+data.recipient_id+" with text: "+data.text);
});
client.on("disconnect", function(){
console.log("Client disconnected ");
//delete all_clients[USER_ID_FROM_REDIS];
});
});
app.listen(8895, function(){
console.log("listening on *:8895");
});
var recursive = function () {
//console.log("Connected clients: "+Object.keys(all_clients).length);
//console.log(JSON.stringify(all_clients));
setTimeout(recursive,2000);
}
recursive();
HTTP in itself does not protect against MITM attacks, to protect against MITM the server certificate needs to be pined.
To protect against a user being spoofed you need authentication such as logging-in or a secret token like Dropbox.
Add certificate pinning, that is just jargon for validating that you are connecting to the correct server and not a MITM by verifying the certificate that is sent by the server. MITM used to be harder but WiFi has made it easy to connect to the wrong end-point at Hot Sports, even at home I have seen this.

Changing node.js server to Apache server

I was working with react-webpackage and running the project into node.js
Now due to demand , i have to add some php files in the project but i don't know how to add php file in my project and now transfer my project from node.js to Xampp and run my project with xampp... can you please guide me with that.
I am using this webpack "https://github.com/srn/react-webpack-boilerplate".
And my webpack index.js file looks like this.
'use strict';
var fs = require('fs');
var path = require('path');
var express = require('express');
var app = express();
var compress = require('compression');
var layouts = require('express-ejs-layouts');
app.set('layout');
app.set('view engine', 'ejs');
app.set('view options', {layout: 'layout'});
app.set('views', path.join(process.cwd(), '/server/views'));
app.use(compress());
app.use(layouts);
app.use('/client', express.static(path.join(process.cwd(), '/client')));
app.disable('x-powered-by');
var env = {
production: process.env.NODE_ENV === 'production'
};
if (env.production) {
Object.assign(env, {
assets: JSON.parse(fs.readFileSync(path.join(process.cwd(), 'assets.json')))
});
}
app.get('/*', function(req, res) {
res.render('layout', {
env: env
});
});
var port = Number(process.env.PORT || 3001);
app.listen(port, function () {
console.log('server running at localhost:3001, go refresh and see magic');
});
if (env.production === false) {
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var webpackDevConfig = require('./webpack.config.development');
new WebpackDevServer(webpack(webpackDevConfig), {
publicPath: '/client/',
contentBase: './client/',
inline: true,
hot: true,
stats: false,
historyApiFallback: true,
headers: {
'Access-Control-Allow-Origin': 'http://localhost:3001',
'Access-Control-Allow-Headers': 'X-Requested-With'
}
}).listen(3000, 'localhost', function (err) {
if (err) {
console.log(err);
}
console.log('webpack dev server listening on localhost:3000');
});
}
basically i want to declare some variables in php and fetch them to javascript.so just want to add one file in webpack(file named as index.php) and then all my project work normally
Thanks.
You can't run express on the same port of xampp, you have to use different ports (or different servers) to serve the php file.

Categories